点击【拇指笔记】,关注我的公众号。
本篇文章全部代码可以在后台回复"MLP_PY"获取。
导入需要的库。
import torchfrom torch import nnimport numpy as npimport syssys.path.append("..")
import torchvisionfrom IPython import displayfrom time import timeimport matplotlib.pyplot as pltimport torchvision.transforms as transformsfrom time import time
这一部分依然使用之前的Fashion-MNIST数据集。
batch_size = 256
mnist_train = torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',train=True,download=True,transform=transforms.ToTensor())#获取训练集mnist_test = torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',train=False,download=True,transform=transforms.ToTensor())#获取测试集
#生成迭代器train_iter = torch.utils.data.DataLoader(mnist_train,batch_size=batch_size,shuffle = True,num_workers = 0)
test_iter = torch.utils.data.DataLoader(mnist_test,batch_size = batch_size,shuffle=False,num_workers=0)
num_inputs ,num_outputs,num_hiddens = 784,10,256
class MLP(nn.module): def __init__(self,num_inputs,num_outputs,num_hiddens): super(MLP,self).__init__() #使用父类的初始化参数 self.mlp = nn.Sequential( nn.Linear(num_inputs,num_hiddens) nn.ReLU() nn.Linear(num_hiddens,num_outputs) ) #定义神经网络里的输入、隐藏和输出层 def forward(self,x): #定义前向传播 y = self.mlp(x.view(x.shape[0],-1)) reyurn y net = MLP(x,num_inputs,num_outputs,num_hiddens)
此时通过
print(net)
可以看到现在的神经网络层结构如下图
PyTorch都有内置好的,两行代码。
loss = torch.nn.CrossEntropyLoss()#损失函数optimizer = torch.optim.SGD(net.paramters(),lr=0.5)#优化函数
首先我们需要得到预测的结果。
从一组预测概率(变量y_hat)中找出最大的概率对应的索引(索引即代表了类别)
#argmax(f(x))函数,对f(x)求最大值所对应的点x。我们令f(x)= dim=1,即可实现求所有行上的最大值对应的索引。A = y_hat.argmax(dim=1) #最终输出结果为一个行数与y_hat相同的列向量
然后我们需要将得到的最大概率对应的类别与真实类别(y)比较,判断预测是否是正确的
B = (y_hat.argmax(dim=1)==y).float()#由于y_hat.argmax(dim=1)==y得到的是ByteTensor型数据,所以我们通过.float()将其转换为浮点型Tensor()
最后我们需要计算分类准确率
我们知道y_hat的行数就对应着样本总数,所以,对B求平均值得到的就是分类准确率
(y_hat.argmax(dim=1)==y).float().mean()
上一步最终得到的数据为tensor(x)的形式,为了得到最终的pytorch number,需要对其进行下一步操作
(y_hat.argmax(dim=1)==y).float().mean().item()#pytorch number的获取统一通过.item()实现
整理一下,得到计算分类准确率函数
def accuracy(y_hat,y): return (y_hat.argmax(dim=1).float().mean().item())
作为推广,该函数还可以评价模型net在数据集data_iter上的准确率。
def net_accurary(data_iter,net): right_sum,n = 0.0,0 for X,y in data_iter: #从迭代器data_iter中获取X和y right_sum += (net(X).argmax(dim=1)==y).float().sum().item() #计算准确判断的数量 n +=y.shape[0] #通过shape[0]获取y的零维度(列)的元素数量 return right_sum/n
在训练模型时,迭代周期数num_epochs、隐藏层神经单元数num_hiddens和学习率lr都是可以调节的超参数,通过调节超参数的值可以获得分类更准确的模型。
num_epochs = 5
def train_MLP(net,train_iter,test_iter,loss,num_epochs,batch_size,optimizer,net_accurary): for epoch in range(num_epochs): #损失值、正确数量、总数 初始化。 train_l_sum,train_right_sum,n= 0.0,0.0,0 for X,y in train_iter: y_hat = net(X) l = loss(y_hat,y).sum() #数据集损失函数的值=每个样本的损失函数值的和。 optimizer.zero_grad() #对优化函数梯度清零 #for param in params: # param.grad.data.zero_() l.backward() #对损失函数求梯度 optimizer.step() train_l_sum += l.item() train_right_sum += (y_hat.argmax(dim=1) == y).sum().item() n += y.shape[0] test_acc = net_accurary(test_iter, net) #测试集的准确率 print('epoch %d, loss %.4f, train right %.3f, test right %.3f' % (epoch + 1, train_l_sum / n, train_right_sum / n, test_acc)) start = time()train_MLP(net,train_iter,test_iter,loss,num_epochs,batch_size,optimizer,net_accurary)print('%.3f'% (time()-start),'s')
五个学习周期,四线程读取数据,一共耗时50秒。
使用训练好的模型对测试集进行预测
做一个模型的最终目的当然不是训练了,所以来识别数据集试试。
#将样本的类别数字转换成文本def get_Fashion_MNIST_labels(labels): text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat', 'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot'] return [text_labels[int(i)] for i in labels] #labels是一个列表,所以有了for循环获取这个列表对应的文本列表
#显示图像def show_fashion_mnist(images,labels): display.set_matplotlib_formats('svg') #绘制矢量图 _,figs = plt.subplots(1,len(images),figsize=(12,12)) #设置添加子图的数量、大小 for f,img,lbl in zip(figs,images,labels): f.imshow(img.view(28,28).numpy()) f.set_title(lbl) f.axes.get_xaxis().set_visible(False) f.axes.get_yaxis().set_visible(False) plt.show()
#从测试集中获得样本和标签X, y = iter(test_iter).next()
true_labels = get_Fashion_MNIST_labels(y.numpy())pred_labels = get_Fashion_MNIST_labels(net(X).argmax(dim=1).numpy())
#将真实标签和预测得到的标签加入到图像上titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)]
show_fashion_mnist(X[0:9], titles[0:9])