自然语言处理01 - AIE54 Day13学习笔记
自然语言处理第一天学习内容,包括数据类型概述、文本预处理、向量化技术、词嵌入和循环神经网络
自然语言处理01 - AIE54 Day13学习笔记
学习日期:2024-08-16
主讲老师:李晓华
课时:6
文档来源:day13-自然语言处理01.pdf
课程关键词
数据类型 | 自然语言处理概述 | 文本预处理 | 向量化技术 | 循环神经网络 | LSTM
🎯 第一部分:数据类型与自然语言处理概述
1.1 三类数据的本质特征
核心分类:从数据科学视角,所有数据可以分为三大类,每类数据都有其特定的依赖关系和处理方法。
三种数据类型:
-
表格类数据(Tabular Data)
- 特征:零维信息,各特征互相独立
- 适用算法:机器学习和全连接网络
- 示例:年龄、收入、学历等结构化数据
-
图像类数据(Image Data)
- 特征:二维信息,在两个方向上互相依赖
- 适用算法:卷积神经网络(CNN)
- 示例:224×224×3的RGB图像
-
时序类数据(Time Series Data)
- 特征:一维信息,在时间方向上互相依赖
- 适用算法:循环神经网络(RNN)
- 示例:文本序列、时间序列数据
1.2 文本数据的特殊性
重要提示:文本属于时序类数据,具有强烈的序列依赖性,词语的顺序直接影响语义理解。
import numpy as np import pandas as pd # 表格数据示例 - 各特征独立 tabular_data = pd.DataFrame({ '年龄': [25, 30, 35], '收入': [50000, 60000, 70000], '学历': [1, 2, 3] # 编码后的类别特征 }) # 图像数据示例 - 像素间有空间依赖 image_data = np.random.rand(224, 224, 3) # 高度×宽度×通道 # 文本数据示例 - 词语间有时序依赖 text_sequence = ["我", "爱", "自然", "语言", "处理"] print("文本序列的时序依赖性:", text_sequence)
应用场景:理解数据类型是选择合适算法的基础,文本处理需要考虑序列信息的保持。
1.3 自然语言处理的数据科学本质
核心思想:
- 数据驱动:抛开人为制定的语法规则,让数据本身来决策
- 统计视角:从统计学角度而非语言学角度分析文本
- 机器学习:通过大量数据训练模型,发现语言的内在规律
数据驱动的示例:通过统计而非规则判断词语重要性
from collections import Counter def analyze_word_importance(texts): """通过词频统计分析词语重要性""" all_words = [] for text in texts: all_words.extend(text.split()) word_freq = Counter(all_words) print("词频统计结果:") for word, freq in word_freq.most_common(10): print(f"{word}: {freq} 次") return word_freq # 示例文本 sample_texts = [ "酒店服务很好 房间很干净", "酒店位置不错 服务态度好", "房间设施齐全 服务周到" ] word_importance = analyze_word_importance(sample_texts)
🔧 第二部分:自然语言处理通用流程
2.1 文本预处理流程
完整流程:
- 文本输入 → 2. 分词 → 3. 编码 → 4. 向量化
详细步骤解析:
import jieba import pandas as pd from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer # 步骤1: 文本输入(各种形式的文本) raw_texts = [ "你好吗?", "2H2 + O2 = 2H2O", "今天天气很好" ] # 步骤2: 分词 - 把文本拆成最小语义单元 def tokenize_text(text): """使用jieba进行中文分词""" return jieba.lcut(text) tokenized_texts = [tokenize_text(text) for text in raw_texts] print("分词结果:", tokenized_texts) # 步骤3: 编码 - 构建词汇表并分配ID def build_vocabulary(tokenized_texts): """构建全局词汇表""" # 添加特殊标记 vocab = {"<UNK>", "<PAD>", "<SOS>", "<EOS>"} for tokens in tokenized_texts: vocab.update(tokens) # 创建双向映射 token2idx = {token: idx for idx, token in enumerate(vocab)} idx2token = {idx: token for token, idx in token2idx.items()} return token2idx, idx2token token2idx, idx2token = build_vocabulary(tokenized_texts) print(f"词汇表大小: {len(token2idx)}") print("示例映射:", {k: v for k, v in list(token2idx.items())[:5]})
关键概念:
- 全局字典:每个词都出现且只出现一次,分配唯一ID
- 特殊标记:
<UNK>(未知词)、<PAD>(填充)、<SOS>(句首)、<EOS>(句尾)
2.2 分词策略与原则
核心原则:
重要:不要从语法角度考虑分词的合理性,要从统计的视角看待分词问题!
两种主要分词方法:
import jieba def character_level_tokenize(text): """字符级分词 - 最细粒度""" return list(text) def word_level_tokenize(text): """词级分词 - 使用jieba""" return jieba.lcut(text) # 示例对比 sample_text = "北京大学的学生很优秀" char_tokens = character_level_tokenize(sample_text) word_tokens = word_level_tokenize(sample_text) print("字符级分词:", char_tokens) print("词级分词:", word_tokens) print(f"字符级词汇量: {len(set(char_tokens))}") print(f"词级词汇量: {len(set(word_tokens))}")
分词方法比较:
- 字符级:词汇量小,但语义信息有限
- 词级:语义信息丰富,但词汇量大,存在OOV问题
🎯 第三部分:文本向量化技术
3.1 从非结构化到结构化数据
核心挑战:
- 文本特点:行和列都无法对齐,不能直接套用传统机器学习算法
- 解决思路:通过向量化技术将文本转换为固定长度的数值向量
结构化转换原理:
import numpy as np from sklearn.feature_extraction.text import CountVectorizer # 原始文本数据(非结构化) texts = [ "酒店 服务 很好", "房间 很 干净 服务 态度 好", "位置 不错 房间 设施 齐全" ] print("原始文本长度不一:") for i, text in enumerate(texts): print(f"文本{i+1}: {len(text.split())}个词")
3.2 Count向量化(词袋模型)
定义:统计每个词在文档中出现的次数,形成固定长度的特征向量。
核心思想:
- 计数逻辑:重要的事情说三遍,重复越多越重要
- 稀疏矩阵:大量零值,少量有效数字
- 词袋模型:丢失词语顺序信息,只保留词频信息
from sklearn.feature_extraction.text import CountVectorizer import pandas as pd def create_count_vectors(texts): """创建Count向量化""" # 初始化向量化器 vectorizer = CountVectorizer( token_pattern=r'\b\w+\b', # 词汇提取模式 lowercase=False, # 保持原始大小写 max_features=1000 # 最大特征数 ) # 拟合并转换文本 count_matrix = vectorizer.fit_transform(texts) feature_names = vectorizer.get_feature_names_out() # 转换为DataFrame便于查看 count_df = pd.DataFrame( count_matrix.toarray(), columns=feature_names, index=[f'文档{i+1}' for i in range(len(texts))] ) return count_df, vectorizer # 示例应用 sample_texts = [ "酒店 服务 很好 很好", "房间 干净 服务 态度", "位置 很好 设施 齐全" ] count_df, count_vectorizer = create_count_vectors(sample_texts) print("Count向量化结果:") print(count_df) # 查看稀疏性 total_elements = count_df.size zero_elements = (count_df == 0).sum().sum() sparsity = zero_elements / total_elements * 100 print(f"\n稀疏度: {sparsity:.2f}%")
特点分析:
- 优点:简单直观,计算效率高
- 缺点:忽略词序,无法区分词语重要性
3.3 TF-IDF向量化
定义:Term Frequency-Inverse Document Frequency,综合考虑词频和逆文档频率。
数学原理:
TF-IDF(t, d) = TF(t, d) × IDF(t)
其中:
- TF(t, d) = 词t在文档d中的出现次数 / 文档d的总词数
- IDF(t) = log(文档总数 / 包含词t的文档数)
核心思想:
- TF:词在当前文档中的重要性
- IDF:词在整个语料库中的稀有程度
- 平衡:既考虑局部重要性,又考虑全局稀有性
from sklearn.feature_extraction.text import TfidfVectorizer import numpy as np def create_tfidf_vectors(texts): """创建TF-IDF向量""" # 初始化TF-IDF向量化器 tfidf_vectorizer = TfidfVectorizer( token_pattern=r'\b\w+\b', lowercase=False, max_features=1000, smooth_idf=True, # 平滑IDF use_idf=True # 使用IDF权重 ) # 拟合并转换 tfidf_matrix = tfidf_vectorizer.fit_transform(texts) feature_names = tfidf_vectorizer.get_feature_names_out() # 创建DataFrame tfidf_df = pd.DataFrame( tfidf_matrix.toarray(), columns=feature_names, index=[f'文档{i+1}' for i in range(len(texts))] ) return tfidf_df, tfidf_vectorizer # 示例:比较Count和TF-IDF的差异 extended_texts = [ "酒店 服务 很好 很好 很好", # "很好"出现3次 "房间 干净 服务 态度 很好", # "很好"出现1次 "位置 很好 设施 齐全 服务", # "很好"出现1次 "价格 合理 环境 很好 推荐" # "很好"出现1次 ] # Count向量化 count_df, _ = create_count_vectors(extended_texts) print("Count向量化 - '很好'的权重:") print(count_df['很好']) # TF-IDF向量化 tfidf_df, _ = create_tfidf_vectors(extended_texts) print("\nTF-IDF向量化 - '很好'的权重:") print(tfidf_df['很好'].round(4)) print("\n分析:TF-IDF降低了高频常见词的权重")
应用场景:文档分类、信息检索、关键词提取等需要考虑词语重要性的任务。
🧠 第四部分:词嵌入(Word Embedding)
4.1 嵌入层的概念与实现
定义:将离散的词汇索引映射到连续的高维向量空间,每个词用一个稠密向量表示。
核心优势:
- 语义相似性:相似词语在向量空间中距离较近
- 稠密表示:相比稀疏的one-hot编码,信息密度更高
- 可学习性:通过训练自动学习词语的语义表示
import torch import torch.nn as nn import numpy as np def create_embedding_layer(vocab_size, embedding_dim, padding_idx=None): """创建词嵌入层""" embedding = nn.Embedding( num_embeddings=vocab_size, # 词汇表大小 embedding_dim=embedding_dim, # 嵌入维度 padding_idx=padding_idx # 填充词索引 ) return embedding # 示例:构建嵌入层 vocab_size = 10000 # 词汇表大小 embedding_dim = 300 # 嵌入维度(常用值:100, 200, 300) padding_idx = 0 # 填充词索引 embed_layer = create_embedding_layer(vocab_size, embedding_dim, padding_idx) print(f"嵌入矩阵形状: {embed_layer.weight.shape}") print(f"参数数量: {embed_layer.weight.numel():,}") # 示例输入:批量句子的词索引 batch_sentences = torch.tensor([ [1, 45, 123, 678, 2], # 句子1 [3, 89, 234, 567, 0], # 句子2(最后一个是填充) [12, 56, 789, 0, 0] # 句子3(后两个是填充) ], dtype=torch.long) print(f"输入形状: {batch_sentences.shape}") # [batch_size, seq_len] # 通过嵌入层 embedded = embed_layer(batch_sentences) print(f"输出形状: {embedded.shape}") # [batch_size, seq_len, embedding_dim] # 查看填充词的嵌入(应该是零向量) print(f"\n填充词嵌入的前5维: {embedded[1, -1, :5]}")
重要参数解析:
- num_embeddings:词汇表中词的总数
- embedding_dim:每个词的向量维度
- padding_idx:填充词的索引,其嵌入向量保持为零
4.2 嵌入层的训练机制
训练原理:
- 查找表:嵌入层本质上是一个可学习的查找表(Look-up Table)
- 反向传播:通过下游任务的损失函数更新嵌入权重
- 语义学习:相似上下文中出现的词会学到相似的表示
def demonstrate_embedding_training(): """演示嵌入层的训练过程""" # 创建简单的分类任务来训练嵌入 class SimpleTextClassifier(nn.Module): def __init__(self, vocab_size, embedding_dim, hidden_dim, num_classes): super().__init__() self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0) self.fc1 = nn.Linear(embedding_dim, hidden_dim) self.fc2 = nn.Linear(hidden_dim, num_classes) self.relu = nn.ReLU() def forward(self, x): # x: [batch_size, seq_len] embedded = self.embedding(x) # [batch_size, seq_len, embedding_dim] # 简单平均池化 pooled = embedded.mean(dim=1) # [batch_size, embedding_dim] # 分类层 hidden = self.relu(self.fc1(pooled)) output = self.fc2(hidden) return output # 创建模型 model = SimpleTextClassifier( vocab_size=1000, embedding_dim=128, hidden_dim=64, num_classes=2 # 二分类 ) # 模拟训练数据 batch_size = 4 seq_len = 10 x = torch.randint(1, 100, (batch_size, seq_len)) # 避开padding_idx=0 y = torch.randint(0, 2, (batch_size,)) # 前向传播 logits = model(x) print(f"输入形状: {x.shape}") print(f"输出形状: {logits.shape}") # 查看嵌入权重的变化 initial_embedding = model.embedding.weight[1].clone() # 保存初始权重 # 模拟一次训练步骤 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.01) loss = criterion(logits, y) optimizer.zero_grad() loss.backward() optimizer.step() # 检查权重变化 updated_embedding = model.embedding.weight[1] weight_change = torch.norm(updated_embedding - initial_embedding).item() print(f"\n训练前后嵌入权重变化: {weight_change:.6f}") print("嵌入层通过下游任务的监督信号学习语义表示") demonstrate_embedding_training()
🔄 第五部分:循环神经网络(RNN)
5.1 RNN的基本原理
核心思想:
- 参数共享:在时间维度上共享参数,类似于CNN在空间维度上的参数共享
- 序列建模:能够处理变长序列,保持历史信息
- 递归结构:当前时刻的输出依赖于当前输入和前一时刻的隐状态
数学表达式:
h_t = tanh(x_t W_ih + h_{t-1} W_hh + b_hh)
其中:
- h_t:时刻t的隐状态
- x_t:时刻t的输入
- W_ih:输入到隐层的权重矩阵
- W_hh:隐层到隐层的权重矩阵
import torch import torch.nn as nn def create_rnn_model(input_size, hidden_size, num_layers=1, batch_first=True): """创建RNN模型""" rnn = nn.RNN( input_size=input_size, # 输入特征维度 hidden_size=hidden_size, # 隐状态维度 num_layers=num_layers, # RNN层数 batch_first=batch_first, # 批次维度在前 bidirectional=False # 是否双向 ) return rnn # 创建RNN示例 input_size = 512 # 词嵌入维度 hidden_size = 256 # 隐状态维度 batch_size = 2 # 批量大小 seq_len = 10 # 序列长度 rnn = create_rnn_model(input_size, hidden_size) # 准备输入数据 # 格式:[batch_size, seq_len, input_size] (当batch_first=True时) x = torch.randn(batch_size, seq_len, input_size) print(f"输入形状: {x.shape}") # 初始隐状态 # 格式:[num_layers, batch_size, hidden_size] h0 = torch.zeros(1, batch_size, hidden_size) print(f"初始隐状态形状: {h0.shape}") # 前向传播 output, hidden = rnn(x, h0) print(f"输出形状: {output.shape}") # [batch_size, seq_len, hidden_size] print(f"最终隐状态形状: {hidden.shape}") # [num_layers, batch_size, hidden_size]
RNN的特点:
- 优点:能处理序列数据,理论上可以记住任意长的历史信息
- 缺点:梯度消失问题,难以学习长期依赖关系
5.2 LSTM(长短期记忆网络)
核心创新:通过门控机制解决RNN的梯度消失问题,能够有效学习长期依赖关系。
三个门控机制:
- 遗忘门:决定丢弃哪些信息
- 输入门:决定存储哪些新信息
- 输出门:决定输出哪些信息
def create_lstm_model(input_size, hidden_size, num_layers=1, batch_first=True, bidirectional=False): """创建LSTM模型""" lstm = nn.LSTM( input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, batch_first=batch_first, bidirectional=bidirectional, dropout=0.1 if num_layers > 1 else 0 # 多层时添加dropout ) return lstm # 创建LSTM示例 lstm = create_lstm_model(input_size=512, hidden_size=256, num_layers=2) # 准备输入 batch_size, seq_len, input_size = 2, 15, 512 x = torch.randn(batch_size, seq_len, input_size) # LSTM需要两个初始状态:隐状态和细胞状态 num_layers = 2 h0 = torch.zeros(num_layers, batch_size, 256) # 隐状态 c0 = torch.zeros(num_layers, batch_size, 256) # 细胞状态 print(f"输入形状: {x.shape}") print(f"初始隐状态形状: {h0.shape}") print(f"初始细胞状态形状: {c0.shape}") # 前向传播 output, (hn, cn) = lstm(x, (h0, c0)) print(f"输出形状: {output.shape}") print(f"最终隐状态形状: {hn.shape}") print(f"最终细胞状态形状: {cn.shape}") # 双向LSTM示例 bilstm = create_lstm_model( input_size=512, hidden_size=256, bidirectional=True ) # 双向LSTM的隐状态维度会翻倍 h0_bi = torch.zeros(2, batch_size, 256) # 2 = num_layers * 2 (双向) c0_bi = torch.zeros(2, batch_size, 256) output_bi, (hn_bi, cn_bi) = bilstm(x, (h0_bi, c0_bi)) print(f"\n双向LSTM输出形状: {output_bi.shape}") # hidden_size * 2
LSTM的优势:
- 长期记忆:细胞状态可以携带长距离信息
- 选择性记忆:门控机制决定记住或遗忘信息
- 梯度流动:避免梯度消失,训练更稳定
5.3 实际应用示例
让我们用真实的酒店评论数据演示完整的文本分类流程:
import pandas as pd import torch import torch.nn as nn from torch.utils.data import Dataset, DataLoader import jieba from collections import Counter class TextClassificationModel(nn.Module): """基于LSTM的文本分类模型""" def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim, num_layers=2): super().__init__() self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0) self.lstm = nn.LSTM( embedding_dim, hidden_dim, num_layers, batch_first=True, bidirectional=True, dropout=0.3 ) self.fc = nn.Linear(hidden_dim * 2, output_dim) # *2 for bidirectional self.dropout = nn.Dropout(0.5) def forward(self, x): # x: [batch_size, seq_len] embedded = self.embedding(x) # [batch_size, seq_len, embedding_dim] # LSTM lstm_out, (hidden, _) = self.lstm(embedded) # 使用最后一个时刻的输出 # 取最后一层的前向和后向隐状态 # hidden: [num_layers*2, batch_size, hidden_dim] forward_hidden = hidden[-2, :, :] # 前向 backward_hidden = hidden[-1, :, :] # 后向 final_hidden = torch.cat([forward_hidden, backward_hidden], dim=1) # 分类层 output = self.dropout(final_hidden) output = self.fc(output) return output def prepare_text_data(texts, max_vocab_size=10000, max_seq_len=100): """准备文本数据""" # 分词 tokenized_texts = [jieba.lcut(text) for text in texts] # 构建词汇表 all_tokens = [] for tokens in tokenized_texts: all_tokens.extend(tokens) token_counts = Counter(all_tokens) vocab = ['<PAD>', '<UNK>'] + [token for token, _ in token_counts.most_common(max_vocab_size-2)] token2idx = {token: idx for idx, token in enumerate(vocab)} # 文本转换为索引序列 def text_to_indices(tokens): indices = [token2idx.get(token, token2idx['<UNK>']) for token in tokens] # 截断或填充到固定长度 if len(indices) > max_seq_len: indices = indices[:max_seq_len] else: indices.extend([0] * (max_seq_len - len(indices))) # 0是<PAD>的索引 return indices indexed_texts = [text_to_indices(tokens) for tokens in tokenized_texts] return indexed_texts, token2idx, vocab # 示例:使用酒店评论数据 sample_comments = [ "酒店服务很好,房间干净整洁,位置优越", "前台服务态度差,房间设施陈旧,不推荐", "性价比不错,早餐丰富,交通便利", "房间太小,隔音效果差,影响休息" ] sample_labels = [1, 0, 1, 0] # 1: 正面, 0: 负面 # 数据预处理 indexed_texts, token2idx, vocab = prepare_text_data(sample_comments, max_seq_len=50) vocab_size = len(vocab) print(f"词汇表大小: {vocab_size}") print(f"示例索引序列长度: {len(indexed_texts[0])}") # 创建模型 model = TextClassificationModel( vocab_size=vocab_size, embedding_dim=128, hidden_dim=64, output_dim=2, # 二分类 num_layers=2 ) # 模型参数统计 total_params = sum(p.numel() for p in model.parameters()) trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad) print(f"\n模型总参数: {total_params:,}") print(f"可训练参数: {trainable_params:,}") # 测试前向传播 x = torch.tensor(indexed_texts, dtype=torch.long) y = torch.tensor(sample_labels, dtype=torch.long) with torch.no_grad(): logits = model(x) print(f"\n输入形状: {x.shape}") print(f"输出形状: {logits.shape}") print(f"预测概率: {torch.softmax(logits, dim=1)}")
📈 第六部分:总结与进阶方向
6.1 核心知识点回顾
文本处理流程:
- 分词:字符级 vs 词级,统计视角优于语法视角
- 向量化:Count → TF-IDF → Embedding,从稀疏到稠密
- 序列建模:RNN → LSTM → Transformer,处理序列依赖关系
关键技术对比:
| 技术 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Count向量 | 简单快速 | 忽略词序,稀疏 | 文档分类 |
| TF-IDF | 考虑词重要性 | 仍然稀疏,无语义 | 信息检索 |
| Word Embedding | 稠密,有语义 | 需要训练 | 深度学习NLP |
| RNN | 处理序列 | 梯度消失 | 短序列任务 |
| LSTM | 长期依赖 | 计算复杂 | 长序列任务 |
6.2 实践建议
学习路径:
- 基础巩固:熟练掌握文本预处理和向量化技术
- 代码实践:完成酒店评论分类项目
- 模型调优:尝试不同的超参数和网络结构
- 进阶学习:学习Attention机制和Transformer架构
常见问题与解决方案:
# 常见问题1:内存不足 def create_data_loader(texts, labels, batch_size=32, shuffle=True): """创建数据加载器,避免内存问题""" class TextDataset(Dataset): def __init__(self, texts, labels): self.texts = texts self.labels = labels def __len__(self): return len(self.texts) def __getitem__(self, idx): return torch.tensor(self.texts[idx], dtype=torch.long), \ torch.tensor(self.labels[idx], dtype=torch.long) dataset = TextDataset(texts, labels) dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=shuffle) return dataloader # 常见问题2:序列长度不一致 def pad_sequences(sequences, max_len=None, pad_value=0): """序列填充函数""" if max_len is None: max_len = max(len(seq) for seq in sequences) padded = [] for seq in sequences: if len(seq) >= max_len: padded.append(seq[:max_len]) else: padded.append(seq + [pad_value] * (max_len - len(seq))) return padded # 常见问题3:梯度爆炸 def train_with_gradient_clipping(model, dataloader, epochs=10): """带梯度裁剪的训练函数""" optimizer = torch.optim.Adam(model.parameters(), lr=0.001) criterion = nn.CrossEntropyLoss() for epoch in range(epochs): for batch_idx, (data, target) in enumerate(dataloader): optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() # 梯度裁剪 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=5.0) optimizer.step() if batch_idx % 10 == 0: print(f'Epoch: {epoch}, Batch: {batch_idx}, Loss: {loss.item():.4f}') print("学习完成!继续探索更高级的NLP技术吧!")
🎯 关键要点总结
✅ 最佳实践
- 数据驱动思维:从统计角度而非语法角度分析文本
- 序列建模重要性:文本具有时序依赖性,需要合适的序列模型
- 向量化技术选择:根据任务需求选择合适的向量化方法
- 模型架构设计:LSTM能有效处理长序列依赖关系
🔍 深入理解
- 文本预处理:分词、编码、向量化是NLP的基础步骤
- 词嵌入技术:稠密向量表示比稀疏表示更有语义信息
- 循环神经网络:RNN和LSTM是处理序列数据的重要工具
- 梯度问题:LSTM通过门控机制解决梯度消失问题
📈 进阶方向
- Attention机制:学习注意力机制和Transformer架构
- 预训练模型:BERT、GPT等大规模预训练模型
- 多模态学习:文本与图像、音频的结合
- 实际应用:情感分析、机器翻译、问答系统等
学习心得
这节课深入学习了自然语言处理的核心技术:
- 数据科学视角:从数据类型分类的角度理解文本处理的特殊性
- 技术演进:从简单的词频统计到复杂的神经网络模型
- 实践导向:通过完整的代码示例理解每个技术环节
- 问题解决:学会处理NLP中的常见技术问题
下一步学习计划
- 深入学习Attention机制和Transformer架构
- 实践BERT等预训练模型的使用
- 完成完整的NLP项目(情感分析、文本分类等)
- 探索多模态学习和实际应用场景