一、数据集:
使用内置MINST函数处理数据。代码会自动下载数据。代码见dataset.py
二、代码部分:
网络结构:
网络结构为三层神经网络,第一层为输入层,第二层为隐藏层,第三层为输出层,输入层大小为784,隐藏层为256,输出层大小为10。
前向传播方法:view函数将x展平为一维向量,在实际训练中,输入的x为28*28的灰度图像。通过view函数展平后,得到784个值,将此数据输入第一个线性层,输出256个值,再使用ReLu函数激活256个值再更新给x,再通过输出层输出10个值。其中最大的值的索引就为网络预测的值。
训练过程:
训练过程包括5个步骤:计算神经网络结果,计算损失,计算梯度,根据梯度更新参数,清零梯度
dataset.py
import torchvision
from torch.utils.data import DataLoader
from torchvision import transforms
transform = transforms.Compose([
transforms.ToTensor() # 转换为张量
])
def getDataloder():
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
print("train_dataset length: ", len(train_dataset))
# 小批量的数据读入
train_loader = DataLoader(train_dataset, batch_size=512, shuffle=True, num_workers=8)
print("train_loader length: ", len(train_loader))
return train_loader
def getTestloder():
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
print("train_dataset length: ", len(test_dataset))
# 小批量的数据读入
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=True)
print("train_loader length: ", len(test_loader))
return test_loader
if __name__ == '__main__':
getDataloder()
model.py
import torch
from torch import nn
#from torch import Module
# 定义神经网络Network
class Network(nn.Module):
def __init__(self):
super().__init__()
# 线性层1,输入层和隐藏层之间的线性层
self.layer1 = nn.Linear(784, 256)
# 线性层2,隐藏层和输出层之间的线性层
self.layer2 = nn.Linear(256, 10)
# 在前向传播,forward函数中,输入为图像x
def forward(self, x):
x = x.view(-1, 28 * 28) # 使用view函数,将x展平
x = self.layer1(x) # 将x输入至layer1
#x = torch.sigmoid(x) # 使用relu激活
x = torch.relu(x)
return self.layer2(x) # 输入至layer2计算结果
train.py
import torch
from torch import nn
from torch import optim
from model import Network
#from dataset import getDataloder
from dataset_csdn import getDataloder
if __name__ == '__main__':
# 小批量的数据读入
train_loader = getDataloder()
print("train_loader length: ", len(train_loader))
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = Network().to(device) # 模型本身,它就是我们设计的神经网络
optimizer = optim.Adam(model.parameters()) # 优化模型中的参数
#criterion = nn.BCEWithLogitsLoss()
criterion = nn.CrossEntropyLoss() # 分类问题,使用交叉熵损失误差
# 进入模型的迭代循环
for epoch in range(10): # 外层循环,代表了整个训练数据集的遍历次数
# 整个训练集要循环多少轮,是10次、20次或者100次都是可能的,
# 内存循环使用train_loader,进行小批量的数据读取
for batch_idx, (data, label) in enumerate(train_loader):
data = data.to(device)
label = label.to(device)
# 内层每循环一次,就会进行一次梯度下降算法
# 包括了5个步骤:
output = model(data) # 1.计算神经网络的前向传播结果
loss = criterion(output, label) # 2.计算output和标签label之间的损失loss
loss.backward() # 3.使用backward计算梯度
optimizer.step() # 4.使用optimizer.step更新参数
optimizer.zero_grad() # 5.将梯度清零
# 这5个步骤,是使用pytorch框架训练模型的定式,初学的时候,先记住就可以了
# 每迭代100个小批量,就打印一次模型的损失,观察训练的过程
if batch_idx % 100 == 0:
print(f"Epoch {epoch + 1}/10 "
f"| Batch {batch_idx}/{len(train_loader)} "
f"| Loss: {loss.item():.4f}")
torch.save(model.state_dict(), 'mnist_new.pth') # 保存模型
test.py
import torch
from dataset import getTestloder
from model import Network
if __name__ == '__main__':
testDataloader = getTestloder()
model = Network()
model.load_state_dict(torch.load('./mnist_new.pth'))
true_count = 0
false_count = 0
for idx,(image,label) in enumerate(testDataloader):
predict = model(image).argmax(1).item()
#print(predict)
if predict == label:
true_count += 1
else:false_count += 1
Accuracy = true_count/(true_count+false_count)
print(Accuracy)
#if(predict == label):
三、项目下载
项目下载地址: 点击下载