赞
踩
准备数据,这些需要准备DataLoader
构建模型,这里可以使用torch构造一个深层的神经网络
模型的训练
模型的保存,保存模型,后续持续使用
模型的评估,使用测试集,观察模型的好坏
先从torchvsion中下载好数字的图片数据作为训练数据集,download字段就是没有的话是否下载的意思,使用如下代码,将其下载好保存到data文件夹中
images = torchvision.datasets.MNIST(r'data',train=True,download=True)
为了方便处理数据我们需要对image类型进行转换
使用torchvision.transforms中的conpose,ToTensor,Normalize类
使用数据加载器起到把images打乱的效果,查看一下此时dataloader里的数据样子,一个列表,列表第一个是特征值(一个三阶tensor),第二个数是目标值,也就是这个数字是多少
这里激活函数,就是让本来只能线性的拟合效果变得不是线性,增加了模型的非线性分割能力
import torchvision from torch.utils.data import DataLoader from torchvision.transforms import Compose,ToTensor, Normalize import torch.nn as nn import torch.nn.functional as f # 准备数据 fn = Compose([ ToTensor(), Normalize((0.1307,), (0.3081,)) ]) minst = torchvision.datasets.MNIST(r'data',train=True,download=True,transform=fn) minst2 = DataLoader(minst,shuffle=True) for i in minst2: print(i) break class MinstModel(nn.model,): def __init__(self): super(MinstModel, self).__init__() self.fc1 = nn.Linear(28 * 28 * 1, 28) # 定义Linear的输入和输出的形状 self.fc2 = nn.Linear(28, 10) # 定义Linear的输入和输出的形状 def forward(self, input): # 因为原始输入数据为的形状:[batch_size,1,28,28],要进行神经网络的运算,需要进行矩阵的乘法 # 所以需要变换形状 # 将input修改为[batch_size,28*28] input = input.view(input[0], 28*28) # 进行一次全连接(乘法),变换形状 input = self.fc1(input) # 激活函数处理,处理函数为ReLU,图片适用 input = f.relu(input) # 再进行一次全连接 out = self.fc2(input)
损失函数(loss function)是用来估量模型的预测值f(x)与真实值Y的不一致程度,损失函数找到他的最小值就是我们所要求的,这里因为我们是分类的,而且是多分类,这里给一个别人的关于这个的讲解
用于多分类的交叉熵损失函数:由两步生成
代码一行就可以搞定
f.log_softmax(),就可以对传入的进行softmax和log操作
将准备好的数据放进模型中训练
然后通过反向传播,找到拟合效果最好,误差最低的参数
def train(ones): # 实例化训练模型 for idx, (input, traget) in enumerate(minst2): # 所有参数的梯度,将其值置为0 optimizer.zero_grad() # 模型训练出out out = model1(input) # 得到损失, loss = f.nll_loss(out,traget) # 反向传播计算梯度 loss.backward() # 更新参数值 optimizer.step() if idx % 10 == 0: print(ones, idx, loss.item()) # 保存模型 if idx % 1000 == 0: torch.save(model1.state_dict(),'./model.pkl') torch.save(optimizer.state_dict(),'./optimizer.pkl')
1.梯度置于0是默认算出梯度出来会累加
2.反向传播计算梯度的方法,反向传播的原理如下:
这里反向传播a,b,c就是我们所想求的参数,j(a,b,c)就是根据损失函数进行求导的结果,带入算出每一次的参数梯度,并更新
最后进行保存模型,以免每次开始的时候都要从头训练
import os import torch import torchvision from torch.utils.data import DataLoader from torchvision.transforms import Compose,ToTensor, Normalize import torch.nn as nn from torch.optim import Adam import torch.nn.functional as f # 实现手写数字识别 # 准备数据 fn = Compose([ ToTensor(), Normalize((0.1307,), (0.3081,)) ]) minst = torchvision.datasets.MNIST(r'data',train=True,download=True,transform=fn) minst2 = DataLoader(minst,shuffle=True) # 构建模型 class MinstModel(nn.Module): def __init__(self): super(MinstModel, self).__init__() self.fc1 = nn.Linear(28 * 28 * 1, 28) # 定义Linear的输入和输出的形状 self.fc2 = nn.Linear(28, 10) # 定义Linear的输入和输出的形状 def forward(self, input): # 因为原始输入数据为的形状:[batch_size,1,28,28],要进行神经网络的运算,需要进行矩阵的乘法 # 所以需要变换形状 # 将input修改为[batch_size,28*28] input = input.view(-1, 28*28) # 进行一次全连接(乘法),变换形状 input = self.fc1(input) # 激活函数处理,处理函数为ReLU,图片适用 input = f.relu(input) # 再进行一次全连接 out = self.fc2(input) # 对输出进行一次softmax和取对数 out = f.log_softmax(out,dim=-1) return out model1 = MinstModel() # 优化类的使用方法: # 实例化,c optimizer = Adam(model1.parameters(), lr=0.001) if os.path.exists('model.pkl'): model1.load_state_dict(torch.load('./model.pkl')) optimizer.load_state_dict(torch.load('./optimizer.pkl')) def train(): # 实例化训练模型 for idx, (input, traget) in enumerate(minst2): # 所有参数的梯度,将其值置为0 optimizer.zero_grad() # 模型训练出out out = model1(input) # 得到损失, loss = f.nll_loss(out,traget) # 反向传播计算梯度 loss.backward() # 更新参数值 optimizer.step() if idx % 10 == 0: print(idx, loss.item()) # 保存模型 if idx % 1000 == 0: torch.save(model1.state_dict(),'./model.pkl') torch.save(optimizer.state_dict(),'./optimizer.pkl') if __name__ == '__main__': train()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。