简述和理论知识
一个简单的深度学习项目有不可或缺的三部分:
- 数据集:主要包括训练集,验证集和测试集,其中训练集和验证集中数据有标签,即准确值,测试集无标签。
- 模型:定义相关模型,根据数据(x)预测(pre_y)值。
- 超参数:loss函数,学习率,优化器。
相关类
- Dataset
初始化函数,用来初始化数据集,并且根据传入参数将原本数据划分为训练集,验证集,测试集是独立一个文件,没有最终的准确值。
class CovidDataset(Dataset):
def __init__(self,file_path,mode="train",all_feature=True,feature_dim=6):
with open(file_path,"r") as f:
ori_data = list(csv.reader(f))
csv_data=np.array(ori_data[1:])[:,1:].astype(float)#先去掉第一行的标题,然后转化为array后进行切片,取所有行,第一列到最后一列(去掉第一列序号),最后将字符串类型的值转换为浮点型
columns = ori_data[0]
features = np.array(ori_data[1:])[:,1:-1]#特征值为除标签外全部数据
label_data = np.array(ori_data[1:])[:,-1]#最后一列为标签
if all_feature:
col = np.array([i for i in range(0,93)])#所有列的下标
else:
_,col = get_feature_importance(features,label_data,feature_dim,columns)
col = col.tolist()
if mode =="train": #逢5取1个,在总体数据中划分出训练集
indices = [i for i in range(len(csv_data)) if i%5 != 0]
data = torch.tensor(csv_data[indices, :-1])
self.y = torch.tensor(csv_data[indices,-1])
elif mode =="val": #总体数据中划分出验证集
indices = [i for i in range(len(csv_data)) if i%5 == 0]
data = torch.tensor(csv_data[indices, :-1])
self.y = torch.tensor(csv_data[indices, -1])
else:
indices = [i for i in range(len(csv_data))]
data = torch.tensor(csv_data[indices])
data = data[:,col]
self.data =(data -data.mean(dim=0,keepdim=True))/data.std(dim=0,keepdim=True)//数据标准化,防止因某些数据值过大影响数据,将减去均值后的数据除以每一列的标准差,从而使每一列数据的标准差变为 1。
self.mode = mode
def __getitem__(self, idx):#根据不同的模式选择不同的集合
if self.mode !="test":
return self.data[idx].float(),self.y[idx].float()
else:
return self.data[idx]
def __len__(self):
return len(self.data)
模型(model)
全链接神经网络模型类,MyModule1
class MyModel(nn.Module):
def __init__(self,inDim):
super(MyModel,self).__init__()
self.fc = nn.Linear(inDim,64)#线性全链接层,输入维数为inDim,输出维度为64维
self.relu1 = nn.ReLU() #激活函数
self.fc2 = nn.Linear(64,1)#线性全连接层,输入64,输出1维
def forward(self,x):
x=self.fc(x)
x=self.relu1(x)
x=self.fc2(x)
if len(x.size()) >1:
return x.squeeze(1)#如果输出维度大于一则进行维度压缩
return x
模型训练
每次训练和验证过后打印loss值
def train_val(model,train_loader,val_loader,device,epochs,optimize,loss,saveKey):
model=model.to(device)
plt_train_loss = []
plt_val_loss = []
min_loss = 9999999999999999
for epoch in range(epochs): #训练开始
train_loss = 0.0
val_loss = 0.0
start_time = time.time()
model.train() #模型调为训练模式
for batch_x,batch_y in train_loader:
x,target = batch_x.to(device),batch_y.to(device)#在 PyTorch 里,所有的张量(数据)和模型(由一系列张量组成)都必须位于同一设备上才能进行计算
pred = model(x)#进行前向传播,得到模型的预测结果
train_bat_loss = loss(pred,target,model)
train_bat_loss.backward()
optimize.step()#根据梯度更新模型参数。
optimize.zero_grad()
train_loss += train_bat_loss.cpu().item()
plt_train_loss.append(train_loss/train_loader.__len__())
model.eval()
with torch.no_grad():#上下文管理器,用于关闭梯度计算,减少内存消耗并提高计算速度。
for batch_x,batch_y in val_loader:
x, target = batch_x.to(device), batch_y.to(device)
pred = model(x)
val_bat_loss = loss(pred, target,model)
val_loss+= val_bat_loss.cpu().item()
plt_val_loss.append(val_loss/val_loader.__len__())
if val_loss< min_loss:
torch.save(model,saveKey)
print("[%03d/%03d] %2.2f sec(s) Trainloss:%.6f |Valloss: %.6f"% \
(epoch,epochs,time.time()-start_time,plt_train_loss[-1],plt_val_loss[-1]))
plt.plot(plt_train_loss)
plt.plot(plt_val_loss)
plt.title("Loss图")
plt.legend(["train","val"])
plt.show()
得出结果
最后将测试集数据放入模型中得出最后结果,并且写入到csv文件中
def evaluate(save_path, test_loader, device, rel_path): # 得出测试结果文件
model = torch.load(save_path).to(device)
model.eval() # 将模型设置为评估模式
all_preds = []
with torch.no_grad():
for x in test_loader:
x=x.to(device).float()
# pred = model(x.to(device))
pred = model(x)
all_preds.append(pred.cpu().numpy()) # 将预测结果转换为 numpy 数组并存储
# 拼接所有批次的预测结果
all_preds = torch.tensor(np.concatenate(all_preds, axis=0))
with open(rel_path, "w", newline='') as f:
csvWriter = csv.writer(f)
csvWriter.writerow(["id", "tested_positive"])
for i, value in enumerate(all_preds):
csvWriter.writerow([str(i), str(value.item())]) # 将预测结果转换为 Python 标量并写入文件
print("文件已经保存到{}".format(rel_path))
总结
这次实战让我理解到了数据的细致分类,以及如何优化模型(计算出每列的相关系数,找出相关系数最大的几列数据对模型进行优化,采用正则化loss=loss+w*w目的是为了找最小loss时也让w尽量小),也学会了如何计算需要的参数个数(偏置,权重个数)如linear(4,1),参数个数为4*1+1=5个。
1423

被折叠的 条评论
为什么被折叠?



