Pytorch--fast.ai--Mnist 从零开始(1)

 Pytorch 0.4 Minist 从零开始构建Logistic模型:

本文将使用普通的矩阵运算实现一个简单的逻辑回归网络,本质上就是单神经元网络 对Minist数据集进行分类,

接着手动实现梯度下降代码,更新网络参数,

然后再从上至下,一步一步用Pytorch 模块重构网络, 逐步添加更多PyTorch功能

便于更深刻的理解 Pytorch模块的背后实现.

1.MNIST data setup

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()

Pytorch--fast.ai--Mnist 从零开始(1)_第1张图片

2.Basic model 

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])

Trian loop

这里我们就完成了一个简单的逻辑回归网络,下一步就是训练它。

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

你可能感兴趣的:(Pytorch--fast.ai--Mnist 从零开始(1))