全连接神经网络手写数字识别实验

【实验目的】

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

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

【实验内容】

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

 

【实验报告要求】

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

 

import torch
import torch.nn as nn
import torch.nn.functional as F
import matplotlib.pyplot as plt
import torchvision
import numpy as np
import torch.optim as optim
from torch.utils.data import Dataset    
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datasets
import os

train_transform = transforms.Compose([
                                transforms.RandomAffine(degrees = 0,translate=(0.1, 0.1)),
                                transforms.RandomRotation((-10,10)),     
                                transforms.ToTensor(),
                                transforms.Normalize((0.1307,),(0.3081,))])
test_transform = transforms.Compose([transforms.ToTensor(),
                                    transforms.Normalize((0.1307,),(0.3081,))])

train_batch_size = 256
learning_rate = 0.006
test_batch_size = 100
random_seed = 2    
torch.manual_seed(random_seed)
torch.cuda.manual_seed_all(random_seed) 

train_dataset = datasets.FashionMNIST(
    root='../datasets', train=True, transform=transforms.ToTensor(), download=False)

test_dataset = datasets.FashionMNIST(
    root='../datasets', train=False, transform=transforms.ToTensor(),download=False)

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(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
  
        self.conv1 = nn.Conv2d(1  ,32, kernel_size=5,padding=2)
        self.conv2 = nn.Conv2d(32 ,64, kernel_size=5,padding=2)
        self.conv3 = nn.Conv2d(64 ,128,kernel_size=5,padding=2)
        self.conv4 = nn.Conv2d(128,192,kernel_size=5,padding=2)

  
        self.rblock1 = ResidualBlock(32)
        self.rblock2 = ResidualBlock(64)
        self.rblock3 = ResidualBlock(128)
        self.rblock4 = ResidualBlock(192)

        
        self.bn1 = nn.BatchNorm2d(32)
        self.bn2 = nn.BatchNorm2d(64)
        self.bn3 = nn.BatchNorm2d(128)
        self.bn4 = nn.BatchNorm2d(192)

 
        self.mp = nn.MaxPool2d(2)


        self.fc1 = nn.Linear(192*7*7, 256) 
        self.fc6 = nn.Linear(256, 10)  

    def forward(self, x):
        in_size = x.size(0)

        x = self.conv1(x)   
        x = self.bn1(x)
        x = F.relu(x)
        x = self.rblock1(x)

        x = self.conv2(x)   
        x = F.relu(x)
        x = self.bn2(x)
        x = self.rblock2(x)

        x = self.mp(x)     


        x = self.conv3(x)   
        x = self.bn3(x)
        x = F.relu(x)
        x = self.rblock3(x)

        x = self.conv4(x)   
        x = self.bn4(x)
        x = F.relu(x)
        x = self.rblock4(x)

        x = self.mp(x)     

        x = x.view(in_size, -1)    
        x = F.relu(self.fc1(x))  

        return self.fc6(x)


os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
torch.backends.cudnn.benchmark = True      
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

torch.cuda.empty_cache()       

model.to(device)


criterion = torch.nn.CrossEntropyLoss() 

optimizer = optim.SGD(model.parameters(),lr=learning_rate,momentum=0.5)   

scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=2, verbose=True, threshold=0.00005, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08)
def train(epoch):
    running_loss =0.0
    for batch_idx,data in enumerate(train_loader,0):
        inputs,target = data
        inputs,target = inputs.to(device),target.to(device)
        optimizer.zero_grad()

       
        outputs = model(inputs)
        loss = criterion(outputs,target)
        loss.backward()
        optimizer.step()

        running_loss+=loss.item()
        if batch_idx%300==299:
            train_loss_val.append((running_loss/300))
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
            running_loss = 0.0

def test():
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            images,labels = data
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            predicted = torch.max(outputs.data,dim=1)       
            total += labels.size(0)
            correct += (predicted==labels).sum().item()
    print('Accuracy on test set: %f %% [%d/%d]' % (100 * correct / total, correct, total))

    return correct/total
train_epoch = []
model_accuracy = []
temp_acc = 0.0
train_loss_val = []
for epoch in range(30):
    train(epoch)
    acc = test()

    print(epoch + 1,acc)
    train_epoch.append(epoch)
    model_accuracy.append(acc)
    scheduler.step(acc)

plt.figure(1)
plt.plot(train_epoch, model_accuracy)
plt.grid(linestyle=':')
plt.ylabel('accuracy') 
plt.xlabel('epoch') 
plt.show()

运行结果:

posted @   1nfinite  阅读(104)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示