神经网络学习--PyTorch学习04 数字识别

实验1.获取数据集,装载并预览数据集

import torch
from torchvision import datasets, transforms
import torchvision
import pylab
import matplotlib.pyplot as plt
from torch.autograd import Variable

transform = transforms.Compose([transforms.ToTensor(),  # transfroms.Compose是一个容器,可以同时对多种数据变换进行组合; ToTenser为类型转变
                                transforms.Normalize(mean=[0.5],  # Normalize 数据标准化变换  mean和std为原始数据的均值和标准差(此处直接赋值)
                                                     std=[0.5])])
data_train = datasets.MNIST(root="./data/",  # 下载数据集MNIST,保存位置 ./data/
                            transform=transform,  # 数据变换
                            train=True,  # 载入训练集
                            download=True)  # 下载
data_test = datasets.MNIST(root="./data/", transform=transform, train=False)

data_loader_train = torch.utils.data.DataLoader(dataset=data_train,  # DataLoader 装载数据
                                                batch_size=64,  # 每个包中图片数据个数
                                                shuffle=True)  # 随机打乱顺序进行打包
data_loader_test = torch.utils.data.DataLoader(dataset=data_test,
                                               batch_size=64,
                                               shuffle=True)

images, labels = next(iter(data_loader_train))  # iter为迭代器,next遍历
img = torchvision.utils.make_grid(images)  # 将同一批次的图片构造成网格模式
# 数据维度 images: batch_size,channel,height,weight =>img: channel,height,weight
img = img.numpy().transpose(1, 2, 0)  # transpose 为交换数据维度 由(channel,height,weight)=>(height,weight,channel)
std = [0.5, 0.5, 0.5]  # 图像为三通道,std为每个通道的方差
mean = [0.5, 0.5, 0.5]  # mean为每个通道的均值
img = img*std+mean  # 灰度拉伸
print([labels[i] for i in range(64)])
plt.imshow(img)
pylab.show()

 实验二 搭建模型进行训练

import torch
from torchvision import datasets, transforms
import torchvision
import pylab
import matplotlib.pyplot as plt
from torch.autograd import Variable

transform = transforms.Compose([transforms.ToTensor(),  # transfroms.Compose是一个容器,可以同时对多种数据变换进行组合; ToTenser为类型转变
                                transforms.Normalize(mean=[0.5],  # Normalize 数据标准化变换  mean和std为原始数据的均值和标准差(此处直接赋值)
                                                     std=[0.5])])
data_train = datasets.MNIST(root="./data/",  # 下载数据集MNIST,保存位置 ./data/
                            transform=transform,  # 数据变换
                            train=True,  # 载入训练集
                            download=True)  # 下载
data_test = datasets.MNIST(root="./data/", transform=transform, train=False)

data_loader_train = torch.utils.data.DataLoader(dataset=data_train,  # DataLoader 装载数据
                                                batch_size=64,  # 每个包中图片数据个数
                                                shuffle=True)  # 随机打乱顺序进行打包
data_loader_test = torch.utils.data.DataLoader(dataset=data_test,
                                               batch_size=64,
                                               shuffle=True)

images, labels = next(iter(data_loader_train))  # iter为迭代器,next遍历
img = torchvision.utils.make_grid(images)  # 将同一批次的图片构造成网格模式
# 数据维度 images: batch_size,channel,height,weight =>img: channel,height,weight
img = img.numpy().transpose(1, 2, 0)  # transpose 为交换数据维度 由(channel,height,weight)=>(height,weight,channel)
std = [0.5, 0.5, 0.5]  # 图像为三通道,std为每个通道的方差
mean = [0.5, 0.5, 0.5]  # mean为每个通道的均值
img = img*std+mean  # 灰度拉伸
# print([labels[i] for i in range(64)])
# plt.imshow(img)
# pylab.show()


# 训练模型
class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.convl = torch.nn.Sequential(
            torch.nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1),  # 卷积层
            # 输入通道数,输出通道数 都为整形
            # kernel_size指卷积核的大小;stride指步长,即卷积核或者pooling窗口的滑动位移。
            # padding指对input的图像边界补充一定数量的像素,目的是为了计算位于图像边界的像素点的卷积响应;
            # ( input_size + 2*padding - kernel_size ) / stride+1 = output_size
            torch.nn.ReLU(),  # 激活函数
            torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(stride=2, kernel_size=2)  # 最大池化层
        )
        self.dense = torch.nn.Sequential(  # 全连接层
            torch.nn.Linear(14*14*128, 1024),
            torch.nn.ReLU(),
            torch.nn.Dropout(p=0.5),  # 防止训练过程发生过拟合,torch.nn.Dropout对所有元素中每个元素按照概率0.5更改为零
            torch.nn.Linear(1024, 10)
        )

    def forward(self, x):  # 前向传播
        x = self.convl(x)  # 输入卷积层
        x = x.view(-1, 14*14*128)  # torch里面,view函数相当于numpy的reshape
        # -1表示一个不确定的数,就是你如果不确定你想要reshape成几行,但是列确定,-1会自动更改为合适的值
        x = self.dense(x)  # 输入全连接层
        return x


model = Model()
# print(model)
cost = torch.nn.CrossEntropyLoss()  # 交叉熵损失函数
optimizer = torch.optim.Adam(model.parameters())  # Adam自适应优化算法
n_epochs = 5

for epoch in range(n_epochs):
    running_loss = 0.0
    running_correct = 0
    print("Epoch {}/{}".format(epoch, n_epochs))
    print("-"*10)
    for data in data_loader_train:
        x_train, y_train = data  # 获取训练样本
        x_train, y_train = Variable(x_train), Variable(y_train)  # 设为计算节点
        outputs = model(x_train)  # 放入模型进行计算
        _, pred = torch.max(outputs.data, 1)  # 返回一个tensor中的最大值
        optimizer.zero_grad()  # 梯度归零
        loss = cost(outputs, y_train)  # 设置损失函数
        loss.backward()  # 反向传播
        optimizer.step()  # 更新参数
        running_loss += loss.item()  # 将损失累计
        running_correct += torch.sum(pred == y_train.data)  # 预测正确的个数
    testing_correct = 0
    for data in data_loader_test:
        x_test, y_test = data  # 获取测试集
        x_test, y_test = Variable(x_test), Variable(y_test)
        outputs = model(x_test)  # 进行预测
        _, pred = torch.max(outputs, 1)  # 返回一个tensor中的最大值
        testing_correct += torch.sum(pred == y_test.data)  # 预测正确的个数
    print("Loss is :{:.4f},Train Accuracy is :{:.4f}%,Test Accuracy is:{:.4f}".format(running_loss/len(data_train),100*running_correct/len(data_train),100*testing_correct/len(data_test)))
原文地址:https://www.cnblogs.com/zuhaoran/p/11462892.html