ChatGPT入门之文本情绪识别:先了解LSTM如何处理文字序列
文章目录
- 0. 首先聊聊什么是RNN
- 1. 理解LSTM,从数据如何喂给 LSTM开始
- 2. LSTM每个门是如何处理序列数据的?
- 2.1 遗忘门(Forget Gate):该忘掉哪些信息?
- 2.2 输入门(Input Gate):该记住哪些新信息?
- 2.3 输出门(Output Gate):此刻该吐露什么?
- 3. 用代码实现文本情感识别
- **数据预处理**
- **构建LSTM模型**
- 4. 总结:LSTM如何发掘情感?
- 5. 内容延展
- 6.参考资料
想象这样一个任务:你希望训练一个模型,它能说出一段文字的情感是“正面”还是“负面”,比如:
- “这部电影简直太棒了!” → 正面情感
- “糟糕透顶,浪费了两个小时的时间。” → 负面情感
这就是一个典型的文本情感识别任务,而LSTM(长短期记忆网络)特别适合这种顺序依赖的数据。
接下来,我们通过这个具体的例子,从输入文本到情感分类,逐步剖析LSTM的内部机制,结合每一个“门”的作用,帮助你理解它是如何工作的。
0. 首先聊聊什么是RNN
思考问题时,人类不是每一时刻都是从零开始的。当你阅读这篇短文时,对于每一个词的理解都是基于这个词之前的词的含义。你不会把前面看到的丢弃,然后从零开始。你的思考是连贯的。
传统的神经网络无法做到这一点,并且这是它的一个主要的缺点。例如,假如你想清楚地知道在一个电影的每一个片段发生了什么样的事情。现在,还不能确定,传统的神经网络如何能够基于已知的事件推断出将要发生的事件。
循环神经网络致力于解决该问题。这样的网络通过环回链接,保持信息的连贯性。
在上图中,A是一个神经网络的一部分,输入 x t x_t xt得到输出 h t h_t ht。环回链接控制信息被从网络的一层传递到下一层。
这些环回链接使得循环神经网络看起来有些神秘。但是,如果你更进一步地思考,它与普通的神经网络没有太大的区别。一个循环神经网络可以被认为是一个网络的多个拷贝,每一个把信息传递给下一个。对循环神经网络做循环展开后,它就是下面的样子:
这种链式的本质说明了循环神经网络本质上与序列和链表相关。它天生就是要应用到这样的数据上。
RNNs最令人着迷的是,它也许能够将当前的任务与之前的信息联系起来。例如,通过视频以播放过的帧来理解当前的这一帧。如果RNNs能做到,它的作用是巨大的。RNNs能做到吗?在某些条件下是的。
有些时候,当前的任务是可以依据最近的信息推测出来的。例如,依据前面已经出现的词推测下一个词的语言模型。当我们推测“the clouds are in the sky,”这句话的最后一个词时,已经不需要其他的上下文了;非常明显这个词是“sky”或者"mountain"。在这种情况下,相关联的词汇间的距离很短,RNNs能够学习如何使用这些信息。
但是在某些情况下需要更多的上下文。例如预测这句话 - “I grew up in France… I speak fluent French.” - 的最后一个词。与目标词最近的相关信息表明这个词很可能指某个语言。但是如果把这个词缩小到某个具体的语言上,就需要与距离较远的France的上下文考虑到。
与目标点相关的信息与目标点之间的间隔非常的大,这是完全可能的。
不幸的是,随着距离的增加,RNNs就不能学习到这些关联信息。
在理论上,RNNs绝对能够处理长距离间的依赖关系。通过仔细挑选参数,能够在一些实验性的玩具项目上取得很好的效果。不幸的是,在现实中,RNNs不能学习使用这些信息。Hochreiter (1991) [German] 和 Bengio, et al. (1994), 在这方面做了深入的研究,他们的研究结果揭示了一些RNNs在这方面的本质上的缺陷。
令人欣慰的是,LSTMs能解决这个问题!
1. 理解LSTM,从数据如何喂给 LSTM开始
在情感识别中,输入是一段文本,比如:
输入句子:
“This movie is fantastic and I love it!”
LSTM接收的数据要求是一个序列型输入,因此我们需要以下预处理步骤:
-
分词和索引化
将句子分割成单词并用数值表示。例如:
"This movie is fantastic and I love it!" → [1, 2, 3, 4, 5, 6, 7]
(假设 “This” 对应索引 1,“movie” 对应索引 2,依此类推。) -
嵌入向量表示
每个单词会用一个固定长度的向量表示,例如通过**词嵌入(Embedding)**生成300维向量:[1, 2, 3, 4, 5, 6, 7] → [[0.5, 0.8, ...], [0.2, 0.9, ...], ..., [0.7, 0.4, ...]]
输入的数据就变成了一个二维矩阵,形状为:
(单词数, 每个单词的向量维度) = (7, 300)
2. LSTM每个门是如何处理序列数据的?
现在我们以这句输入 “This movie is fantastic and I love it!” 为例,逐步拆解 LSTM 的门机制,看看它是如何从文字序列中提取情感特征的。
2.1 遗忘门(Forget Gate):该忘掉哪些信息?
首先,遗忘门会接收当前单词的表示(如第一个单词 “This” 的嵌入向量)和上一时间步的信息(即隐藏状态 h t − 1 h_{t-1} ht−1),决定过去哪些记忆应该被“遗忘”。
公式如下:
f t = σ ( W f [ h t − 1 , x t ] + b f ) f_t = \sigma(W_f[h_{t-1}, x_t] + b_f) ft=σ(Wf[ht−1,xt]+bf)
- x t x_t xt:当前时间步的输入(如 “This” 的向量表示)。
- h t − 1 h_{t-1} ht−1:上一时间步的隐藏状态(尚未产生)。
- f t f_t ft:遗忘门输出向量(值在 0 和 1 之间)。接近1的值会保留过去信息,接近0的值会遗忘。
在解读句子的时候,“This”和情感无关,因此模型可能输出低遗忘比例,例如 f t = [ 0.3 , 0.1 , 0.2 , . . . ] f_t = [0.3, 0.1, 0.2, ...] ft=[0.3,0.1,0.2,...],表示对当前单词(“This”)相关的记忆会部分清除。
2.2 输入门(Input Gate):该记住哪些新信息?
遗忘了无关信息后,输入门决定哪些新信息需要记住。两个核心过程:
-
生成候选记忆内容 C ~ t \tilde{C}_t C~t
当前单词向量(如"fantastic")经过权重变换和激活函数处理,生成可能的记忆内容:C ~ t = tanh ( W C [ h t − 1 , x t ] + b C ) \tilde{C}_t = \tanh(W_C[h_{t-1}, x_t] + b_C) C~t=tanh(WC[ht−1,xt]+bC)
例如,“fantastic” 强烈关联到积极情感,候选记忆向量 C ~ t \tilde{C}_t C~t 的值可能表示强正面情感。
-
输入门决定记忆的权重 i t i_t it
i t = σ ( W i [ h t − 1 , x t ] + b i ) i_t = \sigma(W_i[h_{t-1}, x_t] + b_i) it=σ(Wi[ht−1,xt]+bi)输入门输出 i t i_t it 决定该候选记忆的比重。
-
更新记忆单元 C t C_t Ct
最终,记忆单元的更新公式为:C t = f t ⋅ C t − 1 + i t ⋅ C ~ t C_t = f_t \cdot C_{t-1} + i_t \cdot \tilde{C}_t Ct=ft⋅Ct−1+it⋅C~t
在处理"fantastic"时,输入门可能输出 i t = [ 0.9 , 0.8 , 0.7 , . . . ] i_t = [0.9, 0.8, 0.7, ...] it=[0.9,0.8,0.7,...],表示“要记住这个强正面情感的单词”。然后结合候选记忆单元 C ~ t \tilde{C}_t C~t,将它添加到记忆中。
2.3 输出门(Output Gate):此刻该吐露什么?
最后,输出门决定当前记忆中哪些信息需要释放给下一层或时间步,用于接续处理或最终的分类。
-
计算输出门权重 o t o_t ot:
o t = σ ( W o [ h t − 1 , x t ] + b o ) o_t = \sigma(W_o[h_{t-1}, x_t] + b_o) ot=σ(Wo[ht−1,xt]+bo) -
生成隐藏状态 h t h_t ht:
h t = o t ⋅ tanh ( C t ) h_t = o_t \cdot \tanh(C_t) ht=ot⋅tanh(Ct)h t h_t ht 是 LSTM 的输出,会直接用于下一时间步的计算,或通过全连接层参与情感分类。
在处理到句子最后的 “it” 时,LSTM 的隐藏状态已经累积了上下文信息。此时的 h t h_t ht 可能非常接近“正面情感”的特征表示。
3. 用代码实现文本情感识别
以下代码演示如何用 TensorFlow 构建一个简单的 LSTM 模型,用于情感分类任务。
数据预处理
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 样本数据
texts = [
"This movie is fantastic and I love it!", # 正面情感
"This film is horrible, I hate it!" # 负面情感
]
# 标签 (1 表示正面, 0 表示负面)
labels = [1, 0]
# 分词与索引化
tokenizer = Tokenizer(num_words=10000)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
# 填充序列到固定长度
maxlen = 10
X = pad_sequences(sequences, maxlen=maxlen, padding='post')
y = labels
print("输入形状:", X.shape)
构建LSTM模型
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense
# 定义LSTM情感分类模型
model = Sequential([
Embedding(input_dim=10000, output_dim=300, input_length=maxlen),
LSTM(128, return_sequences=False),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
# 假设使用训练数据进行训练
model.fit(X, y, batch_size=2, epochs=10)
4. 总结:LSTM如何发掘情感?
结合我们的例子可以看到:
- 遗忘门:过滤掉“无关”单词对情感的影响,比如 “This”。
- 输入门:捕捉关键情感词汇,比如 “fantastic”、“horrible”。
- 输出门:输出情感特征,逐步累积句子的情感信息。
最后,通过分类器,我们得到了精准的情感判断:
“This movie is fantastic and I love it!” → Positive
从这一任务中,可以感受到 LSTM 对时间序列建模的强大能力,它让机器逐步理解了句子的情感含义!
5. 内容延展
虽然LSTM在处理文本、音频和其他序列数据时表现十分优秀,但它也有一定的局限性,例如当序列非常长时,仍然可能有信息丢失的问题。近年来,更加先进的模型正在逐渐取代LSTM:
-
Transformer
Transformer模型通过自注意力机制建模长距离依赖,极大提升了序列数据的建模能力。在自然语言处理任务(如机器翻译)中,Transformer已成为主流。 -
Conformer
在语音识别任务中,Conformer结合了卷积网络和Transformer的优势,是处理语音序列的强大模型。 -
Mamba
Mamba 是一种由斯坦福大学研究团队在 2023 年底提出的新型状态空间模型架构,它专为信息密集型任务(如长序列数据或高维数据)而生。与LSTM相比,Mamba使用选择性状态空间模型(Selective State Space Model, SSM),能够以线性时间复杂度处理长序列数据。
在后续内容中,我们将逐步介绍这些更现代、更强大的模型,敬请期待!
6.参考资料
[1] 理解LSTM网络 (https://colah.github.io/posts/2015-08-Understanding-LSTMs/).
[2] 深入理解LSTM (https://xiaohutou.github.io/2018/05/01/understanding-lstm-networks/).
[3] LSTM情绪识别实战 (https://github.com/lukasgarbas/nlp-text-emotion).
感谢各位读者耐心看到这里!如果这篇文章对您有所启发,请收藏、点赞和分享给更多的朋友,让我们一起交流人工智能的魅力。如果您有任何问题或想法,欢迎在评论区留言,我会尽量回复每一条评论!
期待我们在学习之路上的共同成长!🎉