自然语言处理(NLP)自学教程:从符号主义到预训练大模型

本教程系统梳理自然语言处理(NLP)的演进脉络,涵盖文本预处理、分词、静态与上下文相关词表示(Word2Vec、BERT、GPT)、经典任务建模(分类、NER、机器翻译)、预训练范式(Transformer/BERT/GPT/T5)、提示工程及评测方法。强调从人工特征工程到数据驱动表示学习的范式跃迁,突出Transformer架构、掩码机制差异、微调与提示的适用场景,以及P/R/F1、BLEU等核心评测指标的技术内涵。

一句话:NLP 让机器读懂、生成人类语言。本教程是一张「自学路线图」——按学习顺序串起 6 个阶段:① 概念与范式 → ② 文本预处理 / 分词 → ③ 文本表示(从 one-hot 到词向量)→ ④ 经典任务与模型 → ⑤ 预训练时代(Transformer / BERT / GPT / T5)→ ⑥ 大模型与评测。每节配图示,含 5 个可交互演示(学习路线图浏览器 / 分词演示器 / 文本表示显微镜 / 预训练家族选择器 / 评测指标计算器,见同名 HTML 版)。学完可独立接住后续系列篇。

目录


0 · 导读:一张自学路线图

下面这条主线贯穿全篇。每一站都回答两个问题:「这一站学什么」 与 「它解决上一站的什么痛点」。

① 概念与范式 ──▶ ② 预处理·分词 ──▶ ③ 文本表示 ──▶ ④ 任务与模型 ──▶ ⑤ 预训练时代 ──▶ ⑥ 大模型·评测
  (语言不可       (切成可计算       (表示成向量       (套具体任务       (预训练统一表示   (提示+评测闭环
   直接计算)        的单元)          与相似度)          模型)              与微调)            )

[核心洞见] NLP 的演进史,就是不断把「人设计的特征」替换为「机器学到的表示」的历史。分词是人为切分单元的终点;词向量是人为设计特征的终点;预训练把「为每个任务单独设计模型」也干掉了——你只需在通用表示上微调或提示。

自测 0.1 用一句话向不懂技术的朋友解释 NLP。再想一个你手机里用到的 NLP 功能(提示:输入法联想、翻译、语音助手、垃圾短信过滤)。

演示 W1 · 学习路线图浏览器(交互,见 HTML 版)

点阶段卡片,展开该阶段的 目标 / 前置知识 / 学习产出 / 推荐动手项目。各阶段内容如下:

阶段 目标 前置 学习产出 动手项目
① 概念与范式 理解 NLP 难在哪、三范式如何演进 高中数学 + 编程基础 能画自学路线图、解释为何需要分词 用一句话向非技术朋友讲清 NLP
② 预处理·分词 把文本切成 token,理解 subword ① 能手算 BPE 合并、说清 OOV 权衡 用 jieba / sentencepiece 切一段中文并分析
③ 文本表示 从 one-hot 到上下文向量 ② + 线性代数直觉 说清分布式假设、词向量多义局限 用 gensim 训 mini Word2Vec 看类比性质
④ 任务与模型 分类/标注/翻译的模型套路 ③ 能为任务选模型、讲清注意力 用 sklearn 做情感分类 baseline
⑤ 预训练时代 Transformer / BERT / GPT / T5 ④ + 反向传播 能解释三家族结构与选型 用 HuggingFace 微调一个 BERT 分类
⑥ 大模型·评测 提示工程、评测闭环 ⑤ 会写 prompt、会选评测指标 做一个 RAG 小 demo 并写评测

1 · 什么是 NLP:让机器读懂、生成人类语言

1.1 学科定位

NLP(Natural Language Processing)是人工智能的分支,目标让计算机理解(分类、抽取、问答)与生成(翻译、摘要、对话)人类语言。它站在三学科交叉口:

学科 贡献给 NLP 的东西 例子
语言学 语言的层次结构:音系→词法→句法→语义→语用 主谓宾、词性、歧义
计算机科学 算法、数据结构、系统(分词器、索引、推理引擎) 字符串算法、编译思想
机器学习 / 深度学习 从数据中自动学规律与表示 词向量、Transformer

1.2 为什么 NLP 这么难

  • 歧义性:一词多义(“苹果”=水果 or 公司)、句法歧义(“咬死猎人的狗”=“(咬死猎人)的狗” vs “咬死(猎人的狗)”)。
  • 组合性:有限词能组成无限多句子,无法穷举。
  • 语境依赖:同一句话在不同上下文含义相反(反讽、省略、指代)。
  • 表达 ≠ 意图:字面意思之下还有言外之意(“今天真冷”=关窗请求)。
  • 跨语言 / 跨领域:同一概念在不同语言、不同专业语料里形态迥异。

注意 贯穿全篇的例句:「苹果公司发布了新手机。」 在 §2 它要被切成词,在 §3 里 “苹果” 的向量要随语境(水果 vs 公司)变化,在 §5 里 BERT 靠双向上下文同时看见左右判断它是公司,而不是水果。

1.3 三范式简史:每种方法都死在它的「命门」上

范式 年代 核心思路 命门(为什么被取代)
符号主义(规则 + 词典) 1950s–80s 人写规则(“若 X 则 Y”)、专家系统、句法树 规则爆炸、无法覆盖例外、换领域要从头写(brittle)
统计机器学习(特征 + 模型) 1990s–2010s 语料 + 手工特征 + HMM/CRF/SVM/朴素贝叶斯 特征靠人设计,质量决定上限;语义表示仍稀疏
神经网络 / 表示学习(端到端) 2013– 表示自己学(词向量→上下文向量)、预训练+微调 吃数据吃算力;可解释性下降、幻觉

[学习建议] 三范式不是"旧的没用"。正则化、特征思想、CRF 的序列约束在今天的模型里仍以不同形式存在。理解旧范式,才能看懂新模型"省掉了哪一步"。

1.4 一个任务的两种范式对照

以「判断一句评论是正面 / 负面」为例:

符号主义:IF 含"好/喜欢/赞" THEN 正面;IF 含"差/烂/退" THEN 负面 …(规则永远写不完)
统计    :人工设计特征(是否含褒义词、否定词数、程度副词)→ 丢给 SVM 分类
神经    :文本 → 词向量 → 神经网络 → 直接学"词 → 情感"的映射,特征自己长出来

自测 1.1 为什么"给每个词写规则"在自然语言上行不通?举一个你日常说话里"字面意思 ≠ 真实意思"的例子。
自测 1.2 三范式里,哪一阶段开始"不再需要人工设计特征"?它的代价是什么?


2 · 文本预处理与分词:先把语言切成可计算的单元

2.1 为什么要先分词

模型吃的是离散符号序列,不是连续字符串。第一步必须把文本切成「词 / 子词 / 字」这样的基本单元(token)。但「词的边界」远非理所当然:

语言 边界难点 例子
英文 空格≠词边界;缩写、复合词、标点附着 don't、New York、state-of-the-art
中文 无空格;词长不固定;歧义切分 苹果公司发布了新手机 → 苹果/公司/发布/了/新/手机?

2.2 分词粒度:一个旋钮控制三件事

粒度 词表大小 序列长度 语义完整度 OOV 风险
字 / 字符 极小(几千) 很长 切碎,需模型自己拼 几乎无
词 大(几十万~百万) 短 完整 高(新词/专有名词)
subword(折中) 中(几千~几万) 中 部分保留 低

[关键权衡] 词表越大 → 序列越短(算力省)、语义越完整,但 OOV 越多、显存越爆;词表越小 → 序列越长、OOV 越少,但模型要自己从字拼出词意。subword(BPE/WordPiece 等)用一个旋钮同时控制这三者(词表账详见系列篇 llm-deep-dive Q2)。

2.3 英文:正则切分 + BPE 合并

BPE(Byte-Pair Encoding)从一个字符级词表出发,反复把语料中出现最频繁、且相邻的字符对合并成新单元,直到达到目标词表大小。它是"从字长出来、按需合并"的自适应过程。

2.4 中文:词典匹配 vs 分词模型

  • 基于词典:正向/逆向/双向最大匹配(如"苹果公司"优先成词,而非"苹果/公司")。简单快,但依赖词典、抗歧义弱。
  • 基于模型:序列标注(每个字标"词首/词中/词尾/单字")+ HMM/CRF/BiLSTM/Transformer,能处理未登录词与歧义。

2.5 Subword 四算法速查

算法 合并依据 代表
深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

reset2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值