第7讲 深度学习(四)
一、人类记忆机制的启发
1.1 记忆机制
记忆是在头脑中积累和保存个体经验的心理过程。用信息加工的术语说,记忆是人脑对外界输入信息进行编码、存储和提取的过程,也是一种主动的信息处理机制:人会把输入编码为大脑可以接受的形式,对外界信息有所选择;新信息只有以某种形式汇入已有知识结构,才便于记忆;信息能否提取,又与编码程度和信息的组织结构密切相关。
不同脑区与不同记忆过程有关:前额叶参与短时记忆;额叶参与语义记忆和情节记忆;颞叶参与长时语义、情节记忆的整合与存储,也参与短时记忆中新材料的加工;海马整合新的长时语义和情节记忆;杏仁核整合新的情绪记忆信息;皮层运动区和小脑与程序性记忆有关。
1.2 记忆系统及其加工过程
记忆是由感觉记忆、短时记忆和长时记忆组成的结构性信息加工系统。它包含三个基本过程:编码,即把外界信息转换形式;存储,即把编码结果以一定形式保留在大脑中;提取,即从记忆中查找已有信息,包括再认和回忆。
感觉记忆也称瞬时记忆,信息只保存毫秒或数秒。心理学家假设每种感觉通道都有自己的感觉记忆,能在进一步加工前短暂登记刺激物理特征的精确表征。Sperling 于 1960 年用全部报告法研究图像记忆:向被试呈现一张含 9 个字母的卡片 50 ms,卡片内容为 C F X / P L A / N T S,要求立即报告全部字母,结果一般只能报告 4~5 个。
感觉记忆有如下特点:图像记忆持续几百毫秒,声像记忆最长可达 4 s;加工只是初步的,但可以进行信息整合;编码基本依照刺激的物理特征,是外界刺激的真实复本;容量较大,图像记忆约容纳 9~20 个项目,声像记忆容量小于图像记忆,但只有一部分信息会进入短时记忆;整个过程无意识、自动化,不能由人主动控制。
短时记忆的保持时间在 1 min 以内,通常约 15~30 s,因此也称“电话号码式记忆”。它负责对刺激信息进行加工、编码和短暂保持,容量有限。课件给出的测试要求在 1 min 内读完任选的一行 12 组两位数,平均每 5 s 一组,随后写出记住的组,组内位置允许颠倒:
73 49 64 83 41 27 62 29 38 93 74 9757 29 32 47 94 86 14 67 75 28 49 3536 45 73 29 87 28 43 62 75 59 93 67
短时记忆一般可同时容纳 5~9 组内容。正确记住 12 组为“特优”,8~9 组为“优”,4~7 组为“一般”,少于 4 组则有待改进。其容量通常概括为 \(7\pm2\) 个组块,组块可以是词或习惯用语;从短时记忆向长时记忆存入一项内容约需 5~10 s。记忆的组织呈等级结构,类似计算机内存与外存的组织。
短时记忆编码是把信息转换成适合记忆系统的形式,编码后的具体信息形式称为代码(code)。短时记忆内容在 15~30 s 内会随时间逐渐减少,受干扰作业难度和材料熟悉程度影响。痕迹衰退说认为记忆痕迹随时间消退,干扰说则认为遗忘来自已有信息的干扰。
长时记忆指信息保持 1 min 以上,可以持续数年乃至终生。其变化不只有量的减少:存储数量会随时间下降;在知识与经验影响下,内容本身也可能发生质的变化,出现记忆扭曲和记忆错觉。
三种子系统按时间相连:容量不小于 9、仅保持数秒的感觉记忆,经注意进入容量为 \(7\pm2\) 组块、保持不超过 1 min 的短时记忆;短时内容经复述进入容量巨大的长时记忆,长时内容又可提取回短时记忆。感觉和短时阶段都可能发生遗忘。
二、循环神经网络
2.1 序列建模问题
媒体数据中的序列任务包括手写文字识别、语音识别、视频分析、机器翻译等自然语言处理任务,以及基因识别等生物信息计算。按输入与输出的对应形式,可以有多对多、多对一和一对多等关系:图像分类是图像特征到类别,视频帧分类是视频帧序列到类别序列或类别,图像描述是图像到句子,文本分类是文档到类别,机器翻译是句子到句子。
深度学习序列建模方法包括 RNN 配合 CTC 解码、RNN Encoder-Decoder,以及基于自注意力的 Transformer Encoder-Decoder。RNN 的发展脉络包括 1982 年 Hopfield nets、1986 年 Jordan Network、1990 年 Elman Network 与 BPTT、1997 年 LSTM、双向 RNN、2014 年 GRU、2015 年 Stack RNN 与 Neural Turing Machine。早期核心思想是重新利用信息,1990—2010 年间 LSTM 引入门控机制,2010 年以后 RNN 广泛用于语音、手写识别、自然语言处理和视频分析,并由 PyTorch、TensorFlow、MxNet、Caffe 等工具支持。
2.2 传统循环神经网络与 BPTT
反馈通过让输出影响输入来改善系统运行和控制效果。电子电路把一部分或全部输出电压、电流经一定电路形式作用到输入回路;生物神经网络中也存在后一个神经元的反馈支路作用于前一个神经元的结构。前馈网络的计算图是有向无环图,隐层可写为 \(h=f(Wx)\);循环网络引入带时延的反馈环路:
Elman 网络把上一时刻隐状态反馈到当前隐层,Jordan 网络则把上一时刻网络输出反馈到隐层。传统 RNN 的参数为 \(W,U,V\),计算为
\(x_t\) 是时刻 \(t\) 的输入,\(h_t\) 由 \(x_t\) 和 \(h_{t-1}\) 共同决定,\(y_t\) 由当前 \(h_t\) 决定,因而间接受 \(x_t,h_{t-1}\) 影响。常用隐层激活是双曲正切:
Softmax 第 \(k\) 维及其导数为
其中 \(j=k\) 时 \(\delta_{kj}=1\),否则为 0。
时序分类中,\(y_t\) 的第 \(k\) 维是属于第 \(k\) 类的概率。若时刻 \(t\) 的真值类别序号 \(g_t=i\),交叉熵为
整个序列的损失为
RNN 沿时间展开后共享参数:
初始隐状态 \(h_0\) 一般设为 0。前向计算按 \(x_1,x_2,\ldots,x_T\) 依次更新隐状态与输出。
误差随时间反向传播(back-propagation through time, BPTT)与普通 BP 都用链式法则求损失对权重的偏导,再按梯度下降更新,直到收敛或达到预设迭代次数;区别是 BPTT 必须处理时间展开后的权值共享。以 \(U_t=U\) 为例,把 \(L\) 看成具有 \(T\) 个中间变量的函数,有
远距离梯度需连续相乘:
若各步 \(|\partial h_{i+1}/\partial h_i|<1\),连乘后常出现梯度消失;若大于 1,则可能梯度爆炸,后者可用梯度截断缓解。前馈网络也会有梯度消失,尤其使用 Sigmoid 时;课件指出前馈网络各层权值矩阵不同,因而没有 RNN 这种权值反复相乘所致的梯度爆炸。循环网络的解决思路是在反馈回路中引入门控机制。
2.3 LSTM 与 GRU
门用 Sigmoid 输出控制数据流动,一般形式为
门控能缓解梯度消失,并帮助学习长距离上下文。Hochreiter 等人在 1997 年提出长短时记忆单元 LSTM,引入输入门、遗忘门和输出门控制输入、记忆与输出通道,并用 cell 保存信息:
其中 \(\sigma\) 为 Sigmoid,\(\phi\) 为 Tanh,\(\odot\) 表示张量对应元素相乘。遗忘门关闭可阻断旧记忆,输出门关闭可阻断 cell 向外输出,输入门打开则允许新候选信息进入。参数仍通过把这些复合运算沿时间展开后应用链式法则求导。
Cho 等人在 2014 年提出 GRU。它比 LSTM 精简,只保留更新门 \(z_t\) 和重置门 \(r_t\):
2.4 双向 RNN 与 CTC
普通 RNN、LSTM 或 GRU 单元都可取代神经元;同类单元组成一层,多层再堆叠为网络。双向 RNN 把输入序列按时间正向和反向分别送入两个循环层,再把两层在对应时刻的输出拼接,因而同时利用前后文。
语音识别、手写文本识别等时序分类任务同时面对三个问题:输入 \(X=[x_1,\ldots,x_T]\) 与输出 \(Y=[y_1,\ldots,y_L]\) 的长度都不固定;二者长度比例不固定;训练数据没有输入帧与输出字符间的精确对齐,例如不知道哪段语音波形对应字符 j。
CTC(Connectionist Temporal Classification)为给定 \(X\) 建模所有可能输出序列 \(Y\) 的分布,可输出概率最大的序列,也可计算指定序列的概率。它在字符集之外增加空白符号 blank(记作 -),用来处理输入输出对齐以及连续出现的相同类别。
模型逐帧预测的符号串称为解码路径,多条路径可映射到同一输出。例如 -R-O-O-M- 和 RRO--OOM- 都可对应 ROOM。解码先合并相邻重复字符,如 RRO-OOM- 变为 RO-OM-,再删去空白符,得到 ROOM。注意只有相邻重复先合并,空白可将两个相同字符隔开。训练时最大化所有解码后恰为真值序列的路径概率之和。
完整 CTC 流程为:输入 \(X=[x_1,\ldots,x_T]\) 经过 RNN 等神经网络,得到逐帧概率分布 \(P=[p_1,\ldots,p_T]\);若字符集合为 \(C\),则 \(p_t\in\mathbb R^{|C|+1}\),额外一维对应 blank,\(p_{tk}\) 是第 \(t\) 帧属于类别 \(k\) 的概率;最后合并重复字符、删除 blank,或者使用 beam search,输出 \(Y=[y_1,\ldots,y_L]\)。
BiLSTM+CTC 连写文字识别案例的流水线是:图像归一化、二值化;用滑动窗把图像变成序列;双向 LSTM 建模;Dropout 防止过拟合;Softmax 逐帧分类;CTC 解码。手写阿拉伯文训练集含 26,459 幅图像,训练 51 轮,第 1 轮 batch size 为 1,后 50 轮为 50。不同层数结果如下:
| 层数 | 各层 LSTM 单元数 | 测试集字符错误率 |
|---|---|---|
| 1 | 50 | 33.01% |
| 2 | 50, 100 | 21.89% |
| 3 | 50, 100, 200 | 17.87% |
| 4 | 50, 100, 200, 200 | 14.48% |
| 5 | 50, 100, 200, 200, 200 | 14.70% |
| 6 | 50, 100, 200, 200, 200, 200 | 20.87% |
四层模型在该实验中最低,继续加深并未继续改善。
PyTorch 提供 LSTMCell、LSTM、GRUCell、GRU、RNNCell 和 RNN。以 torch.nn.RNN(input_size, hidden_size, num_layers=1, nonlinearity='tanh', bias=True, batch_first=False, dropout=0.0, bidirectional=False, ...) 为例:input_size 是输入特征数,hidden_size 是隐状态特征数,num_layers 指堆叠层数,激活可为 Tanh 或 ReLU;bias=False 时不使用输入—隐层和隐层—隐层偏置;batch_first=True 令输入输出采用 (batch, seq, feature);非零 dropout 作用于除最后一层外各层输出;bidirectional=True 构成双向 RNN。
课件第 45 页列出的完整构造签名为:
torch.nn.LSTMCell(input_size, hidden_size, bias=True, device=None, dtype=None)
torch.nn.LSTM(input_size, hidden_size, num_layers=1, bias=True, batch_first=False, dropout=0.0, bidirectional=False, proj_size=0, device=None, dtype=None)
torch.nn.GRUCell(input_size, hidden_size, bias=True, device=None, dtype=None)
torch.nn.GRU(input_size, hidden_size, num_layers=1, bias=True, batch_first=False, dropout=0.0, bidirectional=False, device=None, dtype=None)
torch.nn.RNNCell(input_size, hidden_size, bias=True, nonlinearity='tanh', device=None, dtype=None)
torch.nn.RNN(input_size, hidden_size, num_layers=1, nonlinearity='tanh', bias=True, batch_first=False, dropout=0.0, bidirectional=False, device=None, dtype=None)
其中 LSTM 的 proj_size=0 表示默认不使用投影层。
记序列长度为 \(L\)、batch 大小为 \(N\)、输入维数为 \(H_{in}\)、输出隐状态维数为 \(H_{out}\),方向数为 \(D\)。无 batch 时输入形状为 \((L,H_{in})\);batch_first=False 时为 \((L,N,H_{in})\),为真时为 \((N,L,H_{in})\)。初始隐状态 hx 的形状无 batch 时为 \((D\cdot\text{num_layers},H_{out})\),有 batch 时为 \((D\cdot\text{num_layers},N,H_{out})\)。输出 output 无 batch 时为 \((L,DH_{out})\),其余两种分别为 \((L,N,DH_{out})\) 和 \((N,L,DH_{out})\);最终隐状态 h_n 与 hx 形状相同。
2.5 基于 RNN 的语言模型
词是能独立使用的最小音义结合体。中文词之间没有天然分隔符,分词(tokenization 或 word segmentation)要把文本切成 token 序列,且可能有歧义,例如“南京市长江大桥”既可切成“南京市/长江大桥”,也可切成“南京市长/江大桥”。
传统 one-hot 词表示高维、离散、稀疏,不能表示语义相似性。改进办法包括增加词性等额外特征,利用 WordNet、HowNet 等语义词典的上位信息,但要处理一词多义、词表不全和更新慢;还可采用 Brown Clustering,把语料中的词组织成聚类二叉树。
基于语料库的自监督预训练包括:Word2vec 用一层线性变换等神经网络把 one-hot 变成分布式词向量,即词嵌入;ELMo 用语言模型产生动态词向量;更大规模的预训练模型包括单向语言模型 GPT 和双向语言模型 BERT。它们依据分布语义假设:一个词的含义可以由上下文词的分布表示。课件用 moon 在 shinning, bright, trees, dark, look 上的共现计数 38, 45, 2, 27, 12 示意分布向量,再用向量相似度比较 moon、star 与 cucumber。普通语料预训练得到的通常是静态词向量,使用时不随上下文改变。
语言模型描述一段自然语言的概率,或给定上文时下一个词的条件概率:
两种定义由概率链式法则联系。语言模型能在机器翻译中给出 \(P(\text{the cat is small})>P(\text{small the is cat})\),也能在语音识别中给出 \(P(\text{there are four cats})>P(\text{there are for cats})\)。
前馈神经网络语言模型 FF-NNLM 根据前 \(n-1\) 个词预测当前词,即采用马尔可夫假设;通过查找表取得词嵌入,再用前馈网络预测。缺点是历史长度固定,无法灵活处理“他 喜欢 吃 苹果”和“他 感冒 了,于是 下班 后 去 了 医院”这样长短不同的上下文。
Word2vec 有两种架构:CBOW 把周围词向量求平均,用上下文预测中间词;Skip-Gram 用中间词分别预测周围词。词和上下文使用不同参数矩阵,目标词经 Softmax 预测并优化分类损失。大词表下完整归一化效率低,因此可用负采样:把“词—上下文”是否共现变成二分类,真实共现为 1,通过人为替换词构造不共现的负例 0。词向量既可作为文本分类等下游任务的输入,也可在下游训练中继续精调,并支持词类比计算。
ELMo 是动态词表示方法。它先在维基百科等大规模文本上无监督预训练,再用目标任务数据微调。ELMo 基于双向 LSTM,不只取最后一层,而把所有层输出线性组合为词表示;一个含 \(L\) 层的双向语言模型对每个词产生 \(2L+1\) 个表示。
课件的简化 PyTorch 实现使用 torch、Dataset/DataLoader、Counter 和 jieba。jieba 有精确、全模式和搜索引擎三种主要模式;对“我来到北京清华大学”,结果分别为“我/来到/北京/清华大学”,“我/来到/北京/清华/清华大学/华大/大学”和“我/来到/北京/清华/华大/大学/清华大学”。数据准备过程用 jieba.cut 分词,以 Counter.most_common() 建立词到序号的词表,并由 TextDataset 返回词及其编号。
示例模型包含 nn.Embedding(vocab_size, embedding_size)、nn.LSTM(embedding_size, hidden_size, num_layers, bidirectional=True) 和 nn.Linear(2*hidden_size, vocab_size);预测时将句子分词、转编号、增加 batch 维,经模型后取 argmax。输入语料为“我在学习自然语言处理,自然语言处理是人工智能的核心技术。”,设置 embedding_dim=100、hidden_dim=128、num_layers=2、batch size 为 2;用交叉熵、Adam(学习率 0.001)训练 20 轮。得到词表 {'自然语言':0,'处理':1,'我':2,'在':3,'学习':4,',':5,'是':6,'人工智能':7,'的':8,'核心技术':9,'。':10}。对“我 在 学习 核心技术”,示例输出为 ['自然语言','处理','学习','人工智能']。
2.6 RNN Encoder-Decoder 与注意力
机器翻译要处理不同语言和文字间复杂的上下文对应关系。课件以秦始皇统一文字、《中庸》“今天下车同轨,书同文,行同伦”、巴别塔故事和文言倒装“关山度若飞”说明语言沟通与翻译的困难。预处理包括分词和 Word2vec 向量化,核心是序列建模。
Encoder-Decoder 架构把输入序列 \(x=(x_1,\ldots,x_T)\) 编码为隐含表示 \(z=(z_1,\ldots,z_n)\);Decoder 接收 \(z\),每次生成一个符号,直到得到 \(y=(y_1,\ldots,y_m)\)。解码是自回归的,即生成下一符号时把已经生成的符号作为附加输入。
普通 RNN Encoder-Decoder 只用编码器最后状态概括整个输入,例如把“深 度 学 习”压缩到 \(h_4\),再逐步生成 deep learning <eos>,对局部上下文依赖关系的描述不足。加入注意力后,第 \(t\) 步上下文向量为
其中 \(\alpha_{tj}\) 是解码器第 \(t\) 步与编码器第 \(j\) 步的对齐权重,即注意力系数。解码状态和输出写为
这样每个输出时刻都能按需汇集所有编码时刻的信息,而不再只依赖一个固定的末状态。
本讲要求与思考
本讲应掌握人类记忆机制、传统 RNN、门控 RNN、BiRNN+CTC 和 RNN Encoder-Decoder,理解多自变量、多中间变量复合函数的求导,并完成网络学堂“课程文件→编程实践”中的第 7 讲编程教程。
- Swish 是自门控激活函数 \(\operatorname{swish}(x)=x\sigma(\beta x)\),推导其导数。
- 思考循环神经网络引入门控机制后如何对参数求导。
- LSTM 的 Input Node 已用 Tanh 把数值限制在 \((-1,1)\),思考输出 cell 时为何还要再使用一次 Tanh。