动手学深度学习-Day2-深度学习基础

李沐-动手学深度学习-Day2

自动求梯度

/chapter_prerequisite/autograd.ipynb

// 导入
from mxnet import autograd, nd
//示例
x = nd.arange(4).reshape((4, 1))  --产生4个元素的一维向量,在整形成4行1列
x
//Out
[[0.]
 [1.]
 [2.]
 [3.]]
<NDArray 4x1 @cpu(0)>
//调用attach_grad函数来申请存储梯度所需要的内存
x.attach_grad()
//调用record函数来要求MXNet记录与求梯度有关的计算。
with autograd.record():
    y = 2 * nd.dot(x.T, x)  ---做矩阵X的转置和X的dot运算,1行4列*4行1列,得到一个标量
//调用backward函数自动求梯度
y.backward()    ---对标量求梯度,见数学基础部分A.2.4梯度的验证部分
//验证
assert (x.grad - 4 * x).norm().asscalar() == 0
x.grad
//Out x.grad
[[ 0.]
 [ 4.]
 [ 8.]
 [12.]]
<NDArray 4x1 @cpu(0)>

assert语句用于在代码中进行判断,若为False时,程序会引发AssertionError错误
asscalar() 将向量转换成标量,且向量只能为一维含单个元素的向量

训练模式和预测模式

通过调用is_training函数来查看
作用是什么?后续在学习过程中在来回答这一点

// 查看模式
print(autograd.is_training())  ---预测
with autograd.record():
    print(autograd.is_training())   ---训练

对Python控制流求梯度

控制流:程序中包含的一些控制语句,比如循环,条件等。
在运算过程中,需要对变量求梯度

// 如何实现,通过输入a确定后续所有操作
def f(a):   ---定义函数f,其变量为a
    b = a * 2    ----函数的实现
    while b.norm().asscalar() < 1000:    ---while语句中,b的范数在转成标量是否小于1000
        b = b * 2   ---如果是,计算b*2并赋值给b,并循环
    if b.sum().asscalar() > 0:    --如果b求和后为正,执行下面的操作
        c = b
    else:
        c = 100 * b
    return c
 //
a = nd.random.normal(shape=1)  ---产生一个随机的a,标量
a.attach_grad()  ---分配内存
print("a grad:",a.grad)
with autograd.record():   --保留计算记录
    c = f(a)  --调用函数
c.backward() 
print("c:",c)
print("c:",c / a)   ---可以看出函数f(a)实际就是2*a

线性回归

基本要素

1、构建模型
线性回归,就是将要预测的输出与各因素之间是线性关系。假设有两个特征,则模型可以定义为
y ˆ = x 1 w 1 + x 2 w 2 + b . \^{y} = x_1w_1+x_2w_2+b. yˆ=x1w1+x2w2+b.
𝑤1和 𝑤2是权重(weight), 𝑏是偏差(bias)
2、模型训练

  • 训练数据
    training set, sample,label,feature
  • 损失函数
    衡量预测值与真实值之间的误差。 常用的是平房函数,假设对于第i个样本来说,该样本的误差可以表示为平方损失
    l ( i ) ( w 1 , w 2 , b ) = 1 2 ( y ˆ ( i ) − y ( i ) ) 2 l^{(i)}(w_1,w_2,b) = \frac{1}{2}(\^{y}^{(i)}-{y}^{(i)})^2 l(i)(w1,w2,b)=21(yˆ(i)y(i))2
    常数项是为了在求导后的常数系数为1.这一损失函数应该越小越好。显然,这个函数只与模型中的参数有关,因此可以记为“以模型参数为参数的函数”。
    对所有样本的误差函数做平均
    l ( w 1 , w 2 , b ) = 1 n ∑ i = 1 n l ( i ) ( w 1 , w 2 , b ) l(w_1,w_2,b)=\frac{1}{n}\sum_{i=1}^{n} l^{(i)}(w_1,w_2,b) l(w1,w2,b)=n1i=1nl(i)(w1,w2,b)
    训练的目的,是系统找出一组最优的模型参数,可以记为
    w 1 ∗ , w 2 ∗ , b ∗ = arg ⁡ min ⁡ w 1 , w 2 , b l ( w 1 , w 2 , b ) w_1^*,w_2^*,b^*=\mathop{\arg\min}\limits_{w_1,w_2,b}l(w_1,w_2,b) w1,w2,b=w1,w2,bargminl(w1,w2,b)
  • 优化算法
    有解析解(可以用公式表示),数值解(优化算法有限次迭代模型参数来尽可能降低损失函数的值),在求数值解的优化算法中,小批量随机梯度下降(mini-batch stochastic gradient descent)是一种常用的方法,即随机选择参数的初始值,在每次迭代中降低损失函数。每次迭代中,随机均匀采样小批量(mini-batch)B的训练数据,通过对这一小批量数据集中的参数梯度乘以学习率,作为调整量。如下所示:
    w 1 ← = w 1 − η ∣ B ∣ ∑ i ∈ B ∂ l ( i ) ( w 1 , w 2 , b ) ∂ w 1 w_1 \leftarrow =w_1-\frac{\eta}{| \mathcal{B}|}\sum_{i\in\mathcal{B}}\frac{\partial{l^{(i)}(w_1,w_2,b) }}{\partial{w_1}} w1←=w1BηiBw1l(i)(w1,w2,b)
    通过链式求导法则,既可以得到上式的对w1求导后的结论为
    x 1 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) x_1^{(i)}(x_1^{(i)}w_1+x_2^{(i)}w_2+b-y^{(i)}) x1(i)(x1(i)w1+x2(i)w2+by(i))
    在更新参数过程中, η \eta η称为学习率, ∣ B ∣ | \mathcal{B}| B是批量大小,这两个参数都称为超参数(hyperparameter)。

线性回归表示方法

神经网络图

在这里插入图片描述
线性回归是一个单层神经网络,输入层即输入特征,这里假定有两个特征,即特征向量维度为2.输出层就是线性回归的输出,负责计算的单元o称为神经元。输出层和两个输入特征均连接,因此也称为全连接层(fully-connected layer)或稠密层(dense layer)。

矢量计算表达式

矢量计算避免了用for循环做多次逐个元素运算,更节省时间。矢量的表达式为
y ˆ = X w + b \boldsymbol{\^y} =\mathbf{X}\boldsymbol{w} +b yˆ=Xw+b
假设数据样本个数为n,特征维度为d,此时 y ˆ ∈ R n × 1 \boldsymbol{\^y}\in\mathbb{R}^{n\times1} yˆRn×1,样本 X ∈ R n × d \mathbf{X}\in\mathbb{R}^{n\times d} XRn×d,权重 w ∈ R d × 1 \boldsymbol{w}\in\mathbb{R}^{d\times1} wRd×1,偏置 b ∈ R b\in\mathbb{R} bR,对应的样本标签(即真实值) y ∈ R n × 1 \boldsymbol{y}\in\mathbb{R}^{n\times1} yRn×1。模型参数也用矢量表示为 θ = [ w 1 , w 2 , b ] T \boldsymbol{\theta}=[w_1,w_2,b]^T θ=[w1,w2,b]T。损失函数如下
l ( w 1 , w 2 , b ) = 1 n ∑ i = 1 n l ( i ) ( w 1 , w 2 , b ) l(w_1,w_2,b)=\frac{1}{n}\sum_{i=1}^{n} l^{(i)}(w_1,w_2,b) l(w1,w2,b)=n1i=1nl(i)(w1,w2,b)
l ( i ) ( w 1 , w 2 , b ) = 1 2 ( y ˆ ( i ) − y ( i ) ) 2 l^{(i)}(w_1,w_2,b) = \frac{1}{2}(\^{y}^{(i)}-{y}^{(i)})^2 l(i)(w1,w2,b)=21(yˆ(i)y(i))2
当用矢量表示时,可以记为
l ( θ ) = 1 2 n ( y ˆ − y ) T ( y ˆ − y ) l(\boldsymbol{\theta})=\frac{1}{2n}(\boldsymbol{\^y}-\boldsymbol{y})^T(\boldsymbol{\^y}-\boldsymbol{y}) l(θ)=2n1(yˆy)T(yˆy)
小批量随机梯度下降的迭代步骤将相应地改写为

θ ← θ − η ∣ B ∣ ∑ i ∈ B ∇ θ ℓ ( i ) ( θ ) , \boldsymbol{\theta} \leftarrow \boldsymbol{\theta} - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \nabla_{\boldsymbol{\theta}} \ell^{(i)}(\boldsymbol{\theta}), θθBηiBθ(i)(θ),
关于损失函数对参数求导表示为
在这里插入图片描述

线性回归实现

/chapter_deep-learning-basics/linear-regression-scratch.ipynb
导入本节需要的一些包及模块

%matplotlib inline
from IPython import display
from matplotlib import pyplot as plt
from mxnet import autograd, nd
import random

生成数据集样本

假设样本数n=1000,特征维度d=2,因此可以得到 X ∈ R 1000 × 2 \mathbf{X}\in\mathbb{R}^{1000\times 2} XR1000×2,线下回归中的参数为 θ = [ w 1 , w 2 , b ] T = [ 2 , − 3.4 , 4.2 ] T \boldsymbol{\theta}=[w_1,w_2,b]^T=[2,-3.4,4.2]^T θ=[w1,w2,b]T=[2,3.4,4.2]T,定义一个随机噪声 ϵ ∼ N ( μ = 0 , σ 2 = 0.01 ) \epsilon\sim\mathcal{N}(\mu = 0, \sigma^2 =0.0 1) ϵN(μ=0,σ2=0.01)生成标签(label),即真实值 y = X w + b + ϵ \boldsymbol{y} =\mathbf{X}\boldsymbol{w} +b+\epsilon y=Xw+b+ϵ.

num_inputs = 2   ---特征维度
num_examples = 1000   ---样本数
true_w = [2, -3.4]  ---权重w
true_b = 4.2  ---偏差
features = nd.random.normal(scale=1, shape=(num_examples, num_inputs))   ---随机产生1000行2列的特征矩阵,标准差为1
print("feature_1:",features[:,:])
print("feature_1:",features[:, 0])    ----第一个特征,即特征矩阵中的第一列
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b   ---每一行是一个长度为1的向量(标量),得到一个1000*1的列向量
labels += nd.random.normal(scale=0.01, shape=labels.shape)   ---加随机误差
features[0], labels[0]   ---观测特征矩阵的第一行,即第一个样本的两个特征,观测labels矩阵的第一行,即第一个样本的真实值

上述代码运行后,可以看到特征矩阵,样本标签的数值

// 通过生成第二个特征features[:, 1]和标签 labels 的散点图,直观观察两者间的线性关系
def use_svg_display():
    # 用矢量图显示,使⽤svg格式在Jupyter中显⽰绘图
    display.set_matplotlib_formats('svg')
def set_figsize(figsize=(3.5, 2.5)):
    use_svg_display()
    # 设置图的尺寸
    plt.rcParams['figure.figsize'] = figsize
set_figsize()
plt.scatter(features[:, 1].asnumpy(), labels.asnumpy(), 1);  #asnumpy()将MXNet数组转换成NumPy数组

在这里插入图片描述
PS:今天干了点其他事儿,学的较少。
另:我是用的MXNET版本的,新的是用pytorch版本,但是看了很多博客,貌似安装环境很麻烦,暂时就不用新版本了额,内容都是一样的,重点是学会方法么。我也没有去听李沐的课。

  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值