目录
神经网络学习笔记
基础
外文缩写
- SGD:stochastic gradient descent,随机梯度下降
常见概念
-
$l_1$ norm:1-范数,$|X|1=\sum^n{i=1}|x_i|$
-
$l_2$ norm:2-范数,$|X|2=\sqrt{\sum^n{i=1}|x_i|^2}=\sqrt{X^HX}$
-
logits:一般指 softmax 层之前的层
-
softmax:把数据归一化到 [0, 1],且和为 1,可以当作概率
softmax = tf.exp(logits) / tf.reduce_sum(tf.exp(logits), axis, keepdims=True)
-
自编码器 AutoEncoder:从输入中提取的向量与输入可以有物理关系,因此可以通过从向量还原输入,来测试效果
-
嵌入层 embedding layer:将词语等元素编码
-
显变量:能直接观测的,有对应“标准答案”的变量,即可以对齐的变量;反之为隐变量
简单的单层感知机
模型:$y_j=f(\sum_iw_ix_i-\theta_j)$,$f$ 为激活函数,$w$ 为权重,$x$ 为输入,$\theta$ 为阈值,$y$ 为输出
学习规则:$\Delta{w_i}=\eta(y-\hat{y})x_i$,$\hat{y}$ 为当前输出,$\eta$ 为学习率(一般极小)
算了,自己看西瓜书 P101 5.3 误差逆传播算法 吧
流程
输入:训练集 $D={(x_k,y_k)}^m_{k=1}$,学习率 $\eta$
过程:
- 在 (0, 1) 范围內随机初始化网络中所有连接权和阈值
- repeat
- for all $(x_k,y_k)\in{D}$ do
- 根据当前参数和 $y_j=f(\sum_iw_ix_i-\theta_j)$ 计算当前样本输出 $\hat{y}$
- 计算输出层神经元梯度项 $g_j=\hat{y}^k_j(1-\hat{y}^k_j)(y^k_j-\hat{y}^k_j)$
- 计算隐藏层神经元梯度项 $e_h=b_h(1-b_h)\sum^l_{j=1}w_{hj}g_j$
- 计算连接权增量 $\Delta{w_{hj}}=\eta{g_j}b_h$ 和 $\Delta{v_{ih}}=\eta{e_h}x_i$;以及阈值增量 $\Delta{\theta_j}=-\eta{g_j}$ 和 $\Delta{\gamma_h}=-\eta{e_h}$
- end for
- for all $(x_k,y_k)\in{D}$ do
- until 达到停止调节
输出:连接权与阈值确定的多层前馈神经网络
避免陷入局部极小
- 用多种初值训练网络,取其中误差最小的解
- 使用模拟退火,即在每一步都以一定概率接受比当前解更差的结果。这一概率会逐步减小
- 使用随机梯度下降,即在计算梯度时加入了随机因素,使得陷入局部极小时也可能获得非零梯度
- 遗传算法(什么鬼
模拟退火是 是否接收这个结果的时候加入随机,随机梯度是 计算梯度的时候选取随机的部分样本而非所有样本。随机梯度下降实际上主要用于加快计算
Loss
交叉熵:https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html?highlight=crossentropy#torch.nn.CrossEntropyLoss
- target 为下标 y 时,只和预测值 pred[y] 的值有关
常用结论
学习率 $\eta\in(0,1)$ 控制算法每轮迭代的更新步长,一般先大后小。
- 过大容易振荡
- 过小则收敛慢,容易陷入局部最优解
缓解过拟合:
- 早停:启用验证集,当训练集误差降低但测试集误差升高时停止训练
- 正则化:让误差目标函数加上一个用于描述网络复杂度的函数,例如连接权和阈值的平方和,这将使得训练更倾向于较小的连接权和阈值,让输出更光滑
- 正则化是对学习算法的修改,旨在减少泛化误差而非训练误差
两个相连的全连接层,前者的输入维度与后者的输出维度相同(即看起来好像转了一圈啥也没干),实际上起到了自编码器的作用
NLP
- 词袋模型 one-hot:有n个词,就建立 1*n 的向量,这句话里有 2 个第 i 个词,那么第 i 位就为 2
- 词向量:x*n,表示n个词分别与 x 个维度的相关性(概率),这里的维度可以理解为一种属性(譬如是男是女是不是商品),queen 这个词的 女 的维度的概率就很高。实际上维度并没有实际意义,都是深度学习自己设置的
代码相关
在写 Pytorch 的网络的 Class 时,建议同时写 __init__()
和 forward()
,这样能够连贯地完成网络结构
nn.Sequential
是简单的顺序网络架构,架构在 super().__init__()
中直接定义;nn.Module
是自由度极高的网络架构
nn.Identity
是输入层
设 i 是前一层神经元个数,j 是后一层,则权重是 i*j 个,bias 是 j 个
pytorch 中要注意常数可以直接用python的float,或者记得关闭求梯度,否则容易显存持续增长