pyTorch学习笔记(8)--手写体识别
1.加载数据预处理1.1需要导入的包和函数1.2 加载数据及处理1.3封装数据
2.设置神经网络3.定义优化器和损失函数4.训练模型4.总代码
1.加载数据预处理
1.1需要导入的包和函数
from torchvision
.datasets
import MNIST
import torchvision
from torch
.utils
.data
import DataLoader
import torch
from torch
.autograd
import Variable
import torch
.nn
as nn
import numpy
import os
1.2 加载数据及处理
首先获取MNIST 数据集,如果没有就下载,设置download=True。如果下载了设置为False,然后train=True,设置这是训练集,transform=torchvision.transforms.ToTensor(),是将图片数据做一些处理和转化为tensor,
train_set
=MNIST('./mnist',train
=True
,
transform
=torchvision
.transforms
.ToTensor(),
download
=True
)# 数据集目录nmist
, 训练集 ,转为tensor
,没有数据就下载
test_set
=MNIST('./mnist',train
=False
,
transform
=torchvision
.transforms
.ToTensor(),
download
=True
)
1.3封装数据
将数据封装到这个DataLoader里边,即一个迭代器每次迭代除出16张图片,返回图片和标签。
train_data
= DataLoader(train_set
, batch_size
=16, shuffle
=True
) #每次
16 张图片,顺序打乱
test_data
= DataLoader(test_set
, batch_size
=16, shuffle
=False
)
2.设置神经网络
设置好神经网络后,返回一个(batch,class_num),返回一多少batch(这里是16张图片)class_num是分类类别是多少这里是10,返回一个这样的矩阵。
class mncnn(nn
.Module
):
def
__init__(self
):
super(mncnn
,self
).__init__()
self
.cov1
=nn
.Sequential(
nn
.Conv2d(1,16,5,1,2), #
16*28*28
nn
.ReLU(),
nn
.MaxPool2d(kernel_size
=2) #
16*14*14
)
self
.cov2
=nn
.Sequential(
nn
.Conv2d(16,32,5,1,2),#
32*14*14
nn
.ReLU(),
nn
.MaxPool2d(2) #
32*7*7
)
self
.out
=nn
.Linear(32*7*7,10)
def
forward(self
, x
):
x
=self
.cov1(x
)
x
=self
.cov2(x
)
x
=x
.view(x
.size(0),-1) #拉平
变成 (bitch
, 32*7*7)
output
=self
.out(x
) #
输出一个(batch
,10)
return output
3.定义优化器和损失函数
net
=mncnn()
#定义 优化器
,损失函数
optimizer
=torch
.optim
.Adam(net
.parameters(),lr
=0.001)
lossfunc
=nn
.CrossEntropyLoss()
4.训练模型
losses
= []
acces
= []
eval_losses
= []
eval_acces
= []
for e
in range(20):
train_loss
= 0
train_acc
= 0
net
.train()
for t
, data
in enumerate(train_data
):
im
, label
= data
im
= Variable(im
)
label
= Variable(label
)
# 前向传播
out
= net(im
)
loss
= lossfunc(out
, label
)
# 反向传播
optimizer
.zero_grad()
loss
.backward()
optimizer
.step()
# 记录误差
train_loss
+= loss
.data
# 计算分类的准确率
pred
= torch
.max(out
, dim
=1)[1]
num_correct
= (pred
== label
).sum().float()
acc
= num_correct
/ im
.shape
[0]
train_acc
+= acc
eval_loss
= 0
eval_acc
= 0
net
.eval() # 将模型改为预测模式
for t
, data
in enumerate(test_data
):
im
, label
= data
im
= Variable(im
)
label
= Variable(label
)
out
= net(im
)
loss
= lossfunc(out
, label
)
# 记录误差
eval_loss
+= loss
.data
# 记录准确率
pred
=torch
.max(out
,dim
=1)[1]
num_correct
= (pred
== label
).sum().float()
acc
= num_correct
/ im
.shape
[0]
eval_acc
+= acc
eval_losses
.append(eval_loss
/ len(test_data
))
eval_acces
.append(eval_acc
/ len(test_data
))
print('epoch: {}, Train Loss: {:.6f}, Train Acc: {:.6f}, Eval Loss: {:.6f}, Eval Acc: {:.6f}'
.format(e
, train_loss
/ len(train_data
), train_acc
/ len(train_data
),
eval_loss
/ len(test_data
), eval_acc
/ len(test_data
)))
4.总代码
from torchvision
.datasets
import MNIST
import torchvision
from torch
.utils
.data
import DataLoader
import torch
from torch
.autograd
import Variable
import torch
.nn
as nn
import numpy
import os
train_set
=MNIST('./mnist',train
=True
,transform
=torchvision
.transforms
.ToTensor(),download
=True
)# 数据集目录nmist
, 训练集 ,转为tensor
,没有数据就下载
test_set
=MNIST('./mnist',train
=False
,transform
=torchvision
.transforms
.ToTensor(),download
=True
)
train_data
= DataLoader(train_set
, batch_size
=16, shuffle
=True
) #每次
16 张图片,顺序打乱
test_data
= DataLoader(test_set
, batch_size
=16, shuffle
=False
)
# x
,x_label
=next(iter(train_data
))
#
print(x
.size())
#
print(x_label
.size())
#
print(type(train_data
))
# 定义网络
class mncnn(nn
.Module
):
def
__init__(self
):
super(mncnn
,self
).__init__()
self
.cov1
=nn
.Sequential(
nn
.Conv2d(1,16,5,1,2), #
16*28*28
nn
.ReLU(),
nn
.MaxPool2d(kernel_size
=2) #
16*14*14
)
self
.cov2
=nn
.Sequential(
nn
.Conv2d(16,32,5,1,2),#
32*14*14
nn
.ReLU(),
nn
.MaxPool2d(2) #
32*7*7
)
self
.out
=nn
.Linear(32*7*7,10)
def
forward(self
, x
):
x
=self
.cov1(x
)
x
=self
.cov2(x
)
x
=x
.view(x
.size(0),-1) #拉平
变成 (bitch
, 32*7*7)
output
=self
.out(x
) #
输出一个(batch
,10)
return output
net
=mncnn()
#定义 优化器
,损失函数
optimizer
=torch
.optim
.Adam(net
.parameters(),lr
=0.001)
lossfunc
=nn
.CrossEntropyLoss()
losses
= []
acces
= []
eval_losses
= []
eval_acces
= []
for e
in range(20):
train_loss
= 0
train_acc
= 0
net
.train()
for t
, data
in enumerate(train_data
):
im
, label
= data
im
= Variable(im
)
label
= Variable(label
)
# 前向传播
out
= net(im
)
loss
= lossfunc(out
, label
)
# 反向传播
optimizer
.zero_grad()
loss
.backward()
optimizer
.step()
# 记录误差
train_loss
+= loss
.data
# 计算分类的准确率
pred
= torch
.max(out
, dim
=1)[1]
num_correct
= (pred
== label
).sum().float()
acc
= num_correct
/ im
.shape
[0]
train_acc
+= acc
eval_loss
= 0
eval_acc
= 0
net
.eval() # 将模型改为预测模式
for t
, data
in enumerate(test_data
):
im
, label
= data
im
= Variable(im
)
label
= Variable(label
)
out
= net(im
)
loss
= lossfunc(out
, label
)
# 记录误差
eval_loss
+= loss
.data
# 记录准确率
pred
=torch
.max(out
,dim
=1)[1]
num_correct
= (pred
== label
).sum().float()
acc
= num_correct
/ im
.shape
[0]
eval_acc
+= acc
eval_losses
.append(eval_loss
/ len(test_data
))
eval_acces
.append(eval_acc
/ len(test_data
))
print('epoch: {}, Train Loss: {:.6f}, Train Acc: {:.6f}, Eval Loss: {:.6f}, Eval Acc: {:.6f}'
.format(e
, train_loss
/ len(train_data
), train_acc
/ len(train_data
),
eval_loss
/ len(test_data
), eval_acc
/ len(test_data
)))
训练结果