卷积神经网络:MNIST实操+GPU

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.conv1 = nn.Conv2d(1,10,kernel_size=5)
        self.conv2 = nn.Conv2d(10,20,kernel_size=5)
        self.pooling = nn.MaxPool2d(2)
        self.fc = nn.Linear(320, 10)

    def forward(self,x):
        # Flatten data from (n,1,28,28) to (n,784)
        batch_size=x.size(0)                            #(n,1,28,28)
        x = F.relu(self.pooling(self.conv1(x)))         #(n,10,24,24)->(n,10,12,12)
        x = F.relu(self.pooling(self.conv2(x)))         #(n,20,8,8)->(n,20,4,4)
        x = x.view(batch_size,-1)  #Flatten             #(n,320)
        x = self.fc(x)
        return x

net=Net()
device=torch.device("cuda:0"if torch.cuda.is_available()else"cpu") #cuda:1 第二块显卡
net.to(device) #将模型迁移到GPU


#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
        inputs, target = inputs.to(device),target.to(device) #要放到同一块显卡上
        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
            images,labels=images.to(device),labels.to(device)
            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/114327498