在前篇的线性模型中
$$ \widehat y = \omega x $$
如果以神经网络的视角代入来看,则x为输入层,即input层,ω为权重,y^为输出层。在神经网络中,通常将ω以及*计算操作的部分合并看做一个神经元(层)。而神经网络的训练过程即为更新ω的过程,其更新的情况依赖于
$$ \frac{\partial loss}{\partial \omega} $$
,而并非
$$ \frac{\partial \widehat y}{\partial \omega} $$

然而,对于复杂模型而言求解过程就复杂很多。在图示的神经网络中,每个结点为一个神经元,结点之间的连线为权重。

由图上可知,输入层与隐含层第一层之间就有5∗6=30个权重,隐含层的第一层与第二层之间又有6∗7=42个权重,以此类推,上图中共有30+42+49+42+30=193个权重需要计算,传统的列表达式的方式是无法完成的。
计算图中的神经网络
在计算图中,绿色的模块为计算模块,可以在计算过程中求导。MM为矩阵乘法,ADD为加法。

而上图左式中,可以化简得到如下公式
$$ \widehat y = W_2(W_1X+b_1)+b_2=W_2W_1X+(W_2b_1+b_2)=WX+b $$
也就是说,在这个结构下单纯的增加层数,并不能增加神经网络的复杂程度,因为最后都可以化简为一个单一的神经网络。
改进方法
在每层网络结构中,增加一个非线性的变换函数(激活函数),比如sigmod函数

反向传播过程
前馈计算
在某一神经元处,输入的x与ω经过函数f(x, ω)的计算,可以获得输出值z,并继续向前以得到损失值loss.
在向前计算的过程中,在f(x, ω)的计算模块中会计算导数
$$ \frac{\partial z}{\partial x} $$
以及
$$ \frac{\partial z}{\partial \omega} $$
,并将其保存下来(在pytorch中,这样的值保存在变量x以及ω中)。

反向传播
由求导的链式法则,求得loss以后,前面的神经元会将
$$ \frac{\partial loss}{\partial z} $$
的值反向传播给原先的神经元,在计算单元f(x, ω)中,将得到的
$$ \frac{\partial loss}{\partial x} $$
与之前存储的导数相乘,即可得到损失值对于权重以及输入层的导数,即
$$ \frac{\partial loss}{\partial x} $$
,以及
$$ \frac{\partial loss}{\partial \omega} $$
,基于该梯度才进行权重的调整。

Pytorch中的前馈与反馈
利用pytorch进行深度学习,最主要的是==构建计算图==
Tensor 张量
Tensor中重要的两个成员,data用于保存权重本身的值ω,grad用于保存损失函数对权重的导数
$$ \frac{\partial loss}{\partial \omega} $$
,grad本身也是个张量。对张量进行的计算操作,都是建立计算图的过程。

```python import torch
x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0]
赋予tensor中的data
w = torch.Tensor([1.0])
设定需要计算梯度grad
w.requires_grad = True
模型y=x*w 建立计算图
def forward(x): ''' w为Tensor类型 x强制转换为Tensor类型 通过这样的方式建立计算图 ''' return x * w
def loss(x, y): y_pred = forward(x) return (y_pred - y) ** 2
print ("predict (before training)", 4, forward(4).item())
for epoch in range(100): for x,y in zip(x_data,y_data): #创建新的计算图 l = loss(x,y) #进行反馈计算,此时才开始求梯度,此后计算图进行释放 l.backward() #grad.item()取grad中的值变成标量 print('\tgrad:',x, y, w.grad.item()) #单纯的数值计算要利用data,而不能用张量,否则会在内部创建新的计算图 w.data = w.data - 0.01 * w.grad.data #把权重梯度里的数据清零 w.grad.data.zero_() print("progress:",epoch, l.item())
print("predict (after training)", 4, forward(4).item()) ```
本文参考自B站《PyTorch深度学习实践》P4