马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 剑魂 于 2024-6-7 11:37 编辑
本文使用MNIST数据集(6w张训练图片,1w张测试图片,数据集为黑白图,图片大小为28*28)
使用Pytorch搭建神经网络
搭建神经网络7步法:1. 数据 2. 网络结构 3. 损失函数 4. 优化器 5. 训练 6. 训练 7. 保存
【说明】:
- 如果数据集总共有60,000条数据,那么使用 batch_size 为100的加载器(loader)将每次加载600条数据。这样,模型会分批次地处理整个数据集,每批次处理600条数据。总共需要60,000 / 100 = 600个批次来处理完整个数据集。
# 0. 导包
import torch
from torchvision import datasets
from torchvision import transforms
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
# 1. 数据准备
train_data = datasets.MNIST(root = "./data", train = True, download = True, transform = transforms.ToTensor())
test_data = datasets.MNIST(root = "./data",train = False, download = True, transform = transforms.ToTensor())
batch_size = 100
train_loader = DataLoader(dataset = train_data, batch_size = batch_size, shuffle = True)
test_loader = DataLoader(dataset = train_data, batch_size = batch_size, shuffle = False)
# 2. 定义网络模型
class MLP(nn.Module):
def __init__(self,input_size,hidden_size,output_classes):
"""
:param input_size: 神经网络的输入数据维度
:param hidden_size: 隐藏层的大小
:param output_classes: 输出分类的大小
"""
super(MLP, self).__init__()
self.fc1 = nn.Linear(input_size,hidden_size) # 定义第一个全连接层
self.relu = nn.ReLU() # 定义激活函数为ReLu
self.fc2 = nn.Linear(hidden_size,hidden_size) # 定义第二个全连接层
self.fc3 = nn.Linear(hidden_size,output_classes) # 定义第三个全连接层
# 前向传播
def forward(self,x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
x = self.relu(x)
x = self.fc3(x)
return x
# 定义参数
input_size = 28*28
hidden_size = 512
output_classes = 10 # 因为手写数字识别有0~9共10个数字所以输入分类为10
model = MLP(input_size,hidden_size,output_classes) # 初始化MLP
# 3. 定义损失函数(本文使用交叉熵损失函数)
criterion = nn.CrossEntropyLoss()
# 4. 定义优化器(用于反向传播更新权重参数)
learning_rata = 1e-3 # 定义学习率为0.001
optimizer = optim.Adam(model.parameters(), lr = learning_rata) # parameters()返回参数,用于更新权重参数
# 5. 训练
num_epoch = 10
for epoch in range(num_epoch):
for i,(images,labels) in enumerate(train_loader):
images = images.reshape(-1,28*28)
outputs = model(images)
loss = criterion(outputs,labels)
# 每次在进入反向传播的时候,都要将梯度进行清零
optimizer.zero_grad()
loss.backward() # 反向传播
optimizer.step() # 更新参数
if (i+1) % 100 == 0:
print(f"Epoch [{epoch+1}/{num_epoch}],Step[{i+1}/{len(train_loader)}] ,loss = {loss.item()}") # .item() 将这个数量转换为一个标量整数
# 6. 测试
# 这里是测试集了,因此我们不需要在进行梯度和参数的更新, 所以我们用no_grad()
with torch.no_grad():
correct = 0
total = 0
# 从 test_loader中循环读取测试数据
for images, labels in test_loader:
images = images.reshape(-1,28*28) # -1 表示自动计算这个维度的大小
outputs = model(images)
_,predicted = torch.max(outputs.data,1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f"Accuracy of the network on the 10000 test images: {100*correct/total}%")
# 7. 保存模型
torch.save(model,'./mnist.pth')
|