实验五:全连接神经网络手写数字

【实验目的】

理解神经网络原理,掌握神经网络前向推理和后向传播方法;

掌握使用pytorch框架训练和推理全连接神经网络模型的编程实现方法。

【实验内容】

1.使用pytorch框架,设计一个全连接神经网络,实现Mnist手写数字字符集的训练与识别。

 

【实验报告要求】

修改神经网络结构,改变层数观察层数对训练和检测时间,准确度等参数的影响;
修改神经网络的学习率,观察对训练和检测效果的影响;
修改神经网络结构,增强或减少神经元的数量,观察对训练的检测效果的影响。

 
#构建一个类线性模型类,继承自nn.Module,nn.m中封装了许多方法
#本模型所用的包含库
import torch
import torch
import torch.nn
from torchvision import datasets
from torchvision import transforms
from torch.utils.data import DataLoader
import torch.nn.functional as F
#检测是否有cuda
device = torch.device(
    'cuda:0'
    if torch.cuda.is_available()
    else 'cpu')
# 准备数据集
batch_size = 32
transform = transforms.Compose([
    transforms.ToTensor()
])
# 下载训练集 MNIST 手写数字训练集
# 数据是datasets类型的
train_dataset = datasets.FashionMNIST(
    root='D:/nosql数据库/image_data', train=True, transform=transforms.ToTensor(), download=True)

test_dataset = datasets.FashionMNIST(
    root='D:/nosql数据库/image_data', train=False, transform=transforms.ToTensor(),download=True)


train_loader = DataLoader(dataset=train_dataset,batch_size=train_batch_size,shuffle=True,pin_memory=True)
test_loader = DataLoader(dataset=test_dataset,batch_size=test_batch_size,shuffle=False,pin_memory=True)

# 定义三层全连接神经网络
class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = torch.nn.Conv2d(
            in_channels=1, out_channels=10, kernel_size=5)
        self.conv2 = torch.nn.Conv2d(
            in_channels=10, out_channels=20, kernel_size=5)
        self.pooling = torch.nn.MaxPool2d(kernel_size=2)
        self.fc = torch.nn.Linear(320, 10)

    def forward(self, x):
        # Flatten data from (n,1,28,28) to (n,784)
        batch_size = x.size(0)
        x = F.relu(self.pooling(self.conv1(x)))
        x = F.relu(self.pooling(self.conv2(x)))
        x = x.view(batch_size, -1)  # Flatten
        x = self.fc(x)
        return x

# 定义模型训练中用到的损失函数和优化器
# parameters()将model中可优化的参数传入到SGD中
model = Net().to(device)
# 构建损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(
    params=model.parameters(),
    lr=0.01, momentum=0.5)


# 定义训练函数
def train(epoch):
    running_loss = 0
    for batch_idx, data in enumerate(train_loader):
        images, labels = data
        images = images.to(device)
        labels = labels.to(device)
        optimizer.zero_grad()
         # 前馈+反馈+更新
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        # 每300次迭代输出一次
        if (batch_idx + 1) % 300 == 0:
            print('[%d,%d],loss is %.2f' %
                  (epoch, batch_idx, running_loss / 300))
            running_loss = 0


# 定义测试函数
def test():
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            images = images.to(device)
            labels = labels.to(device)
            outputs = model(images)
            # 沿着第一维度找最大值的下标
            _, predict = torch.max(outputs, dim=1)
            correct += (labels == predict).sum().item()
            total += labels.size(0)
        print('correct/total:%d/%d,Accuracy:%.2f%%' % (correct, total, 100 * (correct / total)))


# 实例化训练和测试
if __name__ == '__main__':
    for epoch in range(10):
        train(epoch)
        test()

 

posted @ 2022-11-25 11:43  “su"ning  阅读(66)  评论(0编辑  收藏  举报