自然语言处理学习路线:从词向量到Transformer的NLP进阶笔记

📅 发布时间:2026/9/1 2:28:41
自然语言处理学习路线:从词向量到Transformer的NLP进阶笔记 最近系统刷完了吴恩达老师的 NLP 系列课程结合平时在做文本分类、信息抽取、评论情感分析等项目中的落地经验我整理了一份从入门到进阶的 NLP 学习笔记。很多同学学 NLP 时会遇到同一个困惑资料太多不知道从哪里开始要么直接上手 HuggingFace 跑模型原理完全不理解要么只啃理论代码能力跟不上。吴恩达这套 NLP 课程的优势在于它把整个知识体系拆成了从传统方法到深度学习的递进路线每个模块都配有可运行的 Python 实验非常适合用来建立完整的 NLP 知识骨架。这篇文章会把课程的骨架、核心算法、配套代码和常见的“坑位”一起串起来。无论你是刚接触自然语言处理的新手还是已经在做 NLP 项目但缺少系统梳理的开发者都能从里面找到需要的内容。1. NLP 是什么为什么需要系统学习1.1 NLP 要解决的核心问题自然语言处理Natural Language Processing简称 NLP是让计算机理解、处理和生成人类语言的技术。它不是一个单一算法而是一整个技术栈覆盖了很多子任务文本分类垃圾邮件识别、评论情感分析、新闻分类。信息抽取从文本中抽取实体、关系、事件。机器翻译中英翻译、多语言翻译。问答系统基于文档的问答、知识库问答。文本生成摘要、对话、写作辅助。语音识别后的文本处理分词、纠错、语义理解。这些任务有一个共同难点人类语言充满歧义、省略、指代和上下文依赖。比如“苹果好吃”和“苹果发布了新手机”同一个词在不同的上下文里含义完全不同。NLP 的核心工作就是找到一种方式让模型能够捕捉这些上下文信息。1.2 规则、统计与深度学习的演进NLP 的技术路线大体经历了三个阶段阶段代表方法特点规则时代人工编写语法规则、词典可解释性强但覆盖不了语言多样性统计时代N-gram、HMM、CRF、SVM、朴素贝叶斯靠人工设计特征泛化能力有限深度学习时代RNN、LSTM、Seq2Seq、Transformer、BERT自动学习特征效果大幅提升吴恩达这套 NLP 课程的设计思路恰好就是按照这个演进顺序展开的。它不是一上来就讲大模型而是先从词向量、朴素贝叶斯、逻辑回归这些基础组件讲起再一步步过渡到 RNN、注意力机制、Transformer。这种讲法最大的好处是你能清楚知道每个模型解决什么问题、为什么后来会被新模型替代。1.3 为什么推荐跟着课程体系走一遍现在很多初学者一上来就微调 BERT虽然能用但遇到效果不好时往往不知道如何优化因为不清楚模型内部发生什么。而吴恩达课程强调“用 Python 从零实现关键算法”比如手写逻辑回归、手写反向传播、实现注意力得分计算。这些基本功在工程排查中非常有用。另外这套课程覆盖了 NLP 开发全链路数据预处理、特征表示、模型训练、评估调优不是只讲论文模型。跟着走一遍对项目落地也很有帮助。2. 课程体系拆解与学习路线规划2.1 吴恩达 NLP 系列课程的主要内容这里以 deeplearning.ai 的自然语言处理专项课程为参考整个体系通常被划分为四个大的模块文本分类与向量空间学习词频表示、TF-IDF、词向量、余弦相似度以及朴素贝叶斯、逻辑回归在文本分类中的应用。概率模型与语言模型学习 N-gram 语言模型、概率计算、文本生成以及词性标注、隐马尔可夫模型HMM等经典序列标注方法。序列模型学习 RNN、LSTM、GRU 的原理与实现掌握如何用序列模型处理文本生成、命名实体识别等任务。注意力模型与 Transformer学习 Seq2Seq 中的注意力机制、Transformer 架构并进一步理解 BERT 等预训练语言模型的应用。不同版本课程在章节安排上可能略有差异但主线基本一致。学习时不用纠结版本号重点是抓住这条“从词向量到注意力机制”的主线。2.2 适合哪些人学习刚入门 NLP 的同学课程从最基础的文本表示讲起不需要很强的机器学习基础。会用框架但不懂原理的开发者课程里的手写实现可以帮你补上原理短板。准备做 NLP 工程项目的工程师文本预处理、模型评估、误差分析等章节贴近真实项目。如果你已经熟练使用 HuggingFace 微调各种大模型那么这套课程的前半部分可以快速过一遍重点看注意力机制和 Transformer 的原理推导。2.3 推荐的学习节奏以“边看边写代码”为原则这里给出一份 12 周的学习计划表你可以根据实际情况调整周次学习内容动手任务第 1 周文本表示词袋、TF-IDF用 sklearn 实现文本向量化第 2 周朴素贝叶斯、逻辑回归实现一个垃圾邮件分类器第 3 周词向量与 Word2Vec训练小型中文词向量并做相似度分析第 4 周向量空间与相似度检索实现一个简单问答检索第 5 周N-gram 语言模型用 N-gram 生成中文短句第 6 周HMM 与词性标注完成一个简单词性标注实验第 7 周RNN 原理与代码用 NumPy 实现前向传播第 8 周LSTM、GRU用 Keras 完成文本分类第 9 周Seq2Seq 模型实现日期格式转换等小任务第 10 周注意力机制手动实现注意力得分计算第 11 周Transformer 架构理解多头自注意力代码第 12 周预训练模型 BERT使用 HuggingFace 微调一个分类模型看课和写代码的时间最好保持 1:2甚至写代码的时间更多。只看不写两周后基本会忘掉。3. 核心知识点拆解从词向量到注意力这一节把课程中最核心的内容做一次提炼每部分都会解释原理、适用场景和常见误区。3.1 文本表示从词袋到词向量计算机无法直接处理文字所以第一步是把文本变成数字。最朴素的方式是词袋模型Bag of Words统计每个词在文档中出现的次数。忽略词序只保留词频信息。# 文件路径demo_bow.py from sklearn.feature_extraction.text import CountVectorizer corpus [ 我喜欢自然语言处理, 自然语言处理是人工智能的方向 ] vectorizer CountVectorizer(token_patternr(?u)\b\w\b) X vectorizer.fit_transform(corpus) print(vectorizer.get_feature_names_out()) print(X.toarray())输出结果中每一行代表一个文档每一列代表一个词值是该词在文档中出现的次数。但词袋模型有两个明显问题高频词如“的”“是”会被赋予过高的权重但它们往往没有实际区分度。丢失了词序信息“我喜欢你”和“你喜欢我”在词袋表示下完全相同。为了解决第一个问题出现了 TF-IDF。它通过“词频”乘以“逆文档频率”来降低普遍出现词的权重。为了解决第二个问题就需要引入词向量。3.2 Word2Vec 与词向量的核心思想Word2Vec 的核心思想是一个词的含义由它周围的词决定。也就是“分布假说”。Word2Vec 有两种训练方式CBOW用上下文词预测中心词。Skip-gram用中心词预测上下文词。训练完成后每个词对应一个低维稠密向量。语义相近的词在向量空间中距离更近“国王 - 男人 女人 ≈ 女王”这类类比关系也往往能成立。# 文件路径demo_word2vec.py from gensim.models import Word2Vec sentences [ [自然语言处理, 是, 人工智能, 的, 重要, 方向], [我, 喜欢, 研究, 自然语言处理], [词向量, 是, 自然语言处理, 的, 基础] ] # 按实际 gensim 版本调整参数 model Word2Vec(sentences, vector_size64, window3, min_count1, sg1) vector model.wv[自然语言处理] print(vector.shape) similar_words model.wv.most_similar(自然语言处理, topn3) print(similar_words)这里vector_size是词向量维度window是上下文窗口大小sg1表示使用 Skip-gram 方式训练。在项目里如果语料只有几万条词向量效果一般不会太好如果语料达到百万级词向量的语义效果会明显提升。3.3 RNN 与 LSTM处理序列信息词向量解决了词的表示问题但没有解决“顺序”问题。对于“我不喜欢这家餐厅”和“这家餐厅我不喜欢”词袋或词向量平均都无法体现否定词对情感的影响。RNN循环神经网络让模型在处理当前词时把前一个时刻的隐藏状态一起输入进来。这样模型就具备了“记忆”能力。RNN 的数学表达可以简化为h_t tanh(W_h * h_{t-1} W_x * x_t b)其中h_t是当前时刻的隐藏状态x_t是当前时刻的输入。但标准 RNN 存在梯度消失问题难以捕捉长距离依赖。LSTM 通过引入“门控机制”来解决这个问题遗忘门决定记住多少旧信息。输入门决定把多少新信息写入记忆。输出门决定输出多少记忆信息。在实际项目中LSTM 是处理序列数据的稳妥选择但它的训练速度比 RNN 慢而且很难并行化。这也是后来 Transformer 兴起的原因之一。3.4 注意力机制与 TransformerSeq2Seq 模型在编码器和解码器之间只通过一个固定长度的向量传递信息。句子太长时这个向量装不下所有信息效果会下降。注意力机制的核心改进是解码每个词时让模型“回头看”编码器输出的所有隐藏状态并按照相关性加权求和。注意力得分的计算通常有几种方式点积注意力score q · k缩放点积注意力score q · k / sqrt(d_k)加性注意力score W * tanh(q k)Transformer 则更进一步完全抛弃了循环结构使用“自注意力”机制来处理序列。自注意力的意思是句子中的每个词都与句子中的其他词计算相关性权重从而直接建模全局依赖。# 文件路径demo_attention.py import numpy as np def scaled_dot_product_attention(query, key, value): d_k key.shape[-1] scores np.dot(query, key.T) / np.sqrt(d_k) weights np.exp(scores - np.max(scores, axis-1, keepdimsTrue)) weights / weights.sum(axis-1, keepdimsTrue) return np.dot(weights, value) # 模拟三个词的向量表示 q np.random.randn(3, 8) k np.random.randn(3, 8) v np.random.randn(3, 8) output scaled_dot_product_attention(q, k, v) print(output.shape)在吴恩达课程中这部分会有更完整的推导。理解注意力机制之后再学习 BERT、GPT 等预训练模型就容易很多它们本质上都是基于 Transformer 的不同训练目标和结构变体。4. 完整实战从中文语料清洗到情感分类前面讲了大量概念下面我们把知识点串起来完成一个完整的 NLP 项目。项目目标训练一个中文文本情感分类模型流程覆盖“语料准备 → 数据清洗 → 特征表示 → 模型训练 → 效果评估”。4.1 项目结构与数据准备先创建项目目录nlp_sentiment_demo/ ├── data/ │ ├── raw.txt ├── src/ │ ├── clean.py │ ├── train_traditional.py │ ├── train_lstm.py ├── requirements.txt在requirements.txt中写入依赖jieba0.42.1 scikit-learn1.3.0 pandas2.0.0 tensorflow2.13.0注意依赖版本需要结合你的 Python 环境调整这里以示例环境为准。如果安装的是更高版本API 基本兼容但个别参数可能需要微调。为了方便演示这里使用一段很小的示例数据不要期待它达到生产级效果。真实项目中数据量至少要在几万条以上。# 文件路径src/clean.py import re import jieba raw_texts [ (这个电影太精彩了演员演技在线强烈推荐, 1), (剧情拖沓看了半小时就想睡觉, 0), (画面很美但故事逻辑有很大问题, 0), (非常喜欢这种轻松搞笑的风格, 1), (一般般没有宣传中那么好, 0), ] def clean_text(text: str) - str: # 只保留中文字符和英文字母 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9], , str(text)) # 分词并用空格连接 words jieba.lcut(text) return .join(words) def build_dataset(): texts, labels [], [] for text, label in raw_texts: texts.append(clean_text(text)) labels.append(label) return texts, labels if __name__ __main__: texts, labels build_dataset() for t, l in zip(texts, labels): print(t, -, l)这里做了两件事正则清洗去掉标点符号、特殊字符避免噪声进入模型。中文分词jieba 把句子切成词方便后续向量化。4.2 使用 TF-IDF 朴素贝叶斯搭建基线模型第一个模型选择逻辑回归或朴素贝叶斯。这类模型训练快、可解释性强适合作为项目的 baseline。后续如果深度学习模型效果不理想也可以先回到这个基线做对比。# 文件路径src/train_traditional.py from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import Pipeline from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report from clean import build_dataset texts, labels build_dataset() X_train, X_test, y_train, y_test train_test_split( texts, labels, test_size0.2, random_state42, stratifylabels ) pipeline Pipeline([ (tfidf, TfidfVectorizer(analyzerchar, ngram_range(1, 2))), (clf, MultinomialNB()), ]) pipeline.fit(X_train, y_train) y_pred pipeline.predict(X_test) print(classification_report(y_test, y_pred))这里有一个细节analyzerchar表示按字符级别做向量化ngram_range(1, 2)表示同时保留单个字符和相邻两个字符的信息。在中文短文本任务里字符级别的 n-gram 通常比纯词级别更稳定因为它不会受到分词错误的干扰。4.3 使用 Embedding LSTM 搭建深度模型基线模型跑通之后再用 LSTM 做一版深度模型体验一下从“特征工程”到“自动特征学习”的转变。# 文件路径src/train_lstm.py from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, LSTM, Dense from sklearn.model_selection import train_test_split from clean import build_dataset texts, labels build_dataset() X_train, X_test, y_train, y_test train_test_split( texts, labels, test_size0.2, random_state42, stratifylabels ) VOCAB_SIZE 1000 MAX_LEN 20 EMBED_DIM 64 tokenizer Tokenizer(num_wordsVOCAB_SIZE) tokenizer.fit_on_texts(X_train) X_train_seq tokenizer.texts_to_sequences(X_train) X_test_seq tokenizer.texts_to_sequences(X_test) X_train_pad pad_sequences(X_train_seq, maxlenMAX_LEN, paddingpost) X_test_pad pad_sequences(X_test_seq, maxlenMAX_LEN, paddingpost) model Sequential([ Embedding(input_dimVOCAB_SIZE, output_dimEMBED_DIM, input_lengthMAX_LEN), LSTM(units32), Dense(units1, activationsigmoid) ]) model.compile( optimizeradam, lossbinary_crossentropy, metrics[accuracy] ) model.fit( X_train_pad, y_train, epochs10, batch_size16, validation_split0.2, verbose1 ) loss, acc model.evaluate(X_test_pad, y_test, verbose0) print(fTest accuracy: {acc:.4f})这个代码里有几个容易出错的地方Tokenizer的num_words并不是“实际词典大小”而是“保留最高频词的数量”。设置太小时低频词会被丢弃。pad_sequences的paddingpost表示不到最大长度的序列在后面补 0。Embedding 层接收的是词的索引不是词向量。索引 0 通常留给 padding所以词典大小要预留一个位置。4.4 模型评估与预测评估不能只看准确率。当样本不平衡时准确率会骗人。比如 95% 的样本都是负样本模型全预测为负样本也能有 95% 的准确率。所以分类任务至少要同时看精确率、召回率和 F1。# 继续在 train_lstm.py 中追加 import numpy as np probabilities model.predict(X_test_pad) predictions (probabilities 0.5).astype(int) from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score print(fAccuracy: {accuracy_score(y_test, predictions):.4f}) print(fPrecision: {precision_score(y_test, predictions):.4f}) print(fRecall: {recall_score(y_test, predictions):.4f}) print(fF1: {f1_score(y_test, predictions):.4f})如果出现“准确率高但召回率低”的情况通常表示模型偏向预测多数类需要调整阈值或使用加权损失函数。4.5 预测一条新样本模型训练完成后可以封装一个简单预测函数# 文件路径src/predict.py import re import jieba from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing.sequence import pad_sequences import pickle def preprocess_new_text(text: str) - str: text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9], , str(text)) return .join(jieba.lcut(text)) def predict_sentiment(model_path, tokenizer_path, text): model load_model(model_path) with open(tokenizer_path, rb) as f: tokenizer pickle.load(f) clean preprocess_new_text(text) seq tokenizer.texts_to_sequences([clean]) padded pad_sequences(seq, maxlen20, paddingpost) prob model.predict(padded)[0][0] return prob if __name__ __main__: result predict_sentiment( sentiment_model.h5, tokenizer.pkl, 电影还不错但结局有点仓促 ) print(fPositive probability: {result:.4f})这个函数展示了真实工程中常用的模型部署方式把模型和 Tokenizer 序列化保存预测时重新加载。注意Tokenizer必须在训练集上 fit不能在预测时才新建。5. 常见问题与排查思路5.1 高频问题对照表问题现象常见原因解决思路中文文本向量化结果全是 0没有正确分词或词表与文本不匹配先打印预处理后的文本确认分词结果模型准确率很低数据量太少 / 类别不平衡 / 数据噪声大扩充数据检查样本分布清洗数据LSTM 训练很慢序列过长、Embedding 维度太高限制 max_len减小 embedding 维度模型过拟合数据量小、模型参数多、训练轮数多增加 dropout减小 LSTM 隐层单元使用早停测试集效果好线上效果差训练集和线上数据分布不一致采集更多线上真实数据做领域适配出现 out of vocabulary 词词典太小或者使用按词切分设置更大词表或改用字符级特征预测结果全是某一类样本不平衡 / 阈值设置不合理调整阈值使用 class_weight5.2 一个典型问题排查过程比如训练完成后发现所有测试样本都被预测为“正向”。排查思路如下检查 labels 是否打错正向和负向的 label 是否颠倒。打印验证集上的预测概率分布看模型是否输出接近 0.5 的值。统计训练集中正负样本比例。如果正样本占 90%模型很可能学成“无脑预测正类”。在model.fit中加入class_weight给少数类更高权重。如果问题依旧回到传统模型用 TF-IDF 逻辑回归训练观察特征权重是否合理。6. 最佳实践与工程建议6.1 数据质量优先于模型复杂度做 NLP 项目时数据决定效果上限模型只是逼近这个上限。课程里常见的是处理好的干净语料但生产环境里 80% 的时间都要花在数据上。具体来说要重视以下几步去重重复样本会导致训练集和验证集重叠评估分数虚高。清洗统一大小写、去特殊字符、处理 emoji 和 URL。标签一致性检查人工抽检 100 条标注计算标注一致性。切分策略按时间切分或按用户切分避免数据泄露。6.2 构建高质量中文 NLP 语料库中文语料库构建有几个容易踩坑的点分词不只是“把句子切成词”。领域不同词典差异很大。金融文本里的“多头”“空头”和日常用语含义完全不一样。不要盲目使用网上下载的停用词表很多业务关键词会被误删。如果做实体识别标注规范比标注数量更重要。标注不一致会直接导致模型学错。一个常见的清洗流程是原始数据 → 去HTML标签 → 去URL → 去重复标点。繁体转简体。根据业务规则去掉无效字段。人工抽检记录清洗规则。切分训练/验证/测试集。6.3 模型选型建议不同任务适合不同模型不必一上来就上大模型场景推荐方案短文本分类、垃圾过滤TF-IDF 逻辑回归 / 朴素贝叶斯中等规模数据集上的序列标注BiLSTM CRF大规模文本理解预训练模型微调如 BERT 系列长文本分类分段处理 模型集成或直接使用长文本模型低资源场景数据增强、预训练模型 PEFT 微调其实很多时候用朴素贝叶斯、逻辑回归就能达到生产可用效果。直接上大模型反而会引入部署复杂度和推理成本。6.4 训练与评估注意事项设定固定随机种子保证实验可复现。使用验证集做模型选择测试集只能评估一次。保存每次实验的配置和评估结果方便回溯。深度学习模型的初始学习率非常重要。可以先跑 10 个 batch 观察 loss 变化再调整策略。文本分类中如果类别差异大优先关注 macro-F1而不是准确率。7. 总结与下一步学习路线这套课程学下来你至少应该掌握以下能力理解文本从字符到向量的完整转换过程。掌握朴素贝叶斯、逻辑回归在 NLP 中的应用。理解 RNN、LSTM 的动机和局限。理解注意力机制和 Transformer 的基本原理。能独立完成一个包含数据清洗、模型训练、评估的中文 NLP 小项目。如果这些目标已经达成下一步可以沿着两个方向继续深入预训练模型方向学习 HuggingFace Transformers 库掌握 BERT 微调、提示学习、LoRA 等高效微调方法。工程落地方向学习模型部署、推理优化、数据回流、在线学习了解模型上线后的监控与迭代闭环。如果还想补充理论深度也可以配合《动手学深度学习》中的 NLP 章节一起看。吴恩达课程的代码风格偏算法实现而工程项目更考验数据清洗和调优能力两者结合效果最好。NLP 是一个典型的“入门容易、精通难”的领域。跟着课程体系走一遍再亲手完成一两个完整的实战项目遇到问题能自己定位根因这时候才算真正入了门。建议收藏这份笔记学习过程中随时回来对照知识点查漏补缺。