Pytorch 0.4 Minist 从零开始构建Logistic模型:
本文将使用普通的矩阵运算实现一个简单的逻辑回归网络,本质上就是单神经元网络 对Minist数据集进行分类,
接着手动实现梯度下降代码,更新网络参数,
然后再从上至下,一步一步用Pytorch 模块重构网络, 逐步添加更多PyTorch功能
便于更深刻的理解 Pytorch模块的背后实现.
1).路径与数据集
from pathlib import Path
DATA_PATH = Path('data')
PATH = DATA_PATH/'mnist'
PATH.mkdir(parents=True, exist_ok=True)
2).下载数据集至路径mnist文件夹,若已手动下载,可跳过这一步
import requests
URL='http://deeplearning.net/data/mnist/'
FILENAME='mnist.pkl.gz'
if not (PATH/FILENAME).exists():
content = requests.get(URL+FILENAME).content
(PATH/FILENAME).open('wb').write(content)
3).解析数据集
import pickle,gzip
with gzip.open(PATH/FILENAME,'rb') as f:
((x_train,y_train),(x_valid,y_valid),_) = pickle.load(f,encoding = 'latin-1')
4).数据可视化
from PIL import Image
I = x_train[0]
I.resize((28, 28))
im = Image.fromarray((I*256).astype('uint8'))
im.show()
5).将数据转换为Pytorch可读取的Tensor 张量
import torch
x_train,y_train,x_valid,y_valid = map(torch.tensor, (x_train,y_train,x_valid,y_valid))
查看训练集属性
n,c = x_train.shape
x_train, x_train.shape, y_train.min(), y_train.max()
1)初始化权重和偏差
import math
weight = torch.randn(784,10)/math.sqrt(784)
weight.requires_grad_() #可使用梯度下降更新
bias = torch.zeros(10,requires_grad=True)
x_train[0].shape ,weight.shape
训练集图片维度为[1,784]
Weight矩阵权重 [784,10]
2) 实现逻辑回归函数
本质上就是 y = ax + b 的矩阵运算
import torch.nn.functional as F
def model(xb):
xb = (xb @ weight) +bias #这里换成 * 会报错
return F.log_softmax(xb,dim=-1)
在Python3 中 a @ b 等价于 torch.matmul(a , b) 既矩阵乘法
3)模型预测
定义一个batch_size ,即一次性运算多少张图片
bs=64
preds = model(x_train[0:bs])
preds[0],preds.shape #查看第一张图片的输出,和整个输出的大小
可以看到单张图片 的 输出维度有10,即对应 0--9的预测值。
一个batch_size的大小的64,所以模型最后输出维度为 (64,10)
这里肯定会有疑问,为什么模型输出为负,这是因为我们使用 F.log_softmax的原因,只需要使用torch.exp 即可得到对应的概率
import numpy as np
torch.exp(preds[0])
loss_fn = F.nll_loss #定义个损失函数
查看一个batch-size的初始loss
loss_fn(preds,y_train[0:bs])
这里我们就完成了一个简单的逻辑回归网络,下一步就是训练它。
lr =0.5 #学习速率
epochs = 2 #训练周期
bs=64 #Batch_size
for epoch in range(epochs):
for i in range((n-1)//bs+1): #遍历所有训练数据
start_i = i*bs
end_i = start_i+bs
xb = x_train[start_i:end_i]
yb = y_train[start_i:end_i] #得到一个Batch_size的数据
preds = model(xb) #模型预测
loss = loss_fn(preds,yb) #计算最初的loss
loss.backward() #开始反向传播
with torch.no_grad():
weight -= weight.grad * lr #更新 Weight
bias -= bias.grad * lr #更新 bias
weight.grad.zero_()
bias.grad.zero_()
loss_fn(model(x_train[0:bs]), y_train[0:bs]) #查看训练后的loss
输出模型预测
model(x_train[0]).exp().argmax() #预测值
y_train[0] #实际值
参考并安利 fast.ai