实验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)))