手写数字识别
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%的准确率,如果使用更加强大的卷积神经网络,会取得比这更好的结果。

浙公网安备 33010602011771号