记录一下pytorch学习轨迹
因为笔记本NIVIDA Driver版本的问题一直报警告信息,所以加入了warnings 模块屏蔽所有的警告信息方便查看loss。
1.数据集加载部分
继承至abstract class Dataset,需要补全__init__(), __getitem__(), __len__(),三个魔法方法,特别是__getitem__(), __len__()两个魔法方法在Dataloader 后续加载数据集的时候会根据提供的dataset = dataset来索引数据集以及获取数据集的长度以最终返回一个正确的生成器(在Dataloader定义完成之后,这个类里面会调用到__getitem__(), __len__()两个魔法方法),其中训练数据和标签会根据self.x_data和self.y_data来分配完成。
import torch
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings("ignore")#屏蔽警告信息
#prepare dataset
class TitanicDataset(Dataset):
def __init__(self,filepath):
data = pd.read_csv(filepath,delimiter=',')
self.len = data.shape[0]
self.x_data = torch.from_numpy(data[['Pclass','SibSp','Parch','Fare']].values.astype(np.float32))#nparray为对象形式,强制转为float形式
self.y_data = torch.from_numpy(data[['Survived']].values.astype(np.float32))
#搞清楚这里面的关系,[[]]和[]之间的关系 # self.y_data = torch.from_numpy(data['Survived'].values.astype(np.float32))
#或者在y_pred那里将y_pred 的维度通过 y_pred = y_pred.squeeze(-1)压缩至一维
def __getitem__(self, index):
return self.x_data[index], self.y_data[index]
def __len__(self):
return self.len
dataset = TitanicDataset('train.csv')
data_loader = DataLoader(dataset=dataset,shuffle=True,batch_size=1,num_workers=2)
'''
print(dataset.x_data.shape)
print(dataset.y_data.shape)
print(dataset.x_data)
print(dataset.y_data)
#define models
'''
通过打印self.y_data可以看到此时的标签的维度为[891,1]维,如果代码中写的是data['survived']的话,维度为[891],两者其实有很大的区别,因为是向量化输入矩阵进行运算,前者代表的是每一个样本的标签信息,而后者代表的是一个一维的数组,不能表示每个样本的标签信息。
2.定义模型
这里定义了一个8*6*4的神经网络
class Model(torch.nn.Module):
def __init__(self):
super().__init__()
self.linear1 = torch.nn.Linear(4,8)
self.linear2 = torch.nn.Linear(8,6)
self.linear3 = torch.nn.Linear(6,4)
self.linear4 = torch.nn.Linear(4,1)
self.activate = torch.nn.ReLU()
self.sigmoid = torch.nn.Sigmoid()
def forward(self,x):
x = self.activate(self.linear1(x))
x = self.activate(self.linear2(x))
x = self.activate(self.linear3(x))
x = self.sigmoid(self.linear4(x))
return x
model = Model()
3.定义损失和优化策略
#define loss and optimizer
criterion = torch.nn.BCELoss(size_average=True) #??
optimizer = torch.optim.SGD(model.parameters(),lr=0.005)
现在还没有搞懂这个size_average的真正含义,需要去查文档
4.训练Cycle
#training cycle
if __name__ == '__main__':
for epoch in range(500):
print('epoch:',epoch,end='\n')
for batch_id, data in enumerate(data_loader,0):
inputs, labels = data
#print(inputs,labels,sep='\n')
y_pred = model(inputs)
#print(y_pred)
#print(labels)
loss = criterion(y_pred,labels)
print('\t','batch_id= ',batch_id,'loss= ',loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
调了一部分参数,500轮之后大概稳定在0.4左右,后续写了验证集的代码和提交分数之后,分数是0.8269