pytorch入门

it2022-05-05  114

知识点 1、如何把ndarray显示为灰度图 2、数据矩阵reshape为一行 3、把多个数据捆绑为batch,以便加快训练速度 4、反向传播流程 5、tensor.item() 6、tensor.max(1) 7、pred == label 统计预测与标签的正确数 8、统计正确率的注意点 9、str.format() 10、便捷loss变化图

import numpy as np import torch from torchvision.datasets import mnist from torch import nn from torch.autograd import Variable import matplotlib.pyplot as plt

导入数据 下载速度很慢

train_set = mnist.MNIST('./data', train=True, download=True) test_test = mnist.MNIST('./data', train=False, download=True)

知识点1 读入的数据是PIL库中的格式,可以用 a = np.array(b) 的形式方便转化为ndarray 用plt显示出来,直接print只会显示矩阵

a_data, a_label = train_set[0] np_im = np.array(a_data) plt.imshow(np_im, cmap='gray') plt.show()

知识点2 为了方便训练,data_tf 把图像转化为ndarray,然后28 x 28的数据reshape为784 x 1的格式,再转化为tensor 重新导入数据,而不是在上面的数据上操作,因为这样可以直接调用方法,更方便,不需要自己写

def data_tf(x): x = np.array(x, dtype='float32') / 255 x = (x - 0.5) / 0.5 x = x.reshape((-1,)) x = torch.from_numpy(x) return x train_set = mnist.MNIST('./data', train=True, transform=data_tf, download=True) test_set = mnist.MNIST('./data', train=False, transform=data_tf, download=True) a, a_label = train_set[0] print(a.shape) print(a_label)

知识点3(重点)

deep learning 的基操,一定要掌握 由于图片量太大了,一张一张输入网络效率很低,所以下面的操作把每64张图片(训练集)捆绑在一起。这样的好处就是网络一次处理64张图像,效率会高很多。

from torch.utils.data import DataLoader train_data = DataLoader(train_set, batch_size=64, shuffle=True) test_data = DataLoader(test_set, batch_size=128, shuffle=False) a, a_label = next(iter(train_data)) print(a.shape) print(a_label.shape)

各种初始化

# 定义网络结构 net = nn.Sequential( nn.Linear(784, 400), nn.ReLU(), nn.Linear(400, 200), nn.ReLU(), nn.Linear(200, 100), nn.ReLU(), nn.Linear(100, 10) ) # 定义损失函数(交叉熵) criterion = nn.CrossEntropyLoss() # 定义优化器(随机梯度下降) 优化器需要指明要优化的参数,和学习率 optimizer = torch.optim.SGD(net.parameters(), 1e-1) # 定义各种数据,为后面统计结果做准备 losses = [] acces = [] eval_losses = [] eval_acces = []

前方高能

反向传播20次 疑问: net.train() 有没有必要 知识点4 反向转播的标准步骤: 1、把X,y转化为Variable 2、网络计算数据的结果out 3、计算loss 4、归零w、b梯度 5、反向传播 6、修改w、b梯度 知识点5 tensor.item() 把一个只含有1个值的tensor转化为python number 知识点6 _, pred = out.max(1) 这句真的是骚操作 _这个东西就是一个变量,别想复杂了 out是一个64 x 10的tensor 返回的结果就是 _是out tensor每行的最大值组成的tensor 64 x 1 pre是out tensor每行最大值索引组成的tensor 64 x 1 max(1)这里是把输出压缩为1维,记住 知识点7 num_correct = (pred == label).sum().data.item() 这行代码比较好理解,是基操,要记住 知识点8 acc = num_correct / im.shape[0] 计算一张图片的准确率 注意:这里一定是除 im.shape[0] ,而不能偷懒直接除batch_size也就是64。因为一组batch的最后一个的size有可能不是batch_size 比如:有15张图片,batch_size设置为4,那么前面3个batch的size确实是4,但是最后一个batch的size只有3

for e in range(20): train_loss = 0 #记录loss函数下降的过程 train_acc = 0 net.train() # 把网络设置为train模式 for im, label in train_data: # 基操反向传播的标准流程 im = Variable(im) label = Variable(label) out = net(im) loss = criterion(out, label) optimizer.zero_grad() loss.backward() optimizer.step() train_loss += loss.data.item() _,pred = out.max(1) num_correct = (pred == label).sum().data.item() acc = num_correct / im.shape[0] train_acc += acc losses.append(train_loss / len(train_data)) # 记录每次传播的平均loss acces.append(train_acc / len(train_data)) # 记录每次传播的平均准确率

注意下面这段代码前面有4个空格,也就是说它们是在上面的代码for e in range(20): 里面 预测就不需要反向传播了,这里计算loss只是为了看模型的效果 知识点9 str.fromat() 会把()里面的值对应输入到{}中 {:.6}表示保留6位小数

eval_loss = 0 eval_acc = 0 net.eval() # 网络切换为预测模式 for im, label in test_data: im = Variable(im) label = Variable(label) out = net(im) loss = criterion(out, label) eval_loss += loss.data.item() _, pred = out.max(1) num_correct = (pred == label).sum().data.item() 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)))

知识点10 绘图,基操记住 plt.plot(np.arange(losses), losses) 可以很方便的画出loss的变化

import matplotlib.pyplot as plt plt.title('train loss') plt.plot(np.arange(len(losses)), losses) plt.show() plt.plot(np.arange(len(acces)), acces) plt.title('train acc') plt.show() plt.plot(np.arange(len(eval_losses)), eval_losses) plt.title('test loss') plt.show() plt.plot(np.arange(len(eval_acces)), eval_acces) plt.title('test acc') plt.show()

总结流程 1、导入数据并把数据矩阵拉直 2、把数据捆绑为batch 3、定义网络,实例化 损失函数、优化器 4、训练并反向传播(V, out, loss, zero, back, step), 统计数据 5、预测(V, out),统计数据 6、绘图 打完收工,爽!


最新回复(0)