Day-16 Pytorch 的 Training 流程

  • 我们昨天已经讲解完了最基础 Regression 的简易 Pytorch 实作了,那我们今天要稍微煞车一下,把整个 Training 的流程给好好介绍一遍
  • 一样先回归到机器学习的三个步骤
    • 第一步当然是要先决定我们的 Function set 也就是 Model(模型)的部分,Model 会决定我们整个资料选择撷取的方式方向,因此这步骤当然非常重要,他会决定了我们的判断状况
    • 第二步就是要来看看"糟糕程度" Loss function ,还有当然就要来更新(在这里我更喜欢解释成"优化",因为更新参数本来就是为了更好的判断结果)
    • 最後就是输出结果
  • 这三个步骤在任何地方都不会被改变,因此 Pytorch 的三步骤当然也要遵守这些步骤,让我们直接看看如何实作吧~

Pytorch 实作优化

Pytorch 演算法引用

  • Pytorch 提供了很庞大的资料库让我们去引用,里面有各式各样常见的模型架构,我们只要搭配相对应的初始参数的给予,就能够方便快速地建立起相对应的演算法,因此我们要先把套件引用好
import torch
import torch.nn as nn

Pytorch loss function & optimizer

  • 在 Day-15 的 MSE loss 是长这样
# set up loss function as mean square error
def loss(y, y_predicted):

    return ((y_predicted-y) ** 2).mean()
  • 那使用 Pytorch 的 loss function 的话会变成
# MSE in pytorch
loss = nn.MSELoss()
  • 那我们也要基於 loss function 去对资料做优化,在 Pytorch 有一个工具叫做 optimizer(优化器),那我们只要在里面放置希望更新的变数,就可以达到变数更新的效果
# set stochastic gradient descent as optimizer
optimizer = torch.optim.SGD([w], lr=learning_rate)

Pytorch 版本的 Regression loss function & optimizer

  • 我们已经把 regression 中的 loss function 跟 optimizer 交给 Pytorch,也就是把检查错误状况跟更新参数的方式给 Pytorch,那我们来看看整个程序会变成怎样
import torch
import torch.nn as nn

# f = w * x
# f = 2 * x, we set w as 2
x = torch.tensor([1, 2, 3, 4, 5, 6], dtype=torch.float32)
y = torch.tensor([2, 4, 6, 8, 10, 12], dtype=torch.float32)

# init weight
# 这边要注意,我们希望 Pytorch 帮我们计算更新的 Gradient 变数是 w,所以一定要开 requires_grad 在这个变数上
w = torch.tensor(0.0, dtype=torch.float32, requires_grad=True)

# model prediction
def forward(x):
    
    return w * x

# Training
learning_rate = 0.01
n_iters = 10

print(f'Prediction before training: f(5) = {forward(5): .3f}')

# MSE in pytorch
loss = nn.MSELoss()
# set stochastic gradient descent as optimizer
optimizer = torch.optim.SGD([w], lr=learning_rate)

for epoch in range(n_iters):
    # perdiction = forward pass
    y_pred = forward(x)

    # loss
    l = loss(y, y_pred)

    # gradient descent is where calculate gradient and update parameters
    # so gradient descent here includes gradients and update weights
    # 原本在 Python 的 example 还需要自己建立 Gradient 函式
    # gradients = backward pass
    l.backward() # calculate dl/dw

    # update weights
    optimizer.step()

    # zero gradients
    optimizer.zero_grad()

    if epoch % 1 == 0:
        print(f'epoch {epoch + 1}: w = {w:.3f}, loss = {l:.8f}')

print(f'Prediction after training: f(5) = {forward(5): .3f}')

# Prediction before training: f(5) =  0.000
# epoch 1: w = 0.607, loss = 60.66666794
# epoch 2: w = 1.029, loss = 29.44422913
# epoch 3: w = 1.324, loss = 14.29059505
# epoch 4: w = 1.529, loss = 6.93586159
# epoch 5: w = 1.672, loss = 3.36628079
# epoch 6: w = 1.771, loss = 1.63380527
# epoch 7: w = 1.841, loss = 0.79295844
# epoch 8: w = 1.889, loss = 0.38485837
# epoch 9: w = 1.923, loss = 0.18678898
# epoch 10: w = 1.946, loss = 0.09065709
# Prediction after training: f(5) =  9.731

model select

  • 在 Day-15 的时候,我们是自己撰写 forward pass function,也就是我们的 model 的部分
# init weight
w = torch.tensor(0.0, dtype=torch.float32, requires_grad=True)

# model prediction
def forward(x):
    
    return w * x
  • 那如果我们要使用 Pytorch 的预设 model 的话,其实我们就不用撰写了,只要引用就好,我们甚至不需要 weight init 了,因为 Pytorch 会自己初始化好需要的变数,例如 weight 或是 bias 都会准备好
  • 那这边要注意的是,这些 Model 会需要给予一些需要的参数,神经元传递是会有 input 数量 跟 output 数量 的,所以 Model 这边在使用要注意需要那些参数
  • 另外还要注意资料的结构了,对於目前的例子还说,我们是有 6 笔资料,每笔资料 1 个特徵,因此需要调整一下资料状况
# change data look
x = torch.tensor([[1], [2], [3], [4], [5], [6]], dtype=torch.float32)
y = torch.tensor([[2], [4], [6], [8], [10], [12]], dtype=torch.float32)

n_samples, n_features = x.shape
print(n_samples, n_features)

input_size = n_features
output_size = n_features

model = nn.Linear(input_size, output_size)

...

# optimizer 更新就是 model 的 parameters
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

for epoch in range(n_iters):
    y_pred = model(x)
    
    ...
    
    if epoch % 1 == 0:
        [w, b] = model.parameters()
        print(f'epoch {epoch + 1}: w = {w[0][0]:.3f}, loss = {l:.8f}')

All Pytorch Regression

  • 下面就是把整个 Regression Code 完全更新之後的样子,给大家做个参考
import torch
import torch.nn as nn

# f = w * x + b
# f = 2 * x + 0, we set w as 2, b as 0
x = torch.tensor([[1], [2], [3], [4], [5], [6]], dtype=torch.float32)
y = torch.tensor([[2], [4], [6], [8], [10], [12]], dtype=torch.float32)

x_test = torch.tensor([5], dtype=torch.float32)
n_samples, n_features = x.shape
print(n_samples, n_features)

input_size = n_features
output_size = n_features

model = nn.Linear(input_size, output_size)

# Training
learning_rate = 0.01
n_iters = 10

print(f'Prediction before training: f(5) = {model(x_test).item(): .3f}')

# MSE in pytorch
loss = nn.MSELoss()
# set stochastic gradient descent as optimizer
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

for epoch in range(n_iters):
    # perdiction = forward pass
    y_pred = model(x)

    # loss
    l = loss(y, y_pred)

    # gradient descent is where calculate gradient and update parameters
    # so gradient descent here includes gradients and update weights
    # 原本在 Python 的 example 还需要自己建立 Gradient 函式
    # gradients = backward pass
    l.backward() # calculate dl/dw

    # update weights
    optimizer.step()

    # zero gradients
    optimizer.zero_grad()

    if epoch % 1 == 0:
        [w, b] = model.parameters()
        print(f'epoch {epoch + 1}: w = {w[0][0]:.3f}, loss = {l:.8f}')

print(f'Prediction after training: f(5) = {model(x_test).item(): .3f}')

每日小结

  • 今天已经把整个 Pytorch 的基础 Training 流程跟结构都说明完毕了,其实可以发现跟机器学习核心概念一毛毛一样样,所以在这里再次强调,基础打稳用 Framework 就可以事半功倍,让 Framework 帮我们解决恼人的运算问题
  • 到目前为止的所有 Pytorch Coding Example 皆来自 Youtube Pytorch Tutorial,其实这部影片就把很多 Pytorch 使用介绍得非常清楚了,笔者在这里算是个翻译,强烈推荐自己去看过一遍,会有帮助
  • 明天我们就开始练习建立自己的 Logistic Regression Model 来一样解决之前 Day-09 的 Logistic Regrssion 实作

<<:  android studio 30天学习笔记-day 16-databinding Recyclerview

>>:  【心得】不同 gradient 使用方式-- linear-gradient()

[铁人赛 Day12] 来读 Hooks FAQ 文件吧! - Hooks 取代 render props 跟 HOC 的用法了吗?

版本与支援 Hooks 是 React 16.8 版本推出的语法,React Native 则是在...

更新网格交易机器人

改成使用targetCapital这个变数来控制总部位大小,不用每天开机器人的时候还要算加减多少钱。...

Day20 - ImageView(二)

昨天已经学会把ImageView图片设为Android内建的图片 但说实话 内建的图片ICON我到目...

Day22 Istio

由於 Open-Match 在 service 与 service 之间,是建议使用 gRPC 进行...

【DAY 01】 学习网页的第一步

前言 不管你是不是学程序的,常常都会接触到网页,常常会听到网页就是HTML、CSS和JavaScri...