话不多说,记笔记:
1.整体代码
- 导入库
- 加载数据集 datasets
- 定义数据加载器 dataloader
- 创建模型 class:def _init_(self) #初始化自身属性+模型相关函数
- 选择优化函数 optimizer
- 定义训练函数:数据加载器dataloader、模型model、损失函数loss_fn、优化器optimizer
- 定义测试函数:数据加载器dataloader、模型model、损失函数loss_fn
- 开始训练
- 保存模型参数
- 加载模型:model.load_state_dict(torch.load("model.pth"))
- 获取预测效果
2.代码具体笔记
2.1 导入库
- import A
- from B import A
- from B.a import A
e.g.
from torch import nn : 神经网络模块相关包 from torch.utils.data import DataLoader : 实现一个数据加载器
2.2 加载数据集 datasets
- training_data = datasets.XXX( ) 加载datasets中的XXX数据集
- root = 'data' :保存到 data 文件夹中
- train = True :设定为训练集 or train = False :设定为测试集
- download = True :为 True 时若本地没有该数据集就从官网进行下载-源码会指定官方下载路径
- transform = ToTensor() :此代码作用是对数据进行转换,直接把数据变为输入,相当于是进行了数据预处理;其他数据预处理常用的还有:resize()、尺度变换、随即翻转等。
e.g.
training_data = datasets.FashionMNIST( root='data', train=True, download=True, transform=ToTensor(), ) test_data = datasets.FashionMNIST( root='data', train=False, download=True, transform=ToTensor(), )
2.3 定义数据加载器 dataloader
- training_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)- 加载数据 +设置单次传入的数据数量
e.g.
# 设置一次传入的数据数量 batch_size = 64 # 用于给训练集、测试集分别创建一个数据集加载器 training_dataloader = DataLoader(training_data, batch_size=batch_size) test_dataloader = DataLoader(test_data, batch_size=batch_size) for X, y in test_dataloader: print("shape of X [N, C, H, W]: ", X.shape) # X.shape 表示多个维度的图片 # N:代表传入64张图片 # C:代表通道数(灰度图通道数为1) # H:图片的长 # W:图片的宽 print("Shape of y: ", y.shape, y.dtype) # y:标签。 break # 结果: shape of X [N,C,H,W]: torch.Size([64,1,28,28]) shape of y : torch.Size([64]) torch.int64
2.4 创建模型 class:def _init_(self) #初始化自身属性+模型相关函数
- 如果显卡可用,则用显卡进行训练。
device = "cuda" if torch.cuda.is_available() else 'cpu' print("Using {} device".format(device))
- 模型创建
# 创建模型 class NeuralNetwork(nn.Module): def __init__(self): super(NeuralNetwork, self).__init__() # 平铺,将数据平铺成一维 # https://blog.csdn.net/GhostintheCode/article/details/102530451 self.flatten = nn.Flatten() # 定义linear_relu_stack-由多层神经网络构成 # Sequential 意为其下定义的多层操作一个接一个按顺序进行,把它们前后全部拼接在一起 self.linear_relu_stack = nn.Sequential( #全连接层:28 * 28表示输入维度数量; 512表示目前维度数/下一层输出数量 nn.Linear(28 * 28, 512), #nn.ReLU()表示 ReLU 非线性激活函数 nn.ReLU(), nn.Linear(512, 512), nn.ReLU(), nn.Linear(512, 10), nn.ReLU() ) #def forward(self, x)-forward 定义前向传播函数,x为输入数据 def forward(self, x): x = self.flatten(x) logits = self.linear_relu_stack(x) return logits #model = NeuralNetwork().to(device) :调用刚定义的模型,如果 cuda 可用将模型转到 GPU。 model = NeuralNetwork().to(device) print(model)
2.5 选择优化函数 optimizer
- 损失函数+优化器
# 定义损失函数,计算实际输出与真实相差多少 # 此处使用的是交叉熵损失,为图像分类常用的损失函数 loss_fn = nn.CrossEntropyLoss() # 定义优化器,用来训练时候优化模型参数 # SGD表示随机梯度下降,用于控制实际输出y与真实y之间的相差有多大 # lr=1e-3 代表初始学习率 optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
2.6 定义训练函数:
- 数据加载器dataloader、模型model、损失函数loss_fn、优化器optimizer
- loss值越低越好,预测值与真实值越来越靠近,说明模型设计成功
# 此处定义训练函数,把数据加载器、模型、损失、优化器等传到网络中 def train(dataloader, model, loss_fn, optimizer): # 用于查看 dataloader 有多少张图片-size = len(dataloader.dataset) size = len(dataloader.dataset) # 从数据集中读取batch # batch:一次读取张数,即批次数 # X:图片数据 # y: 图片真实标签 for batch, (X, y) in enumerate(dataloader): # 将数据存到显卡 X, y = X.to(device), y.to(device) # 用于得到预测的结果pred pred = model(X) # 用于计算预测的误差 loss = loss_fn(pred, y) # 优化器工作前先将梯度置0,进行归0操作 optimizer.zero_grad() # 用相差多少这种损失值对模型进行参数更新(反向传播,更新模型参数) loss.backward() # 更新优化其中的参数 optimizer.step() # 每当训练100次,输出当前信息 if batch % 100 == 0: loss, current = loss.item(), batch * len(X) print(f"loss:{loss:>7f} [{current:>5d}/{size:>5d}]")
2.7 定义测试函数:
- 数据加载器dataloader、模型model、损失函数loss_fn
def test(dataloader, model, loss_fn): size = len(dataloader.dataset) num_batches = len(dataloader) # 将模型转换为验证模式 model.eval() # 初始化test_loss、corrent 用来统计每次的误差 test_loss, corrent = 0, 0 # 测试时模型参数不用更新,所以 no_grad,整个模型参数正向推就ok,不反向更新参数 with torch.no_grad(): # 加载数据加载器,得到里面的 X(图片数据)和 y(真实标签) for X, y in dataloader: # 将数据转换为 GPU X, y = X.to(device), y.to(device) # 将图片传图到模型中就得到预测的 pred pred = model(X) # 计算预测值pred和真实值y的差距 test_loss += loss_fn(pred, y).item() # 统计预测正确的个数 corrent += (pred.argmax(1) == y).type(torch.float).sum().item() test_loss /= num_batches corrent /= size print(f"Test Error: \n Accuracy: {(100 * corrent):>0.1f}%, Avg loss:{test_loss:>8f}\n")
2.8 开始训练
epoch = 50 for t in range(epoch): print(f"Epoch {t + 1}\n----------------------") train(training_dataloader, model, loss_fn, optimizer) test(test_dataloader, model, loss_fn) print("Done!")
2.9 保存模型参数
torch.save(model.state_dict(), "model.pth") print("Save PyTorch Model State to model.pth")
2.10 加载模型:model.load_state_dict(torch.load("model.pth"))
- 加载时,需要保证前后呼应,即 :
- 先 torch.load 读取模型 pth, 再用 load_state_dict 读取到里面所有参数。
# 得到先前所定义的模型框架 model = NeuralNetwork() # 框架本身加载模型中的参数 model.load_state_dict(torch.load("model.pth"))
2.11 获取预测效果
- 定于整个标签类
# classes 用于定义整个标签类。 #本身标签中有什么,模型并不知道,只是简化标签为 0、1、2、. . . #之后再将 0、1、2、. . . 对应标签的名字。 classes = [ "T-shirt/top", "Trouser", "Pollover", "Dress", "coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot", ]
# 进入验证阶段,不会梯度更新,只会向前推 model.eval() x, y = test_data[0][0], test_data[0][1] with torch.no_grad(): pred = model(x) # 得到预测类别中最高的那一类,再把最高的这一类对应 classes 中的哪一个标签。 predicted, actual = classes[pred[0].argmax(0)], classes[y] # 最终输出预测值与真实值 print(f'Predicted: "{predicted}", Actual: "actual"')
版权声明:本文为CSDN博主「荣仔!最靓的仔!」的原创文章,遵循 CC 4.0 BY-SA 版权协议。
转载请在醒目位置附上原文出处链接及本声明。