Skip to content

MIT深度学习课程第五讲:文本向量化与Bag of Words ​

本节课开始进入 natural language processing 序列。

课程从最基础的问题出发:

文本如何表示成神经网络可以处理的数字?

图像可以直接使用 pixel intensity,例如 0 到 255 的数值;但句子如 I love deep learning 不能直接送入模型,必须先转换成数值表示。

本节课围绕以下内容展开:

  • NLP 课程路线与应用场景。
  • NLP 技术从规则、统计方法到深度学习和 transformers 的发展。
  • text vectorization 的基本流程。
  • standardization、tokenization、indexing、encoding。
  • one-hot encoding 与 UNK token。
  • Bag of Words 模型。
  • 用 Keras TextVectorization 构建歌词 genre 分类模型。
  • 用 bigrams 引入局部词序信息。
  • dropout 的基本思想。
  • KerasTuner 与超参数搜索。

一、本节课在 NLP 单元中的位置 ​

老师说明,本节课是 NLP 序列的开篇。

课程安排大致是:

  1. 本节课:vectorization 和 Bag of Words。
  2. 本节课后半:用一个 Colab 实际构建文本分类模型。
  3. 周三:介绍 embeddings。
  4. 接下来两周:讲 transformers,包括理论和应用。
  5. 第 9、10 讲:围绕 LLMs 展开。

老师强调,embeddings 会成为后续几周的重要基础。它们不仅是现代 NLP 的核心原子单元,也与现代 vision processing 有关。

二、为什么 Natural Language Processing 重要 ​

老师首先说明,NLP 之所以重要,是因为 text 在人类活动中占据核心位置。

几个原因包括:

  • human knowledge 大多以 text 形式编码。
  • internet 很大程度上由 text 构成。老师补充说,在 TikTok、YouTube 等视频平台兴起之前,这一点尤其明显。
  • human communication 大量依赖 text。
  • cultural production,例如 movies、books、arts,也高度依赖 text。

老师认为,text 不只是媒体中的一大类内容,也是人类思考、表达和沟通的重要载体。

NLP 的吸引力在于:

如果 AI 系统能够阅读并“理解”大量文本,就可能从海量知识中发现人类尚未显式连接起来的信息。

老师举了医学文献的例子:

  • 系统阅读 PubMed 和大量 medical literature。
  • 找出某个 disease 对应的 malfunctioning protein。
  • 进一步推断某个 small molecule 可以 dock 到该 protein 上。
  • 最终提出潜在治疗方向。

老师认为类似能力未来可能出现,但可能不会很快实现。

三、NLP 已经存在于日常产品中 ​

老师举了几个 NLP 已经实际发挥作用的例子。

3.1 Google Autocomplete ​

Google autocomplete 使用了大量 NLP 技术。

老师提到,根据 Google 的说法,autocomplete 每天节省约:

text
200 years of typing time

老师认为,在每天有数十亿次搜索的背景下,这个数字本身不一定最令人震撼,更重要的是 autocomplete 对移动设备输入体验的影响。

如果没有 autocomplete,在手机键盘上输入会困难得多,也可能对移动端电商等活动产生明显阻碍。

3.2 iPhone 软键盘的预测式 UI ​

老师还提到一个早期 iPhone 软键盘的例子。

据说,早期 iPhone keyboard 会做简单的 word continuation prediction。

例如用户输入:

text
t h

系统会预测接下来可能是:

text
e

于是键盘上的 e 键可能会在交互区域上稍微变大,让手指更容易点中。

这个例子说明,NLP 不只是生成文字,也可以实时影响 UI 行为。

3.3 LLM 文本生成 ​

老师提到,今天大家已经熟悉 LLMs。

他展示了让模型写一首关于 deep learning 的 limerick 的例子,用来说明现代语言模型已经能够生成较自然的文本。

这个示例诗大意是将 data 比作 stream,描述 deep learning 能从 noise 中提取有用 insight。

四、Text In, Text Out 的通用形式 ​

老师指出,即使只考虑一种非常简单的形式,NLP 的应用范围也非常广:

text
text in, text out

也就是:

  • 输入是一段 text。
  • 输出也是 text 或可由 text 表达的结果。

这个简单形式可以覆盖许多任务。

五、Text Classification ​

text classification 是最容易理解的一类 NLP 任务。

例子包括:

  • sentiment classification。
  • customer support routing。
  • search intent detection。
  • content filtering。
  • toxic 或 abusive content detection。

这些任务都可以理解为:

给定一段文本,判断它属于哪个类别。

六、Text Extraction ​

text extraction 是从 unstructured textual data 中提取结构化信息。

老师举了几个例子:

  • hedge funds 从 news articles 中抽取 company information。
  • 医疗场景中,从 doctor-patient conversation 或 doctor's notes 中抽取 disease codes、diagnosis codes、medication codes 等。

这类任务的价值在于,将原本难以直接计算的自然语言材料转成可分析、可检索、可进入业务流程的数据。

七、Text Summarization 与 Text Generation ​

text summarization 是将长文本压缩成摘要。

老师提到,许多人已经通过 ChatGPT 使用过这类能力:

text
text in → summary out

text generation 则可以产生新的文本,例如:

  • marketing copy
  • sales emails
  • market summaries
  • college application essays

老师特别指出,college application essays 对教育者来说是一个令人担忧的例子。

八、Code Generation 也是 Text Out ​

老师强调,code generation 也是 text out 的一种。

原因是:

code 本质上也是 text。

因此,text in, text out 也包括:

text
text in → code out

九、Question Answering 与 Call Center 应用 ​

question answering 也可以用 text in, text out 表示。

输入可以由两部分构成:

  1. 一批 documents。
  2. 一个 question。

从模型视角看,这些最终仍然是一大段 text。

老师特别强调 call centers 是当前投入很多资金的场景。

一个 call center chatbot 可以利用:

  • call center transcripts
  • internal product documentation
  • service documentation
  • FAQs

在此基础上回答很多业务问题,例如:

  • 昨天客户不满的主要原因是什么?
  • 哪些 agent interventions 有效?
  • 哪些 interventions 没有效?
  • 最好的 agents 与其他 agents 有什么区别?
  • 如何评价某个 agent 与某个 customer 的具体互动?
  • call center script 应该如何调整?
  • 如何实时指导 agent?

老师指出,这些问题都可以被映射到 text in, text out 的形式。

十、Google Gemini 1.5 Pro 与多语言问题 ​

老师提到,Google 刚发布了 Google Gemini 1.5 Pro,并认为它非常强。

随后有学生问:

虽然这些任务被称为 language,但这里讨论的是否主要是 English?

老师回答:并不是只有 English。

目前有两类相关模型:

  • 针对非英语语言专门训练的 models。
  • 真正的 multilingual 或 polyglot models。

很多现代 LLMs 从一开始就会在多个 high-resource languages 上训练。这里的 high-resource languages 指使用者多、可获得数据也多的语言。

十一、低资源语言示例:Kalimpong ​

老师用 Gemini 1.5 Pro 举了一个低资源语言例子。

他提到有一种语言叫 Kalimpong,全世界约 200 人使用。

一位研究者为该语言写了一本类似 grammar manual 的书,因为这种语言几乎没有其他 written works。

实验做法是:

  1. 给模型输入大量 English dialogue。
  2. 同时给模型输入这本 Kalimpong grammar manual。
  3. 让模型将 English 翻译成 Kalimpong。

老师说模型达到了 human-level proficiency,而且之前并没有见过这种语言。

这个例子说明,现代大模型即使没有显式训练过某种语言,如果获得足够的 grammar manual 或类似说明,也可能具备较强的 zero-shot 或 in-context translation 能力。

十二、NLP 创业与企业产品趋势 ​

老师提到,很多人正在围绕这些 NLP 能力创业,构建新的 products 和 services。

他也建议,如果学生已经在考虑 entrepreneurship,可以认真尝试这一方向。

企业软件厂商也在快速把 NLP 或 GPT 能力加入产品:

  • Salesforce 有 Einstein GPT。
  • Microsoft 有 Copilot。
  • 其他厂商也在尝试将 GPT 能力嵌入自己的产品。

老师提醒,其中一部分是真正有价值的能力,也有很多只是包装。

十三、NLP 发展脉络 ​

老师接着回顾 NLP 技术的发展路径。

可以粗略分为几个阶段:

  1. hand-crafted rules based on linguistics。
  2. statistical machine learning。
  3. recurrent neural networks。
  4. transformers。

十四、阶段一:基于语言学的手工规则 ​

早期 NLP 依赖 linguists 的专业知识。

做法是:

  • 理解某种语言的 grammar。
  • 利用语言学知识写出规则。
  • 用这些规则分析和处理 natural language text。

这类方法需要大量人工设计。

十五、阶段二:Statistical Machine Learning ​

后来的 statistical machine learning 方法采用不同思路:

与其手写复杂规则,不如大量计数。

典型做法包括:

  • count how often words co-occur。
  • count other textual patterns。
  • 用这些统计特征做 classification 或 prediction。

老师强调,这些“简单计数”方法效果出人意料地好,甚至超过了许多精心设计的语言学规则。

他提到一个著名玩笑式说法:

每当我解雇一位语言学家,speech recognizer 的性能就会上升。

这句话是玩笑,但反映了统计方法在当时的实际影响。

十六、阶段三:Recurrent Neural Networks ​

大约 2012 年,deep learning 推动了 NLP。

其中一类重要方法是:

text
recurrent neural networks

RNNs 曾经推动了 NLP 进展。

不过本课程不会花时间讲 RNNs。

老师补充,这并不意味着 RNNs 完全死亡。现在也有一些研究尝试复兴 recurrent neural networks,使其适用于现代 LLM 任务,但还处在较早阶段。

十七、阶段四:Transformers ​

2017 年,transformer 被提出。

老师指出:

transformer 后来几乎全面替代了前面许多方法。

因此,本课程会直接进入 transformers,而不是系统讲 RNNs。

十八、NLP 问题的高层形式 ​

从深度学习视角看,NLP 仍然可以写成类似的模型形式:

text
x → f(x, w) → y_hat

其中:

  • x 是输入,在本节课中是 text。
  • w 是 weights。
  • f 是 deep neural network。
  • y_hat 可以是 text、labels、numbers 或其他输出。

老师称这仍然可以理解为某种 “fancy regression”。

十九、本节课的关键问题:如何表示 x ​

图像中,x 可以直接来自 pixels。

例如每个 pixel 是一个 0 到 255 的 intensity number。

但文本不同。

例如:

text
I love deep learning

这句话不能直接作为数字输入送入模型。

本节课的核心问题是:

如何把 text 表示成 numerical vectors?

下一阶段学习 transformers 时,课程会讨论另一个问题:

什么 neural network architecture 更适合处理这些 text inputs?

二十、Text Vectorization 总览 ​

老师介绍标准文本预处理流程:

text
text vectorization

这个流程的目标是:

将 text 转换成 vectors of numbers。

老师用一个缩写帮助记忆:

text
S-T-I-E

对应四个步骤:

  1. standardization
  2. tokenization
  3. indexing
  4. encoding

二十一、Training Corpus ​

在文本任务中,首先有一个:

text
training corpus

它由大量 text documents 或 text data 构成。

从模型角度看:

  • 一篇 novel 可以看作一段很长的 string。
  • 一个 sentence 也可以看作一段 string。
  • 两者本质上都是 text sequence。

因此,training corpus 可以简单理解为:

text
a big list of strings

接下来要对整个 corpus 进行 standardization 和 tokenization。

二十二、Standardization ​

standardization 是文本标准化。

常见操作包括:

  1. strip capitalization,将文本转成 lowercase。
  2. remove punctuation。
  3. remove accents。
  4. remove stop words。
  5. stemming,将相近词形归并到共同 root 或 stem。

老师说明,这些操作的常见程度不同:

  • lowercasing 和去标点通常几乎总会做。
  • stop-word removal 经常会做。
  • stemming 有时会做。

二十三、Stop Words ​

stop words 指常见但在某些预测任务中信息量不大的词。

例子包括:

text
a
the
it
and

这些词在语法上有用,但在某些任务中不一定帮助预测。

例如在 movie review sentiment classification 中,a、and、the 是否出现,通常不会决定情感正负。

因此,可以考虑删除它们。

二十四、Stemming ​

stemming 的目标是把相近词形映射到同一个表示。

例如:

text
ate
eaten
eating

这些词可以被归并到类似 eats 的共同表示上,或更一般地归并到共同 stem 上。

老师的直觉是:

如果多个词形表达近似的核心概念,就没有必要让模型把它们当成完全不同的东西重新学习。

二十五、为什么要做 Standardization ​

学生指出,标准化可以抽取词的本质部分,例如从 eaten 或 eat 中抽象出核心的 eat。

老师进一步解释,标准化有几个目的。

也有学生指出,标准化可以帮助比较不同文本集合,因为它减少了同一概念的表面差异。

25.1 降低计算成本 ​

如果 vocabulary 更小,模型需要处理的输入维度也更小。

这会减少计算量。

25.2 帮助模型识别“本质相同”的东西 ​

老师用上一节 computer vision 的例子类比:

  • vertical line 在左边和右边本质上仍然是 vertical line。
  • 模型不应该浪费 capacity 分别学习它们。

文本中也类似。

例如:

  • Apple
  • apple

在多数任务中,大小写差异并不重要。

将所有词转成 lowercase,就是明确告诉模型:

uppercase version 和 lowercase version 在这里不应被当成两个完全不同的东西。

25.3 移除对预测无用的信息 ​

stop words 的原因略有不同。

它们不是因为“大小写不同但本质相同”,而是因为它们可能对特定预测任务帮助有限。

如果一个词对 sentiment prediction 基本没有贡献,就可以考虑删除。

二十六、Standardization 示例 ​

老师展示了一个以 Hola! 开头、包含 travel to Mexico 等内容的句子。

标准化后可以看到:

  • uppercase 变成 lowercase。
  • punctuation 消失。
  • Mexico 的 M 变成小写。
  • sipping 被归并成类似 sips。
  • think 被归并成类似 thinks。

这个例子展示了 lowercase、去标点和 stemming 等操作的效果。

老师同时提醒,标准流程有重要例外,后面会回到这些例外。

二十七、Tokenization ​

tokenization 是将标准化后的文本切分成 tokens。

最常见的默认做法是:

把一个 word 当作一个 token。

实现方式通常是:

text
split on whitespace

这里的 whitespace 包括:

  • spaces
  • carriage returns
  • 其他空白字符

例如,一个标准化后的句子按空格切分后,每个 word 就成为一个 token。

二十八、Whitespace Tokenization 的问题 ​

按空格切分虽然简单,但有很多局限。

28.1 丢失顺序和上下文 ​

学生指出,如果只看每个 word,会丢失 context。

例如:

text
the cat sat on the mat
the mat sat on the cat

如果只看词集合,两句话包含相同 words,但含义不同。

28.2 破坏复合表达 ​

另一个学生指出,像 Puerto Vallarta 这样的名称被空格切开后,会丢失它作为一个整体 name 的信息。

老师也举了:

text
father-in-law

这类 compound words。

28.3 非英语语言不一定用空格分词 ​

很多 non-English languages 并没有用空格分隔 words 的习惯。

在这些语言中,native speakers 依靠 context 判断如何 chunk 文本。

如果简单按 whitespace split,可能会把整段文本当成一个 token。

28.4 某些语言有极长单词 ​

老师提到 German 中可能出现非常长的 word。

他还提到 Japanese 中的 komorebi,表示阳光穿过秋天树叶的短暂之美。

这些例子说明,不同语言中的 “word” 概念并不总是可以用英文空格切分规则处理。

二十九、为什么 LLM 不能只用简单分词 ​

老师说明,前面描述的 whitespace tokenization 尽管有局限,但对很多 NLP use cases 仍然足够。

例如:

text
text classification

但如果要做 text generation,尤其是 LLMs,这种做法不够。

原因包括:

  • ChatGPT 生成文本时能保留 punctuation。
  • 它能保留 upper/lower case。
  • 用户可以造一个新词,并要求模型使用它。

这说明现代 LLM 不能只依赖固定词表和简单去标点、转小写的规则。

老师提到一种更聪明的 tokenization scheme:

text
byte-pair encoding

本节课暂时不展开,后面讲 LLMs 时会回到它。

三十、Vocabulary ​

当训练集中的每个 sentence 或 passage 都完成 standardization 和 tokenization 后,就会得到所有 distinct tokens。

这些 distinct tokens 构成:

text
vocabulary

在本节课的简单情形下,vocabulary 就是训练数据中出现过的所有 distinct words。

三十一、Indexing ​

indexing 是给 vocabulary 中每个 distinct token 分配一个 unique integer。

例如,假设 training corpus 是大量 English literature。

完成处理后可能得到一个很大的词表,从 a 到 zebra 等。

老师用:

text
50,000 tokens

作为示例。

这个数字是因为 GPT family 使用过约 50,000 tokens 的设定,老师借它说明问题。

老师强调:

这不是 English language 中实际 word 数量。真实词数更多。

三十二、UNK Token ​

除了普通 tokens,还会引入一个特殊 token:

text
UNK

UNK 表示:

text
unknown

在示例中,老师把 UNK 分配为 integer:

text
0

学生问 unknown 是什么。

老师先说明它是某种 placeholder,后面在处理新输入句子时会解释它的用途。

三十三、Encoding ​

encoding 是把每个 integer 映射到一个 vector。

流程可以概括为:

  1. distinct token。
  2. unique integer。
  3. vector representation。

问题是:如何为每个 token 构造一个不同的 vector?

学生提出可以直接把 index 放进一个一维 vector 中。老师认为这有点像把数字加上方括号,形式上像 vector,但没有真正解决表示问题。

另一个学生提出:

text
one-hot encoding

老师确认这是最简单直接的方法。

三十四、One-Hot Encoding ​

如果 vocabulary size 是 50,000,那么每个 token 的 one-hot vector 长度就是:

text
50,000

向量中:

  • 绝大多数位置是 0。
  • 只有 token 对应 index 的位置是 1。

例如:

  • UNK 的 index 是 0,则第 0 个位置是 1。
  • a 如果是下一个 token,则对应位置是 1。

老师提到,有时会说 zero-hot 或 one-hot,本质是同一类稀疏指示向量。

三十五、Vocabulary Size ​

encoding vector 的长度由 vocabulary size 决定。

在包含 UNK 的情况下:

text
vocabulary size = distinct tokens in training corpus + 1

+1 是为了 UNK。

到这里为止,基本文本预处理已经完成:

  • 从 training corpus 创建 vocabulary。
  • 每个 distinct token 被分配 index。
  • 每个 index 被映射成 one-hot vector。
  • 每个输入 token 都可以映射到一个可能非常长的 one-hot vector。

三十六、新句子示例:the cat sat on the mat ​

老师接着说明,已经在 training corpus 上完成 S-T-I-E 后,如何处理新来的句子。

假设训练后发现:

  • 99 个 distinct tokens。
  • 加上 UNK 后 vocabulary size 是 100。

词表从 UNK、a 等开始,一直到 zebra,总数为 100。

老师说明,这个例子没有做 stemming 或 stop-word removal,所以词表里仍然可能包含 the。

现在输入句子:

text
the cat sat on the mat

这个句子有 6 个 words。

每个 word 会被编码成长度 100 的 one-hot vector。

因此结果可以看成一个表:

text
6 x 100

也可以根据约定写成:

text
100 x 6

老师采用的是:

text
6 x 100

整个句子因此变成一个包含 600 个 entries 的 table。

三十七、为什么不能简单 Flatten ​

学生提出,可以像处理图像一样 flatten 这个 table。

老师认为 flatten 是一个合理想法,但有两个重要问题。

37.1 输入向量会非常长 ​

如果每个 word 的 one-hot vector 长度是:

text
50,000

那么 6 个 words 就会变成:

text
6 * 50,000 = 300,000

如果再接一个有 100 个 units 的 hidden layer,第一层参数量会非常大:

text
300,000 * 100

老师认为这太大,难以学习。

37.2 文本长度不固定 ​

不同输入文本有不同长度。

例如:

  • the cat sat on the mat
  • 更长的句子,如包含 rat、cat 等更多词的句子

它们 flatten 后会有不同维度。

但神经网络通常需要固定长度 input。

因此,直接 flatten 无法自然处理 variable-sized inputs。

三十八、Aggregation:把 Table 变成 Vector ​

学生提出,可以按列求和,统计每个词出现次数。

老师确认,这个思路与后面的模型方向一致:

需要把 word-by-token table 聚合成固定长度 vector。

常见方式包括:

  • sum encoding
  • count encoding
  • multi-hot encoding

三十九、Count Encoding ​

count encoding 的做法是:

对每个 token 位置,统计该 token 在输入文本中出现了多少次。

它也可以称为 sum encoding,因为本质上是在按列加总 one-hot rows。

如果某个 word 出现 2 次,对应位置就是:

text
2

如果没有出现,对应位置就是:

text
0

这种方式也可以理解为对 one-hot rows 做 column-wise sum。

四十、Multi-Hot Encoding ​

multi-hot encoding 不统计出现次数,只记录是否出现过。

做法是:

  • 如果某个 token 出现过至少一次,对应位置为 1。
  • 如果从未出现,对应位置为 0。

也就是说,多个相同 token 出现时,在 multi-hot vector 中仍然只记为 1。

四十一、Bag of Words Model ​

上述聚合方法对应:

text
Bag of Words model

名字中的 Bag 表示模型只关心文本里有哪些 words,或每个 word 出现了多少次。

它可以使用:

  • multi-hot encoding:记录 word 是否存在。
  • count encoding:记录 word 出现次数。

更重要的是:

Bag of Words 不关心 words 的顺序。

因此:

text
the cat sat on the mat
the mat sat on the cat

在 Bag of Words 表示下可能完全一样。

这是一个巨大限制,但老师强调:

对很多 applications 来说,它仍然足够好。

四十二、Bag of Words 的局限 ​

老师列出或引导学生指出了几个局限。

42.1 丢失顺序信息 ​

Bag of Words 会丢失 sequentiality。

它无法表达 words 的顺序,也无法捕捉 order 中蕴含的 meaning。

42.2 表示非常稀疏 ​

学生指出,向量里会有很多 zeros,只有少数 ones 或 counts。

老师确认,这会带来 sparsity 问题。

虽然计算机科学中有很多技巧可以更聪明地处理 sparse data,但稀疏性仍是重要问题。

42.3 所有输入长度相同 ​

无论输入是:

text
I love you

还是 Shakespeare 的全部作品,都会被映射成同样长度的 vector。

这个长度由 vocabulary size 决定。

对于短文本来说,这可能浪费大量计算。

42.4 Vocabulary 可能很长 ​

如果 vocabulary 很大,输入 vector 就很长。

老师提到,他读到 English language 约有:

text
500,000 words

但高频的前:

text
50,000 words

已经覆盖了绝大部分日常会遇到的内容。

其余低频词属于:

text
long tail

它们很少出现。

四十三、只保留高频词与 UNK 的代价 ​

为了提高效率,可以只保留最常见的 words。

例如:

只取 top frequent words,忽略 long-tail words。

但这样会带来 UNK 问题。

例如,如果系统忽略了 Hamlet,当输入为:

text
Hamlet was a bad prince

时,模型在 vocabulary 中找不到 Hamlet,只能将它替换为:

text
UNK

如果 Romeo、Juliet、Hamlet 都没有进入词表,它们都会变成同一个 UNK。

结果是模型无法区分这些词。

四十四、UNK 与 Hallucination 的关系 ​

学生问:UNK 是否就是 hallucination 出现的地方?

老师回答:不是。

后面讲 LLMs 时会看到,现代 LLM 通常不会以这种方式遇到 UNK 问题,因为它们使用不同的 tokenization scheme,可以处理几乎任意输入,包括新造的词。

这个问题会在后续课程中回到。

四十五、为什么本节仍然使用 Bag of Words ​

尽管 Bag of Words 有缺点,老师仍然选择从它开始。

原因是:

对许多 NLP tasks 来说,Bag of Words 是一个很好的 default。

这也符合老师反复强调的建模策略:

先做简单方法;只有简单方法不工作时,再使用复杂方法。

四十六、Colab 任务:歌词 Genre 分类 ​

接下来老师切换到 Colab。

任务是:

输入一段 song lyrics,预测它属于哪个 genre。

目标类别包括:

  • hip hop
  • rock
  • pop

这是一个:

text
multi-class classification problem

老师提醒,该歌词数据集中可能包含不适合工作场合展示的 lyrics,因此课堂上不会深入浏览歌词内容。

四十七、歌词分类模型的输入形式 ​

使用 Bag of Words 和 multi-hot encoding 时,每条歌词文本会被表示成一个 vector。原文中老师有时称其为 song,有时也说要 classify each verse。

vector 长度等于:

text
vocabulary size

老师用一个常见歌词片段作为直觉例子:

text
I love you

经过 S-T-I-E 后,它会变成:

text
x1, x2, ..., xv

其中 v 表示 vocabulary size。

四十八、Baseline Model ​

学生指出,最简单的 baseline 可以是:

永远预测最常见的 genre。

老师确认这是正确 baseline。

后面数据检查显示,rock 约占最大比例,约为:

text
55%

因此,一个 naive baseline 如果总预测 rock,大约能得到 55% accuracy。

老师后面在比较结果时也称它大约是 50% 左右的基线。

四十九、最简单的 Neural Network 分类器 ​

老师问:如果要为这个任务构建最简单的 neural network,应该如何设计?

输入是:

text
Bag of Words multi-hot vector

在本课程中,老师认为至少需要一个 hidden layer,才称作 neural network。

因此最简单结构是:

  1. input vector,长度为 vocabulary size。
  2. 一个 hidden layer,使用 ReLU neurons。
  3. output layer,有 3 个 units。
  4. output activation 使用 softmax。

三个 output units 分别对应:

  • hip hop
  • rock
  • pop

softmax 输出三个 probabilities,并且它们加起来为 1。

五十、为什么用 Softmax 而不是直接取 Max ​

学生问:如果最终只需要最可能的 genre,为什么不直接输出三个数字,然后取最大值?

老师回答,核心原因是:

max function 对 differentiation 不友好。

训练神经网络需要:

  • 将输出送入 cross-entropy 等 loss function。
  • 通过 backpropagation 更新参数。
  • backpropagation 本质上依赖 differentiation。

因此,网络中的函数需要有行为良好的 gradients。

softmax 可以看作 max 的 smooth 或 soft version,更适合梯度优化。

老师还类比前面的问题:

为什么不直接 maximize accuracy,而要用 cross-entropy?原因类似,accuracy 对梯度优化不友好。

五十一、Hidden Layer 大小 ​

老师在构建 Colab 前提到,他试了不同设置,发现:

text
8 ReLU neurons

在 hidden layer 中效果不错。

因此本节示例使用 8 个 ReLU neurons。

五十二、Colab 准备工作 ​

进入 Colab 后,老师先做常规准备:

  • upload required files。
  • import TensorFlow 和 Keras。
  • import NumPy、pandas、Matplotlib。
  • set random seed 为 42。

老师把 NumPy、pandas、Matplotlib 称为数据科学中的常用组合。

五十三、Keras TextVectorization Layer ​

老师说明,S-T-I-E 的四个步骤在 Keras 中可以通过一个 layer 处理:

text
TextVectorization

第一个小例子使用默认设置:

  • default standardization:remove punctuation,convert to lowercase。
  • default tokenization:split on whitespace。
  • output mode:multi_hot。

因此,Keras 会自动完成前面讲过的主要步骤。

五十四、Adapt:从 Training Corpus 建 Vocabulary ​

TextVectorization layer 定义后,还不能直接使用。

它需要先看一批 training corpus,建立 vocabulary。

这个过程使用:

text
adapt

老师先构造了一个很小的 training corpus,用几句歌词文本演示。

调用 adapt 后,layer 会:

  1. 创建 vocabulary。
  2. 为 tokens 建立 index。
  3. 保存这些信息,供后续输入使用。

五十五、get_vocabulary 与 17 个 Tokens ​

调用:

text
get_vocabulary

可以查看 layer 创建出的 vocabulary。

小例子中,vocabulary 长度是:

text
17

老师指出,Keras 自动把 UNK 放在最前面。

也就是说,index 0 对应:

text
UNK

五十六、打印 Python 对象的小技巧 ​

老师顺带给了一个编程小技巧。

如果想更清楚地打印 Python lists 等对象,可以把它们放进:

text
pandas DataFrame

再打印。

很多时候这会比直接 print 更易读。

五十七、为什么 arrays 排在前面 ​

老师问:为什么小 vocabulary 中 arrays 排在很前面,而不是 an 或 a?

学生猜测可能是因为它更影响句子意义。

老师解释,此时 Keras 还不知道下游任务是什么,所以无法判断哪个词更“有用”。

实际原因是:

Keras 会按 frequency 排序。

在那个小 training corpus 中,arrays 出现频率最高;老师通过回看小数据集指出它出现了两次,所以排在前面。

老师补充,位置本身通常不重要;但当用户要求只保留最常见的 100 个 tokens 时,频率排序就很有用。

五十八、Adapt 后 Corpus 会被遗忘 ​

老师强调,adapt 完成后:

training corpus 本身不会保留下来,留下的是 vocabulary。

也就是说,输入的几句文本只是用来让 layer 学会 vocabulary。

后续真正使用时,是把新的 text 送进这个已经适配好的 layer。

五十九、用 TextVectorization 编码新句子 ​

老师把一个新句子传入 TextVectorization layer。

输出是一个:

text
multi-hot encoded tensor

小例子中 vocabulary 长度是 17,因此输出 vector 也长:

text
17

这是一个正确性检查:

vocabulary 有多长,multi-hot vector 就有多长。

六十、UNK 示例:still ​

输出 vector 的第 0 位对应 UNK。

老师发现编码后的句子中 UNK 位被激活。

原因是句子中有一个词:

text
still

它没有出现在小 training corpus 中,所以被映射为 UNK。

老师还用 Python 检查 still 是否在 vocabulary 中,结果是不在。

六十一、用小改动理解代码 ​

老师建议学生通过对代码做小改动来理解行为。

例如输入:

text
Sloan HODL DMD

这些词都不在小 training corpus 中。

如果使用 multi-hot encoding,输出不是三个 UNK counts,而是:

text
1, 0, 0, ...

原因是:

  • 三个未知词都会映射到同一个 UNK 位置。
  • multi-hot 只表示该位置是否出现过。
  • 出现多次仍然只是 1。

如果使用 count encoding,结果才会体现出现次数。

六十二、歌词数据集规模 ​

接着老师进入真正的数据集。

这是一个大约:

text
90,000 songs

的数据集。

数据已经被下载并做了 formatting-level cleanup。

老师强调,这里的 cleanup 是格式清理,不是内容清理。

数据已经预先分成:

  • train
  • validation
  • test

规模大致为:

  • training set:接近 49,000 songs。
  • validation set:约 16,000 songs。
  • test set:约 22,000 songs。

后面实际 x_train 显示有:

text
48,991 rows

六十三、DataFrame 浏览与 Target 编码 ​

老师展示了数据集前几行和后几行。

示例中可以看到不同 lyrics 对应不同 genre,例如 pop、hip hop 等。

前几行示例包括类似 Oh, girl, I can't get ready、we met on rainy evening、paralysis through analysis 的 lyrics 片段;后几行示例包括 You never listen to me 对应 pop、Bimmer, Benz 对应 hip hop。

他也提到 Colab 的 DataFrame 浏览功能适合探索数据。

目标变量是 song genre。

由于这是三分类问题,老师使用:

text
pandas get_dummies

将 target variable 转为 one-hot encoding。

因此 y_train 中每行类似:

text
010
001

表示某个 genre。

六十四、关于预制词表与 Transfer Learning 的问答 ​

学生问:

是否总要根据自己的 training data 创建 corpus/vocabulary?能否使用别人已经整理好的 top 50,000 common words?

老师说这是很好的问题,但暂时先搁置。

原因是现代 LLMs 使很多传统 NLP 任务可以不再从头构建模型,而是直接通过 large language models 完成,甚至不需要 further training。

但代价包括:

  • 需要调用大模型。
  • 可能要支付 API cost。
  • 还有其他实际问题。

老师表示后续 NLP 序列会更多讨论 text transfer learning。

六十五、关于 Float Tensor 的问答 ​

学生问:encoding vector 明明只有 0 和 1,为什么显示为 floats?如果 vector 很长,是否浪费 compute?

老师回答:

  • 确实可以做优化。
  • 对当前小问题来说,不需要担心。
  • 后面讲 parameter-efficient fine-tuning 时,会利用类似事实让训练或适配更快。

老师估计这个内容大约在第 10 讲附近出现。

六十六、正式 Bag of Words:max_tokens = 5000 ​

在真实歌词训练数据上,老师不打算把约 49,000 条 lyrics/songs 中出现的每个词都放进 vocabulary。

而是设置:

text
max_tokens = 5000

含义是:

只保留最常见的 5,000 个 tokens。

输出仍然使用:

text
multi-hot

标准化和 tokenization 使用 Keras 默认设置。

六十七、为什么限制 max_tokens ​

学生问,max_tokens 是否是为了效率。

老师回答,是,但不仅是效率。

67.1 向量长度 ​

max_tokens 决定 vocabulary size。

vocabulary size 决定输入 vector 的长度。

输入 vector 越短,计算越轻。

67.2 参数数量 ​

第一层参数量大致等于:

text
input size * hidden layer size

如果 input vector 长度变成 10 倍,第一层参数也会约变成 10 倍。

67.3 Overfitting ​

在有限数据下,参数越多,模型越容易 overfit。

因此,不能无限扩大 vocabulary。

六十八、从 17 词玩具例子切换到真实 Vocabulary ​

学生问:现在是否仍然使用前面 17 个 tokens 的 vocabulary?

老师回答不是。

前面的 17 词例子只是为了演示。

现在会在真实训练数据上调用 adapt,使用接近 49,000 条训练 lyrics/songs 来创建 vocabulary。

从 Keras 视角看,它只需要一组 strings:

  • 小例子是 4 个 phrases。
  • 真实例子是约 49,000 条 lyrics/songs。

方法相同,只是规模不同。

六十九、真实 Vocabulary 检查 ​

adapt 真实训练数据后,老师查看 vocabulary。

常见 tokens 中包括:

  • UNK
  • the
  • you
  • I

老师指出,the 成为最常见词并不意外。

他也查看了末尾低频词,例如:

  • dagger
  • cheddar
  • terrified

这些例子说明,vocabulary 已经按频率选出了 top tokens。

七十、Keras 默认 STIE 与传统 STIE 的差异 ​

学生问:当前是否完整执行了 S-T-I-E,因为似乎保留了一些词。

老师澄清:

严格来说,这里没有执行所有传统 standardization 操作。

通常 S 可能包括:

  • lowercase/uppercase handling
  • strip punctuation
  • stemming
  • stop-word removal

但 Keras 默认行为中:

  • 会 lowercase。
  • 会去 punctuation。
  • 不会做 stemming。
  • 不会做 stop-word removal。

老师说,在实际工作中,他现在常常不做 stemming,也不删除 stop words,模型通常也能工作得足够好。

七十一、Vectorized Training Data 的 Shape ​

使用 max_tokens = 5000 后,每条歌词文本都被表示成长度:

text
5000

的 vector。

训练集经过 vectorization 后,x_train 是一个 tensor:

text
48991 x 5000

也就是:

  • 48,991 rows。
  • 每行一个 5,000 维 multi-hot vector。

七十二、第一个歌词分类神经网络 ​

模型结构是:

  1. Keras Input
  2. 输入 shape 为 max_tokens
  3. dense hidden layer
  4. hidden layer 有 8 个 ReLU units
  5. output layer
  6. 3 类 softmax

老师说,这段 Keras 代码此时应该已经逐渐熟悉,体现了 abstraction 的力量。

七十三、第一个 Dense Layer 的参数量 ​

输入长度是:

text
5000

hidden layer 有:

text
8

个 neurons。

因此第一个 dense layer 的参数量是:

text
5000 * 8 + 8 = 40008

其中 +8 是 hidden neurons 的 biases。

老师称 model summary 中大约有:

text
40,000 parameters

七十四、Compile 设置 ​

编译时使用:

  • optimizer:Adam
  • loss:categorical_crossentropy
  • metric:accuracy

这里使用 categorical_crossentropy,而不是 sparse_categorical_crossentropy。

原因是:

y_train 已经被 one-hot encoded。

例如 target 可能是:

text
010
001

如果 label 仍是整数类别编号,才更适合使用 sparse_categorical_crossentropy。

七十五、Fit 设置与 Validation Data ​

训练设置为:

  • epochs:10
  • batch size:32

由于数据已经提供了 validation set,所以不需要让 Keras 从 training data 中切出 20%。

可以直接传入:

text
validation_data

七十六、如何选择 max_tokens ​

学生问:如何决定 maximum vocabulary size,例如为什么是 5000?

老师回答,实践中可以这样做:

  1. 先不设置 max_tokens。
  2. 查看完整 vocabulary 有多长。
  3. 统计低频词的出现频率。
  4. 找到频率 dramatic fall-off 的位置。
  5. 把该位置设置为 max_tokens。

这是一种经验型但实用的选择方法。

七十七、第一个模型结果 ​

第一个 Bag of Words 神经网络训练后:

  • training accuracy 约 87%。
  • validation accuracy 约 73%。
  • test accuracy 约 72%。

此前 naive baseline 是总预测最大类 rock,准确率大约 50% 到 55%。

因此,72% test accuracy 对这个简单模型来说已经不错。

七十八、为什么引入 Bigrams ​

老师接着指出,Bag of Words 最大问题之一是丢失词序。

词序显然很重要。

老师用一个 movie review 示例说明:

text
Kate Winslet's performance as a detective trying to solve a terrible crime in a small Pennsylvania town is anything but disappointing

如果只看单词:

  • terrible
  • disappointing

模型可能以为这是 negative sentiment。

但正确理解需要知道:

  • terrible 修饰的是 crime,而不是 movie。
  • anything but disappointing 改变了 disappointing 的含义。

整体上,这更像 positive review。

这说明:

word 周围的 words 会提供重要 context。

七十九、Bigrams 与 N-Grams ​

bigram 的做法是:

不只把单个 word 当 token,也把相邻两个 words 的组合当 token。

例如:

text
the cat sat on the mat

可以产生类似 tokens:

  • the
  • the cat
  • cat
  • cat sat
  • sat
  • ...

两个相邻 words 组成的 token 叫:

text
bigram

三个相邻 words 组成的 token 叫:

text
trigram

更一般地称为:

text
n-grams

八十、Keras 中使用 Bigrams ​

在 Keras TextVectorization 中,使用 bigrams 很简单:

text
ngrams = 2

老师指出,由此可知默认设置相当于:

text
ngrams = 1

也就是只使用 unigrams。

老师用 cat sat on the mat 的小例子展示,Keras 会自动生成 bigram tokens。

八十一、在歌词模型中加入 Bigrams ​

回到歌词任务后,老师让 Keras 不仅使用单个 words,也使用 all bigrams。

由于 bigram 组合数量会急剧增大,不能继续只用 5000 tokens。

如果有 5000 个 unigram choices,理论上 two-word combinations 可以达到:

text
5000 * 5000 = 25 million

虽然实际数据中大多数组合不会出现,但 vocabulary 仍应适当扩大。

因此老师设置:

text
max_tokens = 20000

输出仍然使用:

text
multi-hot

八十二、Bigrams 的计算成本 ​

老师指出,bigrams、trigrams 等都会更 compute-intensive。

原因是:

  • token candidates 更多。
  • vocabulary 更大。
  • 输入 vector 更长。
  • 模型参数更多。

查看 bigram vocabulary 时:

  • 前 10 个通常仍是 single words,因为它们出现频率最高。
  • 后面可能出现 phrases,例如 your mom、your God、you shot、you hell 等。

八十三、第二个模型:20000 维输入与 Dropout ​

加入 bigrams 后,每个输入 vector 长度变成:

text
20000

第二个模型整体仍与前一个类似:

  • input shape:20000
  • dense layer
  • Dropout
  • 3 类 softmax output

新的层是:

text
dropout

老师暂时先把 dropout 当成可以插入模型的普通 layer,后面再解释。

它的用途是:

prevent overfitting。

八十四、第二个模型训练设置 ​

第二个模型 compile 设置与前一个相同。

训练时,老师为了课堂时间只运行:

text
3 epochs

他说,如果课后有兴趣,可以尝试更多 epochs,看结果是否更好。

八十五、重复运行时 Accuracy 是否会变化 ​

学生问:如果用同样的 epochs 重新运行代码,accuracy 是否会变化?

老师回答:

  • 在同一台机器上,通常会期望结果大致相同。
  • 但可能因为 hardware、device drivers 等出现细小差异。
  • 如果在同一个 notebook 中反复运行,还取决于之前执行了什么。
  • 从 fresh state 开始通常更接近,但也不一定完全一致。

这个回答延续了前几节中关于随机性和可复现性的讨论。

八十六、Bigrams 模型结果 ​

加入 bigrams 后,模型 test accuracy 达到约:

text
75%

相比 unigram Bag of Words 的:

text
72%

提升约 3 个百分点。

老师认为这个提升有意义,尤其考虑到 bigram 模型只训练了 3 epochs。

如果训练 10 epochs,可能还会更好。

八十七、歌词预测 Demo ​

老师用训练好的模型做了简单 demo。

先输入:

text
another one bites the dust

模型预测为:

text
rock

老师认为这应该是正确的。

随后学生提议:

text
Dancing Queen

来自 ABBA。

老师复制歌词后让模型预测,结果为:

text
pop

老师说明,过去两年这节课现场 demo 中学生常给 rock songs;这次得到 pop song,因此这个例子也展示了模型对不同 genre 的预测。

老师也提到,学生可以课后输入自己选择的 lyrics,观察模型会给出什么预测。

八十八、Dropout 的基本机制 ​

最后老师回到 dropout。

dropout 是一个 layer。

它接收前一层输出,然后随机把其中一些数替换为:

text
0

可以把它理解成对每个输入值 toss a coin:

  • 如果 coin 是 heads,就把该值变成 0。
  • 如果 coin 是 tails,就让该值通过。

这就是 “drop” 的含义。

八十九、Dropout 为什么能防止 Overfitting ​

老师用一种直观说法解释:

overfitting 可能来自 neurons 之间的 collusion。

也就是说,不同 neurons 可能共同利用训练数据中的 spurious correlations,从而在训练集上表现很好,但泛化较差。

dropout 随机关闭部分 neurons 或中间值,使得:

没有一个 neuron 可以稳定依赖另一个特定 neuron 一定可用。

这会迫使网络学习更稳健的表示,从而减少 overfitting。

老师说明,这是一种 game-theoretic 风格的直觉解释,不是严格数学定义。

九十、Dropout 的 Bank Story ​

老师讲了一个关于 dropout 灵感来源的故事。

据说 Jeff Hinton 曾去银行,注意到银行分行工作人员经常变动。

一种解释是,如果工作人员长期固定,可能更容易与客户形成 collusion,从而产生 fraud risk。

不断调换人员可以打破这种 collusion。

这个故事被用来类比 dropout:

  • 固定 neurons 容易形成过拟合性的相互依赖。
  • 随机让部分 neurons 不可用,可以打破这种依赖。

老师也说明,这个故事可能真实,也可能是 apocryphal。

他提到 Jeff Hinton 获得过 Turing Award,主要是因为 deep learning 相关贡献,而不是专门因为 dropout。

九十一、为什么不用 Multicollinearity 分析替代 Dropout ​

学生问:能否借鉴传统模型中的 multicollinearity 思路,更有针对性地处理 neuron 之间的相关性,而不是随机 dropout?

老师回答,问题在于 neural networks 太大。

困难包括:

  1. 每一层都可能很大,检查 layer 内或 layer 间 correlations 本身就很复杂。
  2. 即使发现相关性,下一步如何处理也不明确。
  3. 在线性回归中可以用 PCA 等方法处理,但这里是 nonlinear networks。

因此,在这种场景中,更实用的做法是:

text
dropout

它用一个简单机制一次性缓解过拟合和依赖问题。

九十二、Byte-Pair Encoding 预告 ​

老师提到,他准备了关于:

text
byte-pair encoding

的材料,但本节课时间不够。

这部分会在讲 LLMs 时再讲。

老师说明,byte-pair encoding 是一种 clever tokenization scheme,被 GPT family 等模型使用。

它能支持:

  • 保留 punctuation。
  • 保留 case。
  • 处理用户新造的 words。

这些能力解释了为什么现代 LLM 生成文本时不会受简单词表和 UNK 限制。

九十三、Hidden Layer 神经元数量如何选择 ​

最后有学生问:

hidden layer 中 neurons 数量最初如何选择?是否主要靠 trial and error?

老师回答:通常确实是 trial and error。

他在创建 Colab 时也是这样试出来的。

但这个过程可以更系统化。

九十四、KerasTuner 与 Hyperparameter Optimization ​

老师推荐:

text
KerasTuner

这是一个用于在 Keras 中做超参数搜索的 Python package。

它可以系统尝试很多配置,并且提供了较好的示例 Colabs。

这类方法属于:

text
hyperparameter optimization

可以搜索的内容包括:

  • number of neurons。
  • activation function。
  • learning rate。
  • 其他模型结构或训练参数。

老师提到,如果有机会,可能会录制一个 screen walkthrough 来演示如何使用。

九十五、本节课核心总结 ​

本节课的知识链条可以概括为:

  • NLP 的核心起点是将 text 转换成可计算的 numeric representation。
  • text in, text out 可以覆盖 classification、extraction、summarization、generation、code generation 和 question answering 等大量任务。
  • NLP 发展经历了 hand-crafted linguistic rules、statistical machine learning、RNNs 和 transformers。
  • 本课程会直接聚焦 transformers,但本节先解决文本表示问题。
  • S-T-I-E 是基础文本向量化流程:standardization、tokenization、indexing、encoding。
  • standardization 的作用是减少无意义差异、降低计算负担,并帮助模型把相同概念当作相同输入。
  • tokenization 最简单做法是 whitespace split,但它会丢失顺序、破坏复合表达,也不适用于所有语言。
  • vocabulary 是训练数据中 distinct tokens 的集合。
  • indexing 将每个 token 映射为 integer。
  • encoding 将 integer 映射为 vector。
  • one-hot encoding 简单直观,但会产生很长、很稀疏的 vectors。
  • UNK 用于表示 vocabulary 中不存在的新 token。
  • Bag of Words 将文本聚合成固定长度 vector,可以用 multi-hot 或 count encoding。
  • Bag of Words 丢失 word order,但在许多文本分类任务中仍是有效 baseline。
  • Keras TextVectorization 可以实现文本向量化,并通过 adapt 从 corpus 建立 vocabulary。
  • 歌词 genre 分类中,max_tokens = 5000 的 unigram Bag of Words 模型取得约 72% test accuracy,高于约 50% 到 55% 的 naive baseline。
  • bigrams 引入相邻词组合,部分恢复局部上下文,使结果提升到约 75%。
  • dropout 通过随机置零中间输出,降低 neurons 之间的过拟合性依赖。
  • hidden layer 大小等超参数通常需要试验,也可以用 KerasTuner 系统搜索。

最核心的思想是:

在进入 embeddings 和 transformers 之前,必须先理解文本如何从 strings 变成 vectors;Bag of Words 虽然简单,却清楚展示了 vocabulary、tokenization、encoding、input dimension、overfitting 和 context loss 等 NLP 基础问题。

最后更新于: