下图为一个简单的单层感知机模型
左侧为输入层,对于所有输入 $x$,上标 0 表示第 0 层(即输入层),下标 0~N 表示有 N+1 个元素。对于中间的权重 $w_{ij}$,$i$ 表示上一层的节点编号,$j$ 表示下一层的节点编号。后面紧跟着的分别是求和 $\sum$,以及 $\sigma$ 函数。后面的 E 代表 Error 或者 Loss,将输出值与 t (target) 进行对比
接下来我们推导一下单层感知机梯度公式
首先我们定义 $E (Loss)=\frac {1}{2}(O_0^1-t)^2$,这里额外的 $\frac {1}{2}$ 是为了方便抵消掉求导后的参数 2,该值的设立不会改变结果的单调性,所以有没有都无所谓,但是为了方便,这里还是加上了
$$ \begin{align*} \frac{\nabla E}{\nabla{w_{j0}}} &= (O^1_0 - t)\frac{\nabla O^1_0}{\nabla w_{j0}} \\ &= (O^1_0 - t)\frac{\nabla \sigma(x^1_0)}{\nabla w_{j0}} \end{align*} $$
因为 $\frac {\nabla \sigma (x)}{\nabla x} = \sigma * (1-\sigma)\frac {\nabla x}{\nabla x}$
所以
$$ \begin{align*} (O^1_0 - t)\frac{\nabla \sigma(x^1_0)}{\nabla W_{j0}} &= (O^1_0 - t) \sigma(x^1_0)(1-\sigma(x^1_0))\frac{x^1_0}{w_{j0}} \\ &= (O^1_0 - t) O^1_0(1-\sigma(x^1_0))\frac{\nabla \sum_i w_{i0}x^0_i}{w_{j0}} \\ &= (O^1_0 - t) O^1_0(1-O^1_0)x^0_j \end{align*} $$
因此,$\frac {\nabla E}{\nabla w_{j0}} = (O^1_0 - t) O^1_0 (1-O^1_0) x^0_j$
由该结果可看出,$Loss$ 关于权重 $w$ 的梯度仅与输出节点 $O^1_0$ 和输入节点的 $x$ 有关
- import torch
- import torch.nn.functional as F
- x = torch.randn(1, 10) # dim=2,len=10, x为[1,10]的tensor
- w = torch.randn(1, 10, requires_grad=True) # w为[1,10]的tensor
- o = torch.sigmoid(x@w.t()) # o为[1,1]的tensor
- # [1,10]*[1,10]T => [1,10]*[10,1] => [1,1]
-
- print("o:",o)
-
- loss = F.mse_loss(input=o, target=torch.ones(1, 1))
- # 将shapa为[1,1]的计算结果与全为1的[1,1]矩阵进行mse计算
-
- print('loss:', loss)
- print('loss shape:', loss.shape) # 得到的loss为标量
-
- loss.backward()
- print('w.grad:', w.grad)