深度学习笔记6:神经网络实现FashionMnist数据集
神经网络建模流程梳理
1. 导入所需要的库
2. 设置步长(学习率)lr,设置动量参数gamma,设置迭代次数epochs,设置批量大小
bs,如果后续需要,可以设置初始权重
3. 导入数据,将数据切分成batchs
4. 定义神经网络架构
5. 定义损失函数
6. 定义优化算法(直接内置在训练函数中)
7. 开始在epoch和batch上循环,执行优化算法:
7.1 调整数据结构,确定数据能够在神经网络、损失函数和优化算法中顺利运行
7.2 完成向前传播,计算初始损失
7.3 反向传播,获取梯度信息
7.4 迭代当前权重
7.5 清空本轮梯度
7.6 完成模型进度与效果监控
8. 输出结果
导入所需要的库
import torch
from torch import nn #构筑神经网络结构
from torch import optim #优化算法模块
from torch.nn import functional as F #神经网络的损失函数和激活函数
from torch.utils.data import DataLoader,TensorDataset #神经网络的数据预处理
import torchvision #导入计算机视觉相关的库
import torchvision.transforms as transforms
设置各种参数信息
lr = 0.5 #学习率,步长
gamma = 0.8 #动量参数
epochs = 5 迭代轮次
bs = 128 #每批量的数据量
导入数据集
mnist = torchvision.datasets.FashionMNIST(
root = r"Lesson 11\MINST-FASHION数据集" #你自己存放数据集的目录
,download = False
,train = True
,transform = transforms.ToTensor() #将数据转化成tensor结构
) #实例化数据
查看数据量:
len(mnist)
#返回60000
查看特征张量:
mnist.data
查看标签以及类别:
mnist.targets
#返回:tensor([9, 0, 0, ..., 3, 0, 5])
mnist.classes
#返回:
['T-shirt/top',
'Trouser',
'Pullover',
'Dress',
'Coat',
'Sandal',
'Shirt',
'Sneaker',
'Bag',
'Ankle boot']
查看图像模样:
import matplotlib.pyplot as plt
import numpy as np
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'
plt.imshow(mnist[0][0].view(28,28).numpy()) #左图
plt.imshow(mnist[1][0].view(28,28).numpy()) #右图


切割数据集操作:
batchdata = DataLoader(mnist
,batch_size=bs
,shuffle = True #随机打乱数据
)#对mnist数据集进行分割,每个批次128个样本,共469个批次
查看数据集
for x,y in batchdata:
print(x.shape)
print(y.shape)
break

第一行表示:每一个批量都是四维,大小是128个样本,每个样本的维度是[1,28,28],1是图像的通道数,值为1代表是灰度图像,[28,28]是图像的高度和宽度,即每个图像是28×28的像素尺寸。
第二行表示:批次中图像对应的标签张量,形状为一维张量,长度等于批次大小128,代表有128个标签。
len(batchdata)
#返回469,共469个批次,除最后一个批次外,都是128个样本
设置输入和输出:
#输入层维度
input_ = mnist.data[0].numel() #计算第一个样本的总元素数量,即总像素数
input_
#返回784
#输出层维度
output_ = len(mnist.targets.unique()) #targets属性存储了所有样本的标签的张量格式
output_
#返回10
定义神经网络架构
class Model(nn.Module):
def __init__(self,in_features = 10, out_features = 2):
super().__init__()
self.linear1 = nn.Linear(in_features,128,bias=False)
self.output = nn.Linear(128,out_features,bias=False)
def forward(self,x):
x = x.view(-1,28*28)
sigma1 = torch.relu(self.linear1(x))
sigma2 = F.log_softmax(self.output(sigma1),dim=1)
return sigma2
view(-1,28*28)将张量x重塑形状,需要对数据结构进行改变,-1作为占位符,自动计算该位置的维度是多少,这里-1将x第一维度设置为128,因为有128个样本,每个样本展平为长度784的一维向量。全连接神经网络的输入需要是一维特征向量,而不是多维图像张量。
F.log_softmax()功能是先对输入应用softmax激活(将原始分数转换为和为1的概率分布),再对结果取自然对数,相比直接用softmax后再取对数,可以避免数值下溢,更稳定。
dim=1是在类别维度上应用操作,对于多分类softmax函数取最后概率,dim一般必须存在且恒取1
定义训练函数(难点)
def fit(net,batchdata,lr=0.01,epochs=5,gamma=0.9):
criterion = nn.NLLLoss() #定义损失函数,与前面的log_softmax函数配套使用
opt = optim.SGD(net.parameters(),lr = lr,momentum = gamma) #定义优化算法小批量梯度下降
correct = 0 #循环开始前,设定预测正确的样本量为0
samples = 0 #循环开始前,一个样本都没有使用过,统计已经使用了多少样本,用来监测完成度
for epoch in range(epochs): #在每个轮次里循环,共epochs个轮次
for batch_idx,(x,y) in enumerate(batchdata): #enumerate同时获取批次索引(batch_idx)和批次数据(样本x,标签y),方便追踪当前处理到第几个批次,共batchdata个轮次
y = y.view(x.shape[0]) #降维,把标签形状调整为一维的形状,x.shape[0]是当前批次样本的数量,除最后一个批次,一般为128
sigma = net.forward(x) #正向传播,输出模型的预测结果,对数概率分布
loss = criterion(sigma,y) #返回当前批次的平均损失
loss.backward() #反向传播,获得梯度信息,梯度存储在.grad属性中
opt.step() #根据反向传播计算出的梯度,按照SGD的规则更新模型所有参数
opt.zero_grad() #清空梯度,pytorch默认累积梯度,不清空会叠加梯度导致错误
yhat = torch.max(sigma,dim = 1)[1] #yhat取值为每个样本被预测的标签值(0-9)
#torch.max函数返回一个两个元素的元组(每个样本在类别维度上的最大值,最大值所在的索引)
#[1]取元组的第二个元素,即每个样本被预测的类别标签,赋值给yhat,yhat[i]就是第i个样本被预测为的数字(0-9其中一个)
correct += torch.sum(yhat == y)
#yhat==y主元素比较yaht与y,预测正确结果为True,pytorch自动转换为整数1,预测错误为0
#用来标记每个样本是否预测正确
#torch.sum()对上述(0、1张量)求和,得到预测样本正确的总数
samples = samples + x.shape[0] #每训练一个batch的数据,模型见过的数据就会增加128
if(batch_idx + 1) % 125 == 0 or batch_idx == len(batchdata) - 1:
#打印条件:每处理125个批次打印一次,以及在当前轮次的最后一个批次强制打印
print("Epoch{}:[{}/{}({:.0f}%)] Loss:{:.6f},Accuracy:{:.3f}".foramt(
epoch+1 #第几个轮次,epoch索引从0开始
,samples #已经查看过的数据
,epochs * len(batchdata.dataset) #整个训练模型一共需要查看多少数据
,100 * samples / (epochs * len(batchdata.dataset)) #训练进度百分比
,loss.data.item() #当前批次的损失值,保留6位小数
,float(100 * correct / samples) #到目前为止累积的准确率,3位小数
)
)
模型训练和评估
定义随机数种子
torch.manual_seed(1412)
net = Model(in_features = input_,out_features = output_) #实例化网络
fit(net,batchdata,lr=lr,epochs=epochs,gamma=gamma) #执行训练函数
结果:

准确率越来越低,本次设置的参数并不是很好的参数,需要调参,调参后续会学习。
使用课件所给最佳参数:
#最佳参数
lr=0.15
gamma=0
epochs= 10
bs=128

更多推荐
所有评论(0)