1. 环境配置
Python 3.7.4
torch 1.5.1
torchtext 0.6.0
torchvision 0.6.1
numpy 1.16.5
2. 学习目标_语言模型
学习目标
- 学习语言模型,以及如何训练一个语言模型
- 学习torchtext的基本使用方法
- 构建 vocabulary
- word to inde 和 index to word
- 学习torch.nn的一些基本模型
- Linear
- RNN
- LSTM
- GRU
- RNN的训练技巧
- Gradient Clipping
- 如何保存和读取模型
3. 使用库的语法介绍
4. 项目流程
- 我们使用 torchtext 来创建vocabulary, 然后把数据读成batch的格式。
- 定义模型RNN,LSTM模型介绍
- 继承nn.Module
- 初始化函数
- forward函数
- 其余可以根据模型需要定义相关的函数
- 初始化一个模型
- 定义评估模型
- 定义loss function和optimizer
- 定义训练模型:
- 模型一般需要训练若干个epoch
- 每个epoch我们都把所有的数据分成若干个batch
- 把每个batch的输入和输出都包装成cuda tensor
- forward pass,通过输入的句子预测每个单词的下一个单词
- 用模型的预测和正确的下一个单词计算cross entropy loss
- 清空模型当前gradient
- backward pass
- gradient clipping,防止梯度爆炸
- 更新模型参数
- 每隔一定的iteration输出模型在当前iteration的loss,以及在验证集上做模型的评估
- 计算perplexity
- 使用训练好的模型生成一些句子
5. 项目代码,部分运行结果与解析
import torch
import torchtext
from torchtext import data
from torchtext.vocab import Vectors
import numpy as np
import random
SEED = 53113
random.seed(SEED)
np.random.seed(SEED)
torch.manual_seed(SEED)
torch.cuda.manual_seed(SEED)
# torch.backends.cudnn.deterministic = True
BATCH_SIZE = 32 #一个batch 有多少个句子
EMBEDDING_SIZE = 500 #每个单词多少维
MAX_VOCAB_SIZE = 50000 # 单词总数
- 使用
torchtext
提供的LanguageModelingDataset
来处理语言数据
使用BPTTIterator
得到连续的句子
TEXT = torchtext.data.Field(lower = True)
# .Field这个对象包含了我们打算如何预处理文本数据的信息,这里定义单词全部小写
train,val,test = \
torchtext.datasets.LanguageModelingDataset.splits(
path = ".",
train = "text8.train.txt" ,
validation= "text8.dev.txt" ,
test = "text8.test.txt",
text_field=TEXT)
TEXT.build_vocab(train,max_size = MAX_VOCAB_SIZE)
print("vacabulary size:{}".format(len(TEXT.vocab)))
# #TEXT.vocab 就是定义好的词汇表
# 查看生成的test
test
# 观察定义好的词汇表
print(TEXT.vocab.itos[0:50])
print("------"*10)
print(list(TEXT.vocab.stoi.items())[0:50])
#生成连续的句子
VOCAB_SIZE = len(TEXT.vocab)
train_iter,val_iter,test_iter = \
torchtext.data.BPTTIterator.splits(
(train,val,test),
batch_size = BATCH_SIZE,
device = 0,
bptt_len = 50,# 反向传播往回传的长度,这里我暂时理解为一个样本有多少个单词传入模型
repeat = False,
shuffle= True)
# BPTTIterator可以连续地得到连贯的句子,BPTT的全称是back propagation through time。
'''
Iterator:标准迭代器
BucketIerator:相比于标准迭代器,会将类似长度的样本当做一批来处理,
因为在文本处理中经常会需要将每一批样本长度补齐为当前批中最长序列的长度,
因此当样本长度差别较大时,使用BucketIerator可以带来填充效率的提高。
除此之外,我们还可以在Field中通过fix_length参数来对样本进行截断补齐操作。
BPTTIterator: 基于BPTT(基于时间的反向传播算法)的迭代器,一般用于语言模型中。
观察生成的batch
'''
#观察生成的batch
print(next(iter(train_iter)))# 一个batch训练集维度
print(next(iter(val_iter)))
print(next(iter(test_iter)))
#next(iterator[, default])
#返回iterator.__next__()的值,还可指定默认值,它指定在到达了迭代 器末尾时将返回的值
#iter(obj) 从可迭代对象创建一个迭代器 .简单地说,迭代器是包含方法__next__的对象,可用于迭代一组值。
#next(it) 让迭代器前进一步并返回下一个元素
#模型的输入是一串文字,模型的输出也是一串文字,他们之间相差一个位置,因为语言模型的目标是根据之前的单词预测下一个单词
it