第1关:神经网络概述
下列说法错误的是 D
A、
激活函数可以使神经元搭建输入到输出之间的映射关系。
B、
反馈网络模型在不同 的时刻有属于当前不同的状态,具有一定的记忆功能。
C、
所有神经网络一定都包含输入层、隐藏层、输出层三部分。
D、
理论上而言,网络层次的深度越深,神经网络能够拟合的能力越强,越能够解决更复杂的问题。
第2关:神经元
任务描述
本关任务:通过学习神经元的相关知识,编写一个线性神经元模型。
相关知识
为了完成本关任务,你需要掌握:
神经元模型;
pytorch中torch.mm(a,b)函数的使用。
神经元模型
神经元是神经网络操作的基本信息处理单位,是神经网络实现的基础。神经元模型有三个基本元素:
1.突触或连接链集。每一个都由其权值或者强度作为特征。具体来说,在连到神经元k的突触j上的输入信号x
j
乘以k的突触权值w
kj
;
2.加法器。用于求输入信号被神经元的相应突触加权的和;
3.激活函数。用来限制神经元输入振幅。
其基本结构如下图1:
图1 神经元模型
图中的神经元模型还包括一个外部偏置(bias),记为b
k
。偏置b
k
的作用是根据其为正或是为负,相应地增加或降低激活函数的网络输入。其数学公式如下:
u
k
=
j=1
∑
m
w
kj
x
j
y
k
=φ(u
k
+b
k
)
其中x
1
,x
2
,...,x
m
是输入信号,w
k1
,w
k2
,...,w
km
为神经元k的突触权值,u
k
是输入信号的线性组合器的输出,b
k
为偏置,激活函数为φ(⋅),y
k
神经元输出信号。
pytorch 中 torch.mm(a,b) 函数的使用
pytorch深度学习框架为我们提供了一个进行矩阵乘法的方法——torch.mm(a,b)。
举个例子,假设矩阵 a 的维度为 (3,4),矩阵 b 的维度为(4,2),则torch.mm(a,b)返回的矩阵的维度则为(3,2)。
import torch
import numpy as np
a = torch.tensor(np.random.random((3, 4)), dtype=torch.float32) # 随机生成一个维度为 [3,4] 的矩阵(tensor)
"""
例如:
[[0.3886, 0.3006, 0.4032, 0.9880],
[0.7401, 0.0117, 0.8987, 0.6140],
[0.1048, 0.2333, 0.6146, 0.7663]]
"""
b = torch.tensor(np.random.random((4, 2)), dtype=torch.float32) # 随机生成一个维度为 [4,2] 的矩阵(tensor)
"""
例如:
[[0.3555, 0.2108],
[0.3660, 0.4737],
[0.7785, 0.2913],
[0.3347, 0.4046]]
"""
y = torch.mm(a, b) # y 的维度为 [ 3,2 ]
"""
[[0.8928, 0.7416],
[1.1725, 0.6718],
[0.8576, 0.6217]]
"""
编程要求
根据提示,在右侧编辑器 Begin-End 区间补充代码,编写出神经元模型。
测试说明
平台会对你编写的代码进行测试:
测试输入:无
预期输出:
True
开始你的任务吧,祝你成功!
import torch
def linear(X,w,b):
"""
线性神经元
:param X: 训练数据。形状为[ batch_size, num_inputs ]
:param w: 权值。形状为[ num_inputs,1]
:param b: 偏置项。形状为[ 1 ]
:return: 线性计算结果
"""
# 矩阵相乘可以使用torch.mm(a,b)
########## Begin ##########
y = torch.mm(X,w)+b
########## End ##########
return y
第3关:常见学习方法
下列说法错误的是:B
A、
对于不同的学习方法,他们的目的都是为了减小实际输出和正确值之间的误差。
B、
赫布学习规则中,两个神经元同时被激活, 则这两个神经元之间的权值就会降低;如果它们分别被激活,则它们之间的权值会增加。
C、
最小均方规则基本原理是对一组包含n个元素的输入作为一个线性组合加权求和,对得到的求和结果y与期望输出 d进行比较,计算误差值e,并根据误差值的大小对权值进行调整。
D、
误差修正学习通常与监督学习一起使用,是将系统输出与期望输出值进行比较,并使用该误差来改进。
第4关:优化方法:梯度下降
任务描述
本关任务:通过学习梯度下降法的相关知识,编写一个计算指定函数取得极值时对应的x的值的程序。
相关知识
为了完成本关任务,你需要掌握:
优化算法概述;
梯度下降法;
梯度消失。
优化算法概述
优化算法的作用是通过不断改进模型中的参数使得模型的损失最小或准确度更高。在神经网络中,训练的模型参数主要是内部参数,包括权值(W)和偏置(B) 。
模型的内部参数在有效训练模型和产生准确结果方面起着非常重要的作用。常见的优化算法分为两类。
1.一阶优化算法。
该算法使用参数的梯度值来最小化损失值。最常用的一阶优化算法是梯度下降。函数梯度可以采用导数
dx
dy
的多变量表达式进行表达,用于表示 y 相对于 x 的瞬时变化率 。 通常为了计算多变量函数的导数,用梯度代替导数,并使用导数来计算梯度 。
2.二阶优化算法。
二阶优化算法使用二阶导数(也称为 Hessian 方法)来最小化损失值,以 Newton 法和Quasi-Newton 法为代表的二阶优化算法目前最大的困难在于计算复杂度 , 正是由于二阶导数的计算成本较高,因此该方法未得到广泛应用。
梯度下降法
梯度下降法( Gradient Descent)是机器学习中最常用的优化方法,常常用于求解目标函数的极值。梯度是一个向量,表示函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向变化最快、变化率最大,这个方向即为此梯度的方向,变化率即为该梯度的模 。
梯度下降是一种基于不断迭代的运算方法,每一步都是在求解目标函数的梯度向量,在当前位置的负梯度方向作为新的搜索方向,从而不断迭代。之所以采用在当前位置上的梯度反方向,是由于在该方向上的目标函数下降最快,可以找到局部最小值:同理, 要是沿着梯度的正方向作为新的搜索方向,则找到的是局部最大值。
例如,对于输入(x
1
,x
2
)分别表示人的身高和体重,通过f(x
1
,x
2
)输出的是偏胖或不偏胖的结果。现给定一堆的(x
1
,x
2
)集合,通过训练使得f(x
1
,x
2
)对于输入的值都能够判定其属于偏胖或不偏胖。拟合函数可以采用如下公式 :
f(x)=θ
1
x
1
+θ
2
x
2
+x
3
训练的过程则是找到有效的f(x)函数,使得训练中的样本均满足f(x)的输出结果 。 因此可以定义一个误差函数如下所示,误差函数表达的是预测值与真实值差的平方和的一半:
Loss(θ)=
2
1
i=1
∑
n
[(f(x
i
)−y
i
]
2
其 中 x
i
表示第 i 个输入样本,y
i
表示训练样本的期望输出,f(x
i
)是实际训练结果的输出 。
对于整个系统而言 ,误差函数越小,则表示对训练样本的拟合程度越高,因此可以将问题转换为对Loss(θ)求解极小值(极小值时误差最小),换言之,则为当θ
1
,θ
2
,θ
3
取何值时,整个系统的误差最小 。 因此需要求解Loss(Θ)的梯度,即依次对θ
1
,θ
2
,θ
3
进行求偏导数 ,如下推导公式:
Loss(θ)=
∂θ
j
∂
2
1
(f(x)−y)
2
=2×
2
1
(f(x)−y)×
∂θ
j
∂
(f(x)−y)
=(f(x)−y)×
∂θ
j
∂
(
i=0
∑
n
θ
i
x
i
−y)
=(f(x)−y)x
i
在求得偏导数之后,θ需要在当前梯度位置的反方向调整,公式如下:
θ
j
=θ
j
×η
∂θ
j
∂Loss
其中η为学习速率。 经过多次选代即可得到最优的θ
1
,θ
2
,θ
3
,即在这些参数之下,f(x)训练的样本整体误差值最小 。
梯度消失
梯度消失问题( Gradient Vanishing Problem )在神经网络层数相对较多时可能会遇到, 且随着神经网络层数的不断增加,发生的概率越明显。
对于梯度消失问题,可以通过图1进行说明。
图1 多层神经网络结构图
针对包含 n层的隐藏层的神经网络, 一般情况下第 n个隐藏层的权值还可以正常更新,但是相对于第 1 层和第 2 层的隐藏层,可能存在层的权值更新几乎不变,基本和初始的权值相差较小,这个时候则是发生了梯度消失问题 。 尤其在η较大时,发生梯度消失的概率更高,此刻第 1 层和第 2层隐藏层只是被当作了 一个映射层,并没有发挥其层次结构的价值。
归纳而言,由于在反向传播算法过程中 ,使用的是矩阵求导的链式法则,即通过一系列的连乘,且连乘的数字在每层都小于 1 ,因此梯度越来越小,最终导致梯度消失 。
从梯度消失的角度而言,可以说明并不是网络结构设计的深度越深越好,但是理论上网络结构的深度越深,表达能力和抽象能力就越强,因而对于梯度消失问题,需要从激活函数以及网络层次结构设计上着手解决,例如激活函数可以考虑用 ReLU 函数代替 Sigmoid 函数 。
与梯度消失问题相反的则是梯度爆炸( Exploding Gradient ),如果在反向传播算法过程中,连乘的数字在每层都大于 1 ,则梯度会越来越大,从而导致梯度爆炸问题的发生。梯度爆炸问题相对容易解决,可以通过简单地设置阀值来避免梯度爆炸。
编程要求
根据提示,在右侧编辑器 Begin-End 区间补充代码,计算y=(x+3)
2
+10取得极值时所对应的x的值。
测试说明
平台会对你编写的代码进行测试:
测试输入:无
预期输出:
True
提示:
利用梯度下降法求y=x
2
的函数极值,采用学习速率为 0.4, x 的计算起始位置从-3 开始,目标函数是y=x
2
,可以得到其导数为y=2x,梯度下降的迭代效果如下图2所示 。
图2 梯度下降的迭代效果示例
学习速率(lr)的初始值为0.4,迭代次数(epochs)的初始值为100,你也可以自己修改学习速率和迭代次数。
开始你的任务吧,祝你成功!
def set_learning_rate():
"""
你可以自己设定学习速率
:return: 求解过程的学习速率
"""
########## Begin ##########
lr = 0.4
########## End ##########
return lr
def set_epochs():
"""
你可以自己设定迭代次数
:return: 求解过程的迭代次数
"""
########## Begin ##########
epochs = 100
########## End ##########
return epochs
def iterate(x,lr,epochs):
"""
求解过程
:param x: 随机输入
:param lr: 学习速率
:param epochs: 迭代次数
:return: 指定函数取得极值时所对应的x的值
"""
########## Begin ##########
for _ in range(epochs):
derivative = 2 * (x+3)
x -= lr * derivative
########## End ##########
return x