多分类:MNIST实操

import torch
import torch.nn as nn
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim

#1.构建数据集
batch_size=64
transform=transforms.Compose([ #compose类的实例化    RGB多通道(123)  w*h*c  转化为 通道数chanel*宽width*高h
    transforms.ToTensor(), #像素:Z(28*28)>>R(1*28*28) 转化为图像张量(C*W*H)
    transforms.Normalize((0.1307,),(0.3081,)) # 像素值:pixel(0~255)>>[0,1]  均值和方差 x=(x-mean)/std
])
train_dataset=datasets.MNIST(root='../dataset/mnist/',
                             train=True,
                             transform=transform,
                             download=True)
test_dataset=datasets.MNIST(root='../dataset/mnist/',
                             train=False,
                             transform=transform,
                             download=True)

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

#2.搭建神经网络
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.linear1 = nn.Linear(784,512)
        self.linear2 = nn.Linear(512, 256)
        self.linear3 = nn.Linear(256, 128)
        self.linear4 = nn.Linear(128, 64)
        self.linear5 = nn.Linear(64, 10)

    def forward(self,x):
        x = x.view(-1,784) #将图形张量(N*1*28*28)转化成矩阵(N*784)
        x = F.relu(self.linear1(x))
        x = F.relu(self.linear2(x))
        x = F.relu(self.linear3(x))
        x = F.relu(self.linear4(x))
        x=self.linear5(x) #最后一层不需要激活函数
        return x

net=Net()

#3.定义优化器和损失函数
criterion=nn.CrossEntropyLoss()  #这也算是神经网络的一部分
optimizer=optim.SGD(net.parameters(),lr=0.01,momentum=0.5) #冲量值定为0.5 更容易避免 鞍点 或 局部最优解 而找到全局最优解 下山更快

#4.训练模型
def train(epoch):
    running_loss=0.0
    for batch_idx, data in enumerate(train_loader, 0):  # 此函数返回小批量样本的下标数,0代表从第一个开始  ## i,(inputs,labels)
        inputs, target = data  # 本身读出的是一个样本,但是loader自动组合成矩阵并且转化成tensor
        optimizer.zero_grad()

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

        running_loss+=loss.item()
        if batch_idx % 300 == 299:
            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 train_loader:
            images,labels=data
            outputs = net(images)
            _,predicted=torch.max(outputs.data,dim=1) #dim=1 代表对矩阵的行进行求最大值 返回最大值的数值和下标(类别)
            total+=labels.size(0)  #size为元组(N10) 返回N
            correct+=(predicted==labels).sum().item() #每行若预测正确,则为真 最后矩阵求和即为本批量正确个数
    print('Accurance on test set : %d %%' %(100*correct/total))

if __name__=='__main__':
    for epoch in range(10):
        train(epoch)
        test()             #每轮更新后进行一次测试

猜你喜欢

转载自blog.csdn.net/qq_21686871/article/details/114271724