pytorch实现
用简单的两层CNN跑一下这道题,需要GPU加速,代码如下,代码其实入门都差不多,简单提一下pytorch构建简单神经网络的思路(个人理解):
1.首先载入原始训练集,.values转换成列表形式,并且将标签和数据进行划分进行标准化(像素0-255->0-1)
2.数据集的划分,划分成8:2,一部分训练,一部分测试
3.将数据转换成tensor形式,Data.TensorDataset(X_train,Y_train)
4.设置超参数,BATCH_SIZE,EPOCH以及优化器的学习率learning rate
5.进行数据集的载入 torch.utills.data.DataLoder 设定训练集的batch_size和测试集的batch_size以及是否随机
6.转载完成数据集之后定义自己的神经网络积木,需要注意的是,需要理解每一层图像经过卷积之后的变化,因为最后全连接层需要和长*宽*高进行映射,卷积层中间的参数分别为:
输入高 (上一层卷积核的数量) 输出高(卷积核的数量) 卷积核的大小 卷积步长 在图像周围填充数值的圈数
7.进行forward的填写,开始搭积木,在卷卷卷之后,需要自己view一下形状,经过卷积之后的形状肯定是(batchsize,高,长,宽)由于全连接层是一维的,所以需要变成(batchsize,高*长*宽)这样的形状。
8.现在得到了模型壳子,把它给model,好看一些,并且定义损失函数loss_fun,以及优化器的选择SGD,模型的所有参数 model.parameters(),经过反向传播,在一个学习率(LR)下的优化下实现了学习的过程
9.最后进行模型的迭代,我们在自己定义的EPOCH下面进行迭代,在我们定义的train_loader这个容器里面,我们取出目前已经迭代的次数以及里面的BATCH_SIZE个(x,y),优化器里面的梯度进行清零,通过最终得出来的结果,用损失函数进行loss计算,反向传播之后,进行误差分析,使用梯度下降进行慢慢学习
10.在每一次的批处理中,进行测试数据的loss与acc计算
11.将数据标准化之后,经过model进行分类判断
12.进行测试数据的标准化, torch.from_numpy()以及 dataloader,之后进行
通过pre_all=torch.LongTensor()的初始化不断拼接判断结果进行输出。
(这部分代码千篇一律,无亮点)
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.utils.data as Data
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
train = pd.read_csv(r'../input/digit-recognizer/train.csv',dtype=np.float32)
targets_numpy=train.label.values
features_numpy=train.loc[:,train.columns!='label'].values/255
# print(features_numpy.shape)
features_train, features_test, targets_train, targets_test = train_test_split(
features_numpy,targets_numpy,test_size = 0.2,random_state = 42)
X_train,X_test,Y_train,Y_test=torch.from_numpy(features_train),torch.from_numpy(features_test),torch.from_numpy(targets_train).type(torch.LongTensor),torch.from_numpy(targets_test).type(torch.LongTensor)
#超参数:
BATCH_SIZE=100
LR=0.002
EPOCH=200
#初始化
pytorch_train=Data.TensorDataset(X_train,Y_train)
pytorch_test =Data.TensorDataset(X_test,Y_test)
train_loader =Data.DataLoader(pytorch_train,batch_size=BATCH_SIZE,shuffle=True)
test_loader =Data.DataLoader(pytorch_test,batch_size=BATCH_SIZE,shuffle=True )
# plt.imshow(features_numpy[9].reshape(28,28))
# plt.axis("off")
# plt.title(str(targets_numpy[10]))
# plt.show()
class cnn(nn.Module):
def __init__(self):
super(cnn,self).__init__()
#conv1
self.conv1=nn.Sequential(
nn.Conv2d(1,16,5,1,2),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2)
)
#conv2
self.conv2=nn.Sequential(
nn.Conv2d(16,32,5,1,2),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
# #conv3
# self.conv3=nn.Conv2d(32,64,7,1,0)
# self.relu3=nn.ReLU()
# self.pool3=nn.MaxPool2d(2)
#fc1
self.fc1=nn.Linear(32*7*7,10)
def forward(self,x):
x=self.conv1(x)
x=self.conv2(x)
# x=self.conv3(x)
x = x.view(x.size(0), -1)
output=self.fc1(x)
return output
model=cnn() #cnn的壳子
loss_fun = nn.CrossEntropyLoss() #定义损失函数
use_gpu = torch.cuda.is_available()
if(use_gpu):
model = model.cuda()
loss_fun = loss_fun.cuda()
optimizer = torch.optim.Adam(model.parameters(),lr=LR) #定义反向传播的梯度下降函数
count = 0
loss_list = []
iteration_list = []
accuracy_list = []
for epoch in range(EPOCH):
for i,(x,y) in enumerate(train_loader):
if (use_gpu):
x= x.cuda()
y= y.cuda()
x=x.view(BATCH_SIZE,1,28,28)
y=y
optimizer.zero_grad()
outputs = model(x)
loss=loss_fun(outputs,y)
loss.backward()
optimizer.step()
count+=1
if count % 50 == 0:
# Calculate Accuracy
correct = 0
total = 0
# Iterate through test dataset
for x, y in test_loader:
if (use_gpu):
x= x.cuda()
y= y.cuda()
test =x.view(BATCH_SIZE,1,28,28)
# Forward propagation
outputs = model(test)
# Get predictions from the maximum value
predicted = torch.max(outputs.data, 1)[1]
# Total number of labels
total += len(y)
correct += (predicted == y).sum()
accuracy = 100 * correct / float(total)
# store loss and iteration
loss_list.append(loss.data)
iteration_list.append(count)
accuracy_list.append(accuracy)
if count % 500 == 0:
# Print Loss
print('Iteration: {} Loss: {} Accuracy: {} %'.format(count, loss.data, accuracy))