从线性函数假设到非线性函数假设
线性函数存在的问题
前文中,我们通过一个线性假设函数把一个输入x∈Rn映射到不同类别的输出y∈Rk,也就是下面的线性假设函数:
hθ(x)=θTx, θ∈Rn×k
这个线性假设函数本质上是将输入线性划分为每个类别对应的区域,类似下图:

如果我们的数据不能被分成一系列线性的区域集合,该如何解决呢?

我们可以通过一个非线性的函数来分离不同的类别。
有一种想法是:提取数据更高维的特征,然后将高维特征应用于线性分类器
hθ(x)=θTϕ(x)θ∈Rd×k,ϕ:Rn→Rd
那么我们应该设计一个怎样的的特征提取函数ϕ呢?
- 通过手动提取与问题相关的特征(这是以前机器学习中常用的方法)
- 让它自己从数据中学习如何提取特征(这是目前机器学习中用的方法)
首先,我们思考一个问题,如果我们的ϕ函数还是使用线性函数行不行?
ϕ(x)=WTx
答案是不行的,其实理解起来很简单,因为一个线性函数再乘一个线性函数组合形式还是线性函数,那么提取特征和前面不提取特征的线性函数并没有本质的区别:
hθ(x)=θTϕ(x)=θTWTx=θ~x
非线性特征
我们要怎样处理可以使这个特征起作用呢?实际上只需要在线性函数上加上任意一个非线性函数即可:
ϕ(x)=σ(WTx)
其中W∈Rn×d,并且σ:Rd→Rd是任意一个非线性函数。
如果让W是一个(固定的)随机高斯样本的矩阵,让σ为cosine函数,那么这个特征就是一个 “随机傅里叶特征”(在很多问题上这个特征能取得比较好的结果)
但是我们可能想训练W参数以获得最小的损失,或者我们想将多种特征组合到一起,那我们应该怎么做呢?这就要用到神经网络了。
神经网络(或者说深度学习)
神经网络是指一种特定的假设函数,由多个参数可微的函数(又称为层layers)组合在一起形成输出。
神经网络这个术语来源于生物学,但是只要任何符合上述类型的函数都称为神经网络。
“深度网络”只是“神经网络”的同义词,而“深度学习”只是 意味着“使用神经网络假设函数的机器学习”(假设我们对深度的要求只有“非线性”的话)
但是现在的神经网络的确越来越复杂和庞大了,所以用“深度学习”这个术语也的确符合实际。
一个两层的神经网络
我们从最简单的神经网络形式开始,只是使用了前面提到的非线性特征,并且有两组可以学习权重参数。

hθ=W2Tσ(W1Tx)θ={W1∈Rn×d,W2∈Rd×k}
其中σ:R→R是对向量的每一个元素应用的非线性函数(例如:sigmoid, ReLU)
写成批量矩阵形式如下:
hθ(X)=σ(XW1)W2
全连接深度神经网络
一个更通用的L层的神经网络,又叫做多层感知机、前馈网络、全连接网络。

用批量矩阵写法如下:
Zi+1=σi(ZiWi),i=1,…,LZ1=X,hθ(X)=ZL+1[Zi∈Rm×ni,Wi∈Rni×ni+1]
非线性函数σi:R→R应用于每个向量的元素和参数θ={W1,…,WL} (也可以给假设函数加上偏置项bias)
反向传播算法
回想一下上一篇文章中提到的机器学习算法三要素,神经网络只说明了三要素中的其中之一,还需要说明:
- 损失函数:还是 cross entropy loss
- 优化器:也还是SGD
也就是说,我们要解决的优化问题还是:
θminimizem1i=1∑mℓce(hθ(x(i)),y(i))
还是可以使用SGD优化算法来求解,只不过这里的hθ(x)现在是神经网络了
需要对每一个θ计算梯度∇θℓce(hθ(x(i)),y(i))
两层神经网络的梯度计算
我们用批量矩阵的形式来写对两层神经网络求梯度的式子:
∇{W1,W2}ℓce(σ(XW1)W2,y)
我们对W2求偏导,求出来的形式类似softmax regression 的案例:
∂W2∂ℓce(σ(XW1)W2,y)=∂σ(XW1)W2∂ℓce(σ(XW1)W2,y))⋅∂W2∂σ(XW1)W2=(S−Iy)⋅σ(XW1), [S=softmax(σ(XW1)W2)]
其中(S−Iy)的维度为(m×k),而σ(XW1)的维度为(m×d) 为了使矩阵的维度匹配,最终梯度写成如下形式:
∇W2ℓce(σ(XW1)W2,y)=σ(XW1)T(S−Iy)
下面我们对W1来求偏导:
∂W1∂ℓce(σ(XW1)W2,y)=∂σ(XW1)W2∂ℓce(σ(XW1)W2,y))⋅∂σ(XW1)∂σ(XW1)W2⋅∂XW1∂σ(XW1)⋅∂W1∂XW1=(S−Iy)⋅W2⋅σ′(XW1)⋅X
同样为了使矩阵维度相匹配,我们需要调换矩阵的顺序,其中(S−Iy)的维度为(m×k),W2的维度为(d×k),σ′(XW1)的维度为(m×d),X的维度为(m×n),最终形式为:
∇W1ℓce(σ(XW1)W2,y)=XT((S−Iy)W2T ∘ σ′ (XW1))
∘ 符号代表矩阵之间各元素相乘
更泛化的反向传播算法
有没有一种更加泛化的方法求参数的偏导数,我们以全连接网络为例:
Zi+1=σi(ZiWi), i=1,…,L
然后(我们用比较简洁的符号表示):

我们通过反向迭代计算Gi:
Gi=Gi+1⋅∂Zi∂Zi+1=Gi+1⋅∂ZiWi∂σi(ZiWi)⋅∂Zi∂ZiWi=Gi+1⋅σ′(ZiWi)⋅Wi
而Zi表示正向计算的结果。
计算真正的梯度
要将这些式子转换为“真正的梯度”,我们需要考虑矩阵的维度大小
Gi=∂Zi∂ℓ(ZL+1,y)=∇Ziℓ(ZL+1,y)∈Rm×ni
所以正确的矩阵操作应该是
Gi=Gi+1⋅σ′(ZiWi)⋅Wi=(Gi+1 ∘ σ′(ZiWi))WiT
实际梯度的公式类似∇Wiℓ(ZL+1,y)∈Rni×ni+1
∂Wi∂ℓ(ZL+1,y)=Gi+1⋅∂ZiWi∂σi(ZiWi)⋅∂Wi∂ZiWi=Gi+1⋅σ′(ZiWi)⋅Zi⟹∇Wiℓ(ZL+1,y)=ZiT(Gi+1∘σ′(ZiWi))
反向传播算法:正向和反向传递
把上述正向计算和反向计算的式子放在一起,我们可以有效地计算我们需要的所有梯度,神经网络遵循以下流程:

我们可以通过下面的式子计算所有我们需要的梯度:
∇Wiℓ(Zk+1,y)=ZiT(Gi+1∘σi′(ZiWi))
"反向传播"就是使用链式法则+中间保存的结果
注意这个操作
