Fork me on GitHub 0

手写数字识别

torchvision包功能是实现数据的处理、导入和预览等,通过包来获取手写数字的训练集和测试集。

import torch
from torchvision import datasets,transforms
from torch.autograd import Variable
from torchvision.datasets import MNIST

data_train=datasets.MNIST(root='./data/',transform=transforms,train=True,download=True)
data_test=datasets.MNIST(root='./data/',transform=transform,train=False)

 

root存放指定数据集下载之后的存放路径,transform是对数据进行转换操作,train用于指定数据集下载完成后需要载入哪部分数据,如果设置为True,则为该数据集的训练集部分,为False则为测试集部分。

当获取到的图像和我们预期的不一致时,我们可以使用transfrom进行归一化和大小缩放等操作。transform很大一部分可以用于实现数据增强(Data Argumentation)。若我们的数据集有限,可以同宫对有限的图片数据集进行各种变换,生成新的训练集,可以做的是水平或垂直翻转和缩小或放大数据。

transform=transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5]) #将数据进行标准化转换
])

 其中标准化变换计算公式:

 t图片下载完成后,将数据打包载入,通过Batchsize值来确定每个包的大小,shuffle为是否打乱数据

train_loader=DataLoader(dataset=data_train,batch_size=64,shuffle=True)
test_loader=DataLoader(dataset=data_test,batch_size=64,shuffle=True)

  

使用iter和next获取一个批次的图片数据和相对应的标签

torchvision.utils.make_grid功能:
将该批次的图片构成网格模式
每个批次的装载数据都是4维的,维度的构成 从前往后分别为batch_size、channel、height和weight,分别对应一个批 次中的数据个数、每张图片的色彩通道数、
每张图片的高度和宽度。在 通过torchvision.utils.make_grid之后,图片的维度变成了 (channel,height,weight),这个批次的图片全部被整合到了一起
所以 在这个维度中对应的值也和之前不一样了,但是色彩通道数保持不变。

images,labels=next(iter(train_loader))
img=torchvision.utils.make_grid(images)
img=img.numpy().transpose(1,2,0)
mean=[0.5,0.5,0.5]
std=[0.5,0.5,0.5]
img=img*std+mean
print([labels[i] for i in range(64)])
plt.imshow(img)  

将图片进行numpy和transpose转换,从而用matplotlib绘制出图像

 

 

接下来搭建简单的卷积神经网络

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1=nn.Sequential(
            nn.Conv2d(1,64,kernel_size=3,stride=1,padding=1),
            nn.ReLU(),
            nn.Conv2d(64,128,kernel_size=3,stride=1,padding=1),
            nn.ReLU(),
            nn.MaxPool2d(stride=2,kernel_size=2)
        )
        self.dense=nn.Sequential(
            nn.Linear(14*14*128,1024),
            nn.ReLU(),
            nn.Dropout(p=0.5),
            nn.Linear(1024,10)
        )
    def forward(self,x):
        x=self.conv1(x)
        x=x.view(-1,14*14*128)
        x=self.dense(x)
        return x

  

开始对模型进行训练和参数优化

model=Model().to(device)
cost=nn.CrossEntropyLoss()
optimizer=optim.Adam(model.parameters())
n_epochs=5

for epoch in range(n_epochs):
    running_loss=0
    running_correct=0
    print("Epoch{}/{}".format(epoch,n_epochs))
    print("*"*10)
    for data in train_loader:
        images,labels=data
        images,labels=Variable(images),Variable(labels)
        images, labels =images.to(device),labels.to(device)
        y_pred=model(images)
        _,pred=torch.max(y_pred.data,1)
        optimizer.zero_grad()
        loss=cost(y_pred,labels)
        loss.backward()
        optimizer.step()
        running_loss+=loss.item()
        running_correct+=torch.sum(pred==labels.data)
    testing_correct=0
    for data in test_loader:
        images,labels=data
        images, labels = Variable(images), Variable(labels)
        images, labels = images.to(device), labels.to(device)
        y_pred=model(images)
        _, pred = torch.max(y_pred.data, 1)
        testing_correct+=torch.sum(pred==labels.data)
    print("Train Loss:{:4f},Train Accuracy:{:.4f}%,Test Accuracy:{:.4f}".format(running_loss/len(data_train),100*running_correct/len(data_train),100*testing_correct/len(data_test)))

  运行结果:

 

 可以看到结果表现很不错,训练集和测试集最高都达到了99%的准确率,如果使用更加强大的卷积神经网络,会取得比这更好的结果。

 

posted @ 2020-04-07 22:04  amazingcode  阅读(164)  评论(0编辑  收藏  举报