Pytorch深度学习指南 卷I --编程基础(A Beginner‘s Guide) 第0章
书接上回,为了使用好的深度学习的框架,我们需要使用pytorch的工具,那么必然要使用到我们的各种各样的关于pytorch的函数的用法,所以我们阅读了Pytorch深度学习指南,将里面的核心的关键的内容进行归纳和整理,当然这里的假设你有一定的numpy和简单的机器学习的基础。当然没有话也无所谓,你就当成pytorch的工具书也是一样,本书为第一卷,总共只有3章,包含了一章0,用于打一点简单的基础(简单的介绍,数据,梯度,学习率,标准化等)
环境安装
具体的python的执行环境,我这边就不会详细介绍了,关于jupyter,bind, google colab的使用大家可以分别的参考的不同的工具的安装步骤和环境进行配置
可视化梯度下降
可视化梯度下降是为对于为什么可以使用代码来进行学习的人的提供的一个简单的介绍,通过图形的方式来执行出来解释什么是梯度,如何学习梯度,什么是批量,为什么要标准化等等。
原文中说的一句话很重要,只有我们理解了什么是梯度下降,你才能明白我们的很多行为的包括选择一些超参,数据特征,以及学习率等对于模型的迭代的效果和影响是什么
我们将会通过一个线性回归的例子,来实现话不多说,直接上代码
第一步,引用模块,我们这里使用了numpy模块用于生成和计算数据,使用了机器学习的线性回归的模块,用于计算我们的线性回归的一些用法
注意原文全部都使用了42作为随机的种子,我这里是不打算配置这个随机的种子的,所以我的结果可能和书本上还有一定的差距
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
我们整体的步骤分为如下的步骤
- 生成随机数据(-2步)
- 分类随机数据(-1步)
- 计算当前的模型的预测(1)
- 计算损失(2)
- 计算梯度(3)
- 更新参数(使用梯度和超参)(4)
- 循环往复(1-4)
#显然我们这里要使用一些随机的但是符合一定的分布的图形来生成随机数据作为我们的学习的数据
# 真实模型 y = b + w*x + e
# 如果你希望你的demo每次的运行都是一样的,你需要设置
#np.random.seed(42)
true_b = 1
true_w = 2
N = 100
x = np.random.rand(N,1)
epsilon = (.1 * np.random.randN(N,1))
y = true_b + true_w * x + epsilon
接下来我们需要将数据分离成训练数据,验证数据,如果你不懂,你可以简单的查询一下,简单来说就是一部分用于学习,一部分用于验证模型的形式
# Shuffles the indices,生成序列,打乱序列,按照0.8的比例获取训练数据和0.2的验证数据
idx = np.arange(N)
np.random.shuffle(idx)
# Uses first 80 random indices for train
train_idx = idx[:int(N*.8)]
# Uses the remaining indices for validation
val_idx = idx[int(N*.8):]
# Generates train and validation sets
x_train, y_train = x[train_idx], y[train_idx]
x_val, y_val = x[val_idx], y[val_idx]
得到我们的数据的分离的图,左边是我们的生成的训练数据,右边是验证数据的分布
接下来证明学习的可能性,但是假设我们知道了模型是w,b吗,我们可以随机初始化两个数据w,b
b = np.random.randn(1)
w = np.random.randn(1)
print(b, w)
[0.64768854] [1.52302986]
接下来,使用我们的随机的初始化的参数来计算当前的x对应的y值,和原本的真实的y值之间的差异作为我们的误差(损失)
这里的直接画出来了,真实的点和我们的预测的点的分布(虚线的部分)
这里使用了我们的mse的loss值来计算,这里会将所有的点到真实的点之间的距离的平方来取平均值来作为我们的loss值
M E S = 1 n ∗ ∑ t = 1 n ( b + w ∗ x t − y t ) 2 MES = \frac{1}{n} * \sum_{t=1}^{n}(b + w*x_t - y_t)^2 MES=n1∗∑t=1n(b+w∗xt−yt)2,带入代码
# Step 2 - Computing the loss
# We are using ALL data points, so this is BATCH gradient
# descent. How wrong is our model? That's the error!
error = (yhat - y_train)
# It is a regression, so it computes mean squared error (MSE)
loss = (error ** 2).mean()
print(loss)
0.4023279262473404
显然我们想要讨论梯度, 我们使用了所有的w,b的组合(实际的范围就是-3到3之间),对于每一个w,b的组合,我们计算这个损失函数,然后我们绘制了一个图像,左图是3D图,意思是在一个特定的w,b的组合的loss值,显然loss值越低则这个函数的性能越好,右图是一个等高线图
所谓的梯度就是这个函数的变换的程度,也就是这个图像的陡度,分别确定了一个w值以后可以得到b值的变化的趋势,我们叫做偏导数,就是b在特定的w上的梯度,确定了一个b值以后,w的变化的程度就是w的梯度,
已知了梯度是偏导数,那么我们就可以计算出来具体的是方程,根据MSE的偏导数可以知道b的偏导数就是
∂
M
E
S
∂
b
=
2
∗
1
n
∗
∑
t
=
1
n
(
b
+
w
∗
x
t
−
y
t
)
=
2
∗
1
n
∗
(
y
_
h
a
t
−
y
)
\frac{\partial{MES}}{\partial b} = 2 * \frac{1}{n} * \sum_{t=1}^{n}(b + w*x_t - y_t) = 2 * \frac{1}{n} *(y\_hat - y)
∂b∂MES=2∗n1∗∑t=1n(b+w∗xt−yt)=2∗n1∗(y_hat−y),
∂
M
E
S
∂
b
=
2
∗
1
n
∗
∑
t
=
1
n
(
b
+
w
∗
x
t
−
y
t
)
=
2
∗
x
t
∗
1
n
∗
(
y
_
h
a
t
−
y
)
\frac{\partial{MES}}{\partial b} = 2 * \frac{1}{n} * \sum_{t=1}^{n}(b + w*x_t - y_t) = 2 *x_t * \frac{1}{n} *(y\_hat - y)
∂b∂MES=2∗n1∗∑t=1n(b+w∗xt−yt)=2∗xt∗n1∗(y_hat−y)
这个是梯度是当前的增长的方向,为了能让loss变小,我们需要朝着loss变小的地方去执行,所以我们叫做反向的梯度算法 ,给定一个学习率 η \eta η,那么当前的就会按照梯度的方向前进学习率的步数,这里显然,如果我们的考虑越靠近的局部最小点的时候的梯度越小,那么如果我们的 η \eta η设置的过大,就会跳过最小点,从而导致无法收敛的问题,但是如果学习率过小,就会导致需要迭代的步数过长,所有这是一个超参,需要根据不同的时候来选择,或者我们可以认为当曲率大的时候就配置大一点,小的时候则配置更小一点,
标准化
注意到,我们的学习率将会使用到当前函数的所有的变量,为了保持一个合适的学习率,显然我们需要让所有的参数的步子都不要太大,换句话说,所有的参数的最大的学习率限制了我们对于学习率的使用的大小,显然我们可以通过一定的变化将所有的参数都变成一个(0,1)的正态分布,同时我们记录下这个对应的变化叫做(transform),具体的方法我们将会在后面的章节给出)
循环往复
显然通过多次的学习,我们可以调整我们的w,b的参数,最终我们将会收敛到一个靠近的到真实值的w,b的权重
原文地址:https://blog.csdn.net/liuhui244/article/details/145234306
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!