人工神经网络学习笔记

前记

博主距离上次正式发 blog 已经过 114514 年了。进入大学后关于 OI 方面接触就少了。OI 的姿势越来越不会,导致我 NOI2022 题解鸽到现在

关于为什么想发这篇 blog,更多的还是对这方面的了解甚少,想通过写写文的方式寻找与其相关的灵感。

学习这套理论,源自其中的一个 project 的 AI 设计(任何算法,哪怕暴力都可)。博主想把握好这个机会学习些关于现代搜索和 AI 方面的理论,当然,人工神经网络只是辅助该 AI 实现的一个工具。

本文大多是一些摘记,从多处拼接而来,可能存在不严谨的地方,毕竟是无师自学,寻找相关资料已是不易之事。如有错误之处,望能不吝赐教。

1.模型

根据名称,不难得知人工神经网络源于生物学的神经网络。人的大脑由众多神经元组成,单个神经元的模式图如下:

根据生物学研究,树突和轴突大致可以理解成对该神经元的输入和输出,于是计算机科学家对其进行简化,将神经元看成一个节点,又叫 单一神经元,于是得到:

其中 \(x\) 称为 输入\(w\) 被称为 权重\(b\) 成为 偏移项,作用是对其进行一次水平的调整。\(z\) 是一个运算中间值,\(o\) 是将 \(z\) 通过一个 激活函数 \(f\) 得到,称为 输出值。简单来说,公式为 \(o=f(z)=f(wx+b)\)

如果 \(\boldsymbol x\in\R^{n\times 1}\),相应地,\(\boldsymbol w\in\R^{n\times 1}\),那么得到 \(o=f(\boldsymbol w^T\boldsymbol x+b)\)

下面来说说激活函数 \(f\)。常见的有以下几类:

  1. Sigmoid \(\sigma\):取值 0 到 1,表达式为 \(f(x)=\frac1{1+e^{-x}}\),以及 \(f'(x)=f(x)(1-f(x))\)
  2. 正切函数 Tanh:\(f(x)=\tanh x\)。取值 -1 到 +1 ,平均值为 0,当 \(x\rightarrow 0\) 时,\(f'(x)\rightarrow 1\)
  3. 高斯函数:\(f(x)=\exp(-\frac{x^2}{\sigma^2})\)
  4. ReLU 函数:\(f(x)=\max\{0,x\}\)。听说很强大,能避免幂运算和梯度消失。

2.BPNN(反向传播神经网络)

多个神经元形成多层,且每层若干神经元,它们相互交叉连接,就能构成神经网络。前一层神经元作为后一层的输入,最后一层直接给出整个网络的输出,称为 输出层,输出层之前的层称为 隐含层。当一个神经网络有一层以上的隐藏层,称其为深度学习网络。定义神经元的层数为隐含层数 + 输出层。

假设输入层是一个 \(n\) 维向量,记成 \(\boldsymbol x\),输出层为 \(m\) 维向量,记成 \(\boldsymbol y\),假设一个三层神经网络,各层的 权重矩阵偏移向量入参向量出参向量 分别为:

\[\boldsymbol w^{(i)}= \left[ \begin{matrix} w_{11}^{(i)}&w_{12}^{(i)}&\cdots&w_{1n}^{(i)}\\ w_{21}^{(i)}&w_{22}^{(i)}&\cdots&w_{2n}^{(i)}\\ \vdots&\vdots&\ddots&\vdots\\ w_{m1}^{(i)}&w_{m2}^{(i)}&\cdots&w_{mn}^{(i)}\\ \end{matrix} \right] \]

\[\boldsymbol b^{(i)}= \left[ \begin{matrix} b_1^{(i)}\\ b_2^{(i)}\\ \vdots\\ b_m^{(i)}\\ \end{matrix} \right] \]

\[\boldsymbol z^{(i)}= \left[ \begin{matrix} z_1^{(i)}\\ z_2^{(i)}\\ \vdots\\ z_m^{(i)}\\ \end{matrix} \right] \]

\[\boldsymbol o^{(i)}= \left[ \begin{matrix} o_1^{(i)}\\ o_2^{(i)}\\ \vdots\\ o_m^{(i)}\\ \end{matrix} \right] \]

其中 \(w_{jk}^{(i)}\) 表示第 \(i\) 层神经元第 \(k\) 个输入源传达到第 \(j\) 个神经元的强度权重,\(b^{(i)}_j\) 表示第 \(i\) 层第 \(j\) 个神经元的输入偏移量,\(z_j^{(i)}\) 表示第 \(i\) 层第 \(j\) 个神经元的激活函数入参,\(o_j^{(i)}\) 表示第 \(i\) 层第 \(j\) 个神经元的输出。同时,我们有 \(\boldsymbol y=\boldsymbol o^{(3)}\)

根据以上定义,我们不难得出运算:

\[\boldsymbol z^{(1)}=\boldsymbol w^{(1)}\boldsymbol x+\boldsymbol b^{(1)},\boldsymbol o^{(1)}=f(\boldsymbol z^{(1)}) \]

\[\boldsymbol z^{(2)}=\boldsymbol w^{(2)}\boldsymbol x+\boldsymbol b^{(2)},\boldsymbol o^{(2)}=f(\boldsymbol z^{(2)}) \]

\[\boldsymbol z^{(3)}=\boldsymbol w^{(3)}\boldsymbol x+\boldsymbol b^{(3)},\boldsymbol o^{(3)}=f(\boldsymbol z^{(3)}) \]

现在我们来讨论训练模型。假设有一种模型,满足若干组要求:对于参数 \(\{\boldsymbol x_1,\cdots,\boldsymbol x_t\}\),以及结果 \(\{\boldsymbol y_1,\cdots,\boldsymbol y_t\}\),我们肯定希望通过该神经网络,能够得到 \(\boldsymbol y_i=\text{BPNN}(\boldsymbol x_i)\),并且随着参数集的推广仍然具有很好的预测作用。事实上,我们很难直接获得如此完美的情况,为了评估训练效果,我们定义 代价函数 \(J=\frac1t\sum\limits_{i=1}^tL_i\),其中 \(L_i\) 表示第 \(i\) 个样本的 训练误差,为了方便计算,定义为 \(\frac12||\boldsymbol y-\boldsymbol y_i||^2\),其中 \(\boldsymbol y\) 表示 \(\text{BPNN}\) 给的输出值。

训练的目的是最小化 \(J\),也就是要找到 \(J\) 的梯度 \(\nabla J\),即 \(\frac1t\sum\limits_{i=1}^t\nabla L_i\)。所以我们来讨论 \(\nabla L\)

我们来寻找 \(\boldsymbol w\)\(\boldsymbol b\)\(L\) 的关系,也就是求 偏导 \(\dfrac{\partial L}{\partial\boldsymbol w}\)\(\dfrac{\partial L}{\partial\boldsymbol b}\)。我们仍然假设其为 3 层神经网络,不妨先来看看 \(\boldsymbol w^{(1)}\)

\[\frac{\partial L}{\partial\boldsymbol w^{(1)}}= \left[ \begin{matrix} \frac{\partial L}{\partial w_{11}^{(1)}}&\frac{\partial L}{\partial w_{12}^{(1)}}&\cdots&\frac{\partial L}{\partial w_{1n}^{(1)}}\\ \frac{\partial L}{\partial w_{21}^{(1)}}&\frac{\partial L}{\partial w_{22}^{(1)}}&\cdots&\frac{\partial L}{\partial w_{2n}^{(1)}}\\ \vdots&\vdots&\ddots&\vdots\\ \frac{\partial L}{\partial w_{m1}^{(1)}}&\frac{\partial L}{\partial w_{m2}^{(1)}}&\cdots&\frac{\partial L}{\partial w_{mn}^{(1)}}\\ \end{matrix} \right] \]

下面考察 \(\dfrac{\partial L}{\partial w_{ij}^{(1)}}\)

\[\frac{\partial L}{\partial w_{ij}^{(1)}}=\frac{\partial L}{\partial z_i^{(1)}}\frac{\partial z_i^{(1)}}{\partial w_{ij}^{(1)}}=\frac{\partial L}{\partial z_i^{(1)}}x_j \]

所以得到

\[\frac{\partial L}{\partial\boldsymbol w^{(1)}}= \left[ \begin{matrix} \frac{\partial L}{\partial z_1^{(1)}}\\ \frac{\partial L}{\partial z_2^{(1)}}\\ \vdots\\ \frac{\partial L}{\partial z_m^{(1)}}\\ \end{matrix} \right] \times \boldsymbol x^T \]

我们把右式左边的列向量记为 \(\boldsymbol\delta^{(1)}\),那么:

\[\frac{\partial L}{\partial\boldsymbol w^{(1)}}=\boldsymbol\delta^{(1)}\boldsymbol x^T \]

同理:

\[\frac{\partial L}{\partial\boldsymbol w^{(2)}}=\boldsymbol\delta^{(2)}\left(\boldsymbol o^{(1)}\right)^T \]

\[\frac{\partial L}{\partial\boldsymbol w^{(3)}}=\boldsymbol\delta^{(3)}\left(\boldsymbol o^{(2)}\right)^T \]

再来考察 \(\boldsymbol b^{(1)}\)

\[\frac{\partial L}{\partial\boldsymbol b^{(1)}}= \left[ \begin{matrix} \frac{\partial L}{\partial b_1^{(1)}}\\ \frac{\partial L}{\partial b_2^{(1)}}\\ \vdots\\ \frac{\partial L}{\partial b_m^{(1)}}\\ \end{matrix} \right] \]

同样地:

\[\frac{\partial L}{\partial b_i^{(1)}}=\frac{\partial L}{\partial z_i^{(1)}}\frac{\partial z_i^{(1)}}{\partial b_i^{(1)}}=\frac{\partial L}{\partial z_i^{(1)}} \]

所以得到:

\[\frac{\partial L}{\partial\boldsymbol b^{(1)}}= \left[ \begin{matrix} \frac{\partial L}{\partial z_1^{(1)}}\\ \frac{\partial L}{\partial z_2^{(1)}}\\ \vdots\\ \frac{\partial L}{\partial z_m^{(1)}}\\ \end{matrix} \right] =\boldsymbol\delta^{(1)} \]

同理

\[\frac{\partial L}{\partial\boldsymbol b^{(2)}}=\boldsymbol\delta^{(2)} \]

\[\frac{\partial L}{\partial\boldsymbol b^{(3)}}=\boldsymbol\delta^{(3)} \]

对于训练样本 \(L\leftarrow\{\boldsymbol w_1,\boldsymbol w_2,\boldsymbol w_3,\boldsymbol b_1,\boldsymbol b_2,\boldsymbol b_3\}\),得到 \(\nabla L\leftarrow\{\boldsymbol\delta^{(1)}\boldsymbol x^T,\boldsymbol\delta^{(2)}\left(\boldsymbol o^{(1)}\right)^T,\boldsymbol\delta^{(3)}\left(\boldsymbol o^{(2)}\right)^T,\boldsymbol\delta^{(1)},\boldsymbol\delta^{(2)},\boldsymbol\delta^{(3)}\}\)

最后一点,如何求 \(\boldsymbol\delta\)?我们先来看 \(\boldsymbol\delta^{(1)}\),注意到

\[\frac{\partial L}{\partial z_i^{(1)}}=\frac{\partial L}{\partial o_i^{(1)}}\frac{\partial o_i^{(1)}}{\partial z_i^{(1)}}=f'(z_i^{(1)})\frac{\partial L}{\partial o_i^{(1)}}=f'(z_i^{(1)})\sum_{j=1}^m\frac{\partial L}{\partial z_j^{(2)}}\frac{\partial z_j^{(2)}}{\partial o_i^{(1)}}=f'(z_i^{(1)})\sum_{j=1}^m\frac{\partial L}{\partial z_j^{(2)}}w_{ji}^{(2)} \]

所以有:

\[\frac{\partial L}{\partial z_i^{(1)}}=f'(z_i^{(1)}) \left[ \begin{matrix} w_{1i}^{(2)}&w_{2i}^{(2)}&\cdots&w_{m'i}^{(2)} \end{matrix} \right] \left[ \begin{matrix} \frac{\partial L}{\partial z_1^{(2)}}\\ \frac{\partial L}{\partial z_2^{(2)}}\\ \vdots\\ \frac{\partial L}{\partial z_{m'}^{(2)}} \end{matrix} \right] \]

\[\boldsymbol\delta^{(1)}= \left[ \begin{matrix} \frac{\partial L}{\partial z_1^{(1)}}\\ \frac{\partial L}{\partial z_2^{(1)}}\\ \vdots\\ \frac{\partial L}{\partial z_m^{(1)}}\\ \end{matrix} \right]= \left[ \begin{matrix} f'(z_1^{(1)})&&&\\ &f'(z_2^{(1)})&&\\ &&\ddots&\\ &&&f'(z_m^{(1)})\\ \end{matrix} \right] \left[ \begin{matrix} w_{11}^{(2)}&w_{21}^{(2)}&\cdots&w_{m'1}^{(2)}\\ w_{12}^{(2)}&w_{22}^{(2)}&\cdots&w_{m'2}^{(2)}\\ \vdots&\vdots&\ddots&\vdots\\ w_{1m}^{(2)}&w_{2m}^{(2)}&\cdots&w_{m'm}^{(2)} \end{matrix} \right] \left[ \begin{matrix} \frac{\partial L}{\partial z_1^{(2)}}\\ \frac{\partial L}{\partial z_2^{(2)}}\\ \vdots\\ \frac{\partial L}{\partial z_{m'}^{(2)}} \end{matrix} \right] \]

简单来写就是:\(\boldsymbol\delta^{(1)}=\text{Diag}\left(f'(\boldsymbol z^{(1)})\right)\left(\boldsymbol w^{(2)}\right)^T\boldsymbol\delta^{(2)}\);同样地,\(\boldsymbol\delta^{(2)}=\text{Diag}\left(f'(\boldsymbol z^{(2)})\right)\left(\boldsymbol w^{(3)}\right)^T\boldsymbol\delta^{(3)}\)。当然,边界 \(\boldsymbol\delta^{(3)}\) 是要单独考虑的。

考虑 \(\dfrac{\partial L}{\partial z_i^{(3)}}\)

\[\dfrac{\partial L}{\partial z_i^{(3)}}=\dfrac{\partial L}{\partial o_i^{(3)}}\dfrac{\partial o_i^{(3)}}{\partial z_i^{(3)}}=f'(z_i^{(3)})\dfrac{\partial L}{\partial y_i}=f'(z_i^{(3)})\dfrac{\partial\left(\dfrac12||\boldsymbol y-\boldsymbol{\hat y}||^2\right)}{\partial y_i}=f'(z_i^{(3)})(y_i-\hat{y_i}) \]

所以得到

\[\boldsymbol\delta^{(3)}= \left[ \begin{matrix} \frac{\partial L}{\partial z_1^{(3)}}\\ \frac{\partial L}{\partial z_2^{(3)}}\\ \vdots\\ \frac{\partial L}{\partial z_m^{(3)}}\\ \end{matrix} \right]= \text{Diag}\left(f'(\boldsymbol z^{(3)})\right)(\boldsymbol y-\boldsymbol{\hat y}) \]

至此,推导结束。

将所有的 \(\nabla L\) 求加权平均,选取一个合适的调整系数 \(\lambda\),根据梯度反向调整即可(这样 \(J\rightarrow 0\))。也就是 梯度下降

训练的时候,有三种梯度下降的方法:

批量梯度下降(Batch Gradient Descent,BGD):即每次训练迭代时,使用当前训练样本集合的全集来计算代价函数梯度。

随机梯度下降(Stochastic Gradient Descent,SGD):即每次训练迭代时,仅使用当前训练样本集合中的一个随机样本来计算代价函数梯度。

小批量梯度下降(Mini-Batch Gradient Descent, MBGD):即每次训练迭代时,使用当前训练样本集合中的一个随机子集样本来计算代价函数梯度。此训练方案是上述两种方案的折中,一般效果最好。

3.GRNN

有空再学(未完待续)

posted @ 2022-12-13 04:16  AC-Evil  阅读(146)  评论(1编辑  收藏  举报