模型基本测试运行
我们将通过一个小的copy任务完成基本测试工作
copy任务介绍
针对数字序列进行学习,学习的最终目标时使输出与输入的序列相同
任务意义:copy明显的规律,小数据集中学会它,可以帮助我们断定模型所有过程是否正常,是否已具备基本学习能力。
使用copy任务进行模型基本测试的四部曲
1、构建数据集生成器
2、获得transformer模型及其优化器和损失函数
3、运行模型进行训练和评估
4、使用模型进行贪婪解码
生成数据
def data_generator(V,batch_size,num_batch):
"""
:param V: 随机生成数据的最大值+1
:param batch_size: 每次输送给模型的样本数量,经历这些样本训练后进行一次参数的更新
:param num_batch: 一共输送模型多少轮数据
:return:
"""
for i in range(num_batch):
# 使用numpy中的ranom.randint()来随机生成[1,v]
# 分布的形状(batch,10)
data = torch.from_numpy(np.random.randint(1,V,size(batch_size,10)))
# 将数据的第一列全部设置为1,作为起始标志
data[:,0] = 1
# 因为copy任务,所以源数据和目标数据完全一致
# 设置参数requires_grad = False,样本的参数不需要参与梯度的计算
source = Variable(data,requires_grad = False)
target = Variable(data,requires_grad = False)
yield Batch(source,target)
V = 11
batch_size = 20
num_batch = 30
# 使用make_model获得model
# 源数据的词汇总量=目标数据的任务,我们这个任务就是复制任务
model = make_model(V,V,N=2)
# 使用get_std_opt获得模型优化器
model_optimizer = get_std_opt(model)
# 使用LabelSmoothing获得标签平滑对象
criterion = LabelSmoothing(size=V,padding_idx=0,smoothing=0.0)
# 使用SimpleLossCompute获得利用标签平滑结果的损失计算方法
loss = SimpleLossCompute(model.generator,criterion,model_optimizer)
标签平滑示例
# 标签平滑函数的实例,LabelSmoothing
# 使用LabelSmoothing实例化一个crit对象
# 第一个参数size代表目标数据的词汇总数,也是模型最后一层得到的张量的最后一维大小
# 这里是5说明目标词汇总数是5,
# 第二个参数是padding_dix表示要将哪些tensor中的数字替换为0
# 一般padding_idx=0表示不进行替换
# 第三个参数smoothing,表示标签的平滑程度
# 如原来标签的表示值为1,则平滑后它的值域变为[1-smoothing,1+smoothing]
crit = LabelSmoothing(size=5,padding_idx=0,smoothing=0.5)
# 假设一个任意的模型最后输出预测结果和真实结果
predict = Variable(torch.FloatTensor([[0,0.2,0.7,0.1,0],[0,0.2,0.7,0.1,0],[0,0.2,0.7,0.1,0]]))
# 标签的表达值是0,1,2
target = Variable(torch.LongTensor([2,1,0]))
# 将predict,target传入到对象中
crit(predict,target)
# 绘制标签平滑图像
plt.imshow(crit.true_dist)
plt.show()
标签平滑图像
标签平滑图像分析
我们目光集中在黄色小方块熵,它相对于横坐标横跨的值域就是标签平滑后的正向平滑值域,我们可以看到大致是从0.5到2.5
它相当于纵坐标横跨的值域就是标签平滑后的负向平滑值域,我们可以看到大致是从-0.5到1.5,总的值域空间由原来的[0.2]变为[-0.5,2.5]
构建数据集生成器
这个错误真的不知道为什么出来了!!!!!!!!!!!!!!!!
D:\soft\Anaconda\envs\py3.9\python.exe D:/soft/pycharm/pythonProject2/main.py
D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\_reduction.py:42: UserWarning: size_average and reduce args will be deprecated, please use reduction='sum' instead.
warnings.warn(warning.format(ret))
Traceback (most recent call last):
File "D:\soft\pycharm\pythonProject2\main.py", line 1173, in <module>
run(model,loss)
File "D:\soft\pycharm\pythonProject2\main.py", line 1160, in run
run_epoch(data_generator(V,8,20),model,loss)
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\pyitcast\transformer_utils.py", line 46, in run_epoch
out = model.forward(batch.src, batch.trg,
File "D:\soft\pycharm\pythonProject2\main.py", line 935, in forward
return self.decode(self.encoder(source,source_mask),source_mask,target,target_mask)
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
return forward_call(*input, **kwargs)
File "D:\soft\pycharm\pythonProject2\main.py", line 657, in forward
x = layer(x, mask)
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
return forward_call(*input, **kwargs)
File "D:\soft\pycharm\pythonProject2\main.py", line 618, in forward
x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
return forward_call(*input, **kwargs)
File "D:\soft\pycharm\pythonProject2\main.py", line 558, in forward
return x + self.dropout(sublayer(self.norm(x)))
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
return forward_call(*input, **kwargs)
File "D:\soft\pycharm\pythonProject2\main.py", line 516, in forward
mean = x.mean(axis = -1, keepdims=True)
RuntimeError: mean(): could not infer output dtype. Input dtype must be either a floating point or complex dtype. Got: Int
进程已结束,退出代码1
D:\soft\Anaconda\envs\py3.9\python.exe D:/soft/pycharm/pythonProject2/main.py
D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\_reduction.py:42: UserWarning: size_average and reduce args will be deprecated, please use reduction='sum' instead.
warnings.warn(warning.format(ret))
Traceback (most recent call last):
File "D:\soft\pycharm\pythonProject2\main.py", line 1194, in <module>
run(model,loss)
File "D:\soft\pycharm\pythonProject2\main.py", line 1166, in run
run_epoch(data_generator(V,8,20),model,loss)
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\pyitcast\transformer_utils.py", line 46, in run_epoch
out = model.forward(batch.src, batch.trg,
File "D:\soft\pycharm\pythonProject2\main.py", line 936, in forward
return self.decode(self.encoder(source,source_mask),source_mask,target,target_mask)
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
return forward_call(*input, **kwargs)
File "D:\soft\pycharm\pythonProject2\main.py", line 658, in forward
x = layer(x, mask)
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
return forward_call(*input, **kwargs)
File "D:\soft\pycharm\pythonProject2\main.py", line 619, in forward
x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
return forward_call(*input, **kwargs)
File "D:\soft\pycharm\pythonProject2\main.py", line 559, in forward
return x + self.dropout(sublayer(self.norm(x)))
File "D:\soft\Anaconda\envs\py3.9\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
return forward_call(*input, **kwargs)
File "D:\soft\pycharm\pythonProject2\main.py", line 517, in forward
std = torch.std(x, dim = -1, keepdim=True,dtype = torch.float32)
TypeError: std() received an invalid combination of arguments - got (Tensor, dim=int, keepdim=bool, dtype=torch.dtype), but expected one of:
* (Tensor input, tuple of ints dim, bool unbiased, bool keepdim, *, Tensor out)
* (Tensor input, tuple of ints dim, *, int correction, bool keepdim, Tensor out)
* (Tensor input, bool unbiased)
* (Tensor input, tuple of names dim, bool unbiased, bool keepdim, *, Tensor out)
* (Tensor input, tuple of names dim, *, int correction, bool keepdim, Tensor out)
进程已结束,退出代码1
怎么就这么难呢
什么是语言模型
什么是语言模型
以一个符合语言规律的序列为输入,模型将利用序列间关系等特征,输出一个在所有词汇上的概率分布,这样的模型称为语言模型
语言模型能解决哪些问题
1、根据语言模型的定义,可以在它的基础上完成机器翻译,文本生成等任务,因为我们通过最后输出的概率分布来预测下一个词汇是什么
2、语言模型可以判断输入的序列是否为一句完整的话,因为我们可以根据输出的概率分布查看最大概率是否落在句子结束符上,来判断完整性
3、语言模型本身的训练目标是训练下一个词,因为它的特征提取部分会抽象很多语言序列之间的关系,这些关系可能同样地对其他语言类任务有效果,因此可以作为预训练模型进行迁移学习
五个步骤
1、导入必备包
2、导入wikiText-2数据集并作基本处理
3、构建用于模型输入地批次化数据
4、构建训练和评估函数
5、进行训练和评估(包括验证以及测试)
http://t.csdn.cn/8WC3I
AttributeError: module ‘torchtext.legacy.datasets’ has no attribute ‘wikitext2’
AttributeError: module ‘torchtext.data’ has no attribute ‘Field’
问题:
train_txt,val_txt,test_txt = torchtext.legacy.datasets.WikiText2.split(TEXT)
import math
import torch
import torch.nn as nn
import torch.functional as F
# from torchtext.legacy.data import Field
import torchtext
# print('torchtext版本:',torchtext.__version__)
# torchtext中的数据处理工具,get_torenizer用于英文分类
from torchtext.data.utils import get_tokenizer
# 已经构建完成的TransformerModel
from pyitcast.transformer import TransformerModel
# torchtext介绍
## 它是torch工具中处理NLP问题的常用数据包
## torchtext的重要功能
# 对文本数据进行处理,文本预料加载,文本迭代器构建等
# 包含很多经典文本预料和预加载方法,其中包含的预料有:用于情感分析的SST和IMDB
# 这里使用wikiText-2来训练语言模型,
"""
wikitext-数据集的体谅中等,208万左右的词汇,33278个不重复词汇,OvV(多少正常英文词汇不再该数据集中的占比)为2.6%,数据集中的短文都是维基百科中对一些概念的介绍和描述
"""
# 导入wikiText-2数据集并作基本处理
# 创建语料域,语料域是存放语料的数据结构
# 四个参数代表给存放文本施加的作用
# 分别为tokenizer,使用get_tokenizer("basic-english)获得一个分割器对象
# 分割方式按照文本为基础英文进行分割
# init_token给文本施加的起始符,<sos>给文本施加的终止符<eos>
# 最后一个lower为True,存放的文本字母全部小写
# AttributeError: module 'torchtext.data' has no attribute 'Field'
TEXT = torchtext.legacy.data.Field(tokenize=get_tokenizer("basic_english"),
init_token = '<sos',
eos_token='<eos>',
lower = True)
# 最终获得一个Field对象
print(TEXT)
#然后使用torchtext的数据集方法导入wikitext2数据
# 并切分对应训练文本,验证文本,测试文本,并对这些文本施加刚刚创建的语料域
# AttributeError: module 'torchtext.legacy.datasets' has no attribute 'wikitext2'
# 要加s!!!!!,要不然会报错
train_txt,val_txt,test_txt = torchtext.legacy.datasets.WikiText2.splits(TEXT)
print(test_txt.examples[0].text[:10])
# 我们可以通过examples[0].text去除文本对象进行查看
# 将训练集文本数据构建一个vocab对象
# 这样可以使用vocab对象的stoi方法统计文本共包含的不重复词汇总数
TEXT.build_vocab(train_txt)
# 然后选择设备cuda或者cpu
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
D:\soft\Anaconda\envs\py3.9\python.exe D:/soft/pycharm/pythonProject2/l4transformer.py
<torchtext.legacy.data.field.Field object at 0x0000029CFAA27670>
['<eos>', '=', 'robert', '<unk>', '=', '<eos>', '<eos>', 'robert', '<unk>', 'is']
进程已结束,退出代码0
import math
import torch
import torch.nn as nn
import torch.functional as F
# from torchtext.legacy.data import Field
import torchtext
# print('torchtext版本:',torchtext.__version__)
# torchtext中的数据处理工具,get_torenizer用于英文分类
from torchtext.data.utils import get_tokenizer
# 已经构建完成的TransformerModel
from pyitcast.transformer import TransformerModel
# torchtext介绍
## 它是torch工具中处理NLP问题的常用数据包
## torchtext的重要功能
# 对文本数据进行处理,文本预料加载,文本迭代器构建等
# 包含很多经典文本预料和预加载方法,其中包含的预料有:用于情感分析的SST和IMDB
# 这里使用wikiText-2来训练语言模型,
"""
wikitext-数据集的体谅中等,208万左右的词汇,33278个不重复词汇,OvV(多少正常英文词汇不再该数据集中的占比)为2.6%,数据集中的短文都是维基百科中对一些概念的介绍和描述
"""
# 导入wikiText-2数据集并作基本处理
# 创建语料域,语料域是存放语料的数据结构
# 四个参数代表给存放文本施加的作用
# 分别为tokenizer,使用get_tokenizer("basic-english)获得一个分割器对象
# 分割方式按照文本为基础英文进行分割
# init_token给文本施加的起始符,<sos>给文本施加的终止符<eos>
# 最后一个lower为True,存放的文本字母全部小写
# AttributeError: module 'torchtext.data' has no attribute 'Field'
TEXT = torchtext.legacy.data.Field(tokenize=get_tokenizer("basic_english"),
init_token = '<sos',
eos_token='<eos>',
lower = True)
# 最终获得一个Field对象
print(TEXT)
#然后使用torchtext的数据集方法导入wikitext2数据
# 并切分对应训练文本,验证文本,测试文本,并对这些文本施加刚刚创建的语料域
# AttributeError: module 'torchtext.legacy.datasets' has no attribute 'wikitext2'
# 要加s!!!!!,要不然会报错
train_txt,val_txt,test_txt = torchtext.legacy.datasets.WikiText2.splits(TEXT)
# print(test_txt.examples[0].text[:10])
# 我们可以通过examples[0].text去除文本对象进行查看
# 将训练集文本数据构建一个vocab对象
# 这样可以使用vocab对象的stoi方法统计文本共包含的不重复词汇总数
TEXT.build_vocab(train_txt)
# 然后选择设备cuda或者cpu
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 第三步:构建用于模型输入的批次化数据
# batchify代码分析
def batchify(data,bsz):
"""
batchify函数用于将文本数据映射成连续数字,并转换成指定的样子
:param data: 我们之前得到的文本数据(train_txt,val_txt,test_txt)
:param bsz: batch_size,欸此模型更新参数的数据量
:return:
"""
# 使用TEXT的numericalize方法将单词映射成对应的额连续数字
data = TEXT.numericalize([data.examples[0].text])
print(data)
# 接着用数据词汇总数除以bsz
# 取整数得到一个nbatch代表需要多少词batch后才能遍历完所有数据
nbatch = data.size(0) // bsz
# 之后使用narrow方法对不规整的剩余数据进行删除
# 第一个参数是代表横轴删除还是纵轴删除,0为横轴,1为纵轴
# 第二个和第三个参数代表保留开始轴到结束轴的数值,类似于切片
#从0开始切,切到这个取整的地方
# 在行上面,只保留了0和1,是一个闭开区间
# 在列上,序号为1这个位置切,但是2保留下来了,列上是属于闭闭区间
data = data.narrow(0,0,nbatch*bsz)
# 如果输入的是训练数据的化,形状为[104335,20],可以通过打印data.shape获得
# 也就是data的列数是等于bsz的值的
# -1适配的这个值
data = data.view(bsz,-1).t().contiguous()
return data.to(device)
# x = torch.tensor([[1,2,3],[4,5,6],[7,8,9]])
# print(x.narrow(0,0,2))
# 接下来使用Batchify来处理训练数据,验证数据以及训练测试
# 训练数据的batch size
batch_size = 20
# 验证和测试数据(统称为评估数据)的batch size
eval_batch_size = 10
# 获得train_data.val_data,test_Data
train_data = batchify(train_txt,batch_size)
val_data = batchify(val_txt,eval_batch_size)
test_data = batchify(test_txt,eval_batch_size)
# 语言模型训练的语料规定
# 源数据ABCD,目标数据BCDE
# 如果这里的句子序列是竖着的,发现如果用一个批次处理完所有数据,以训练数据为例,每个句子长度高了
# 批量化的第二个函数get_batch
# 允许子长度的最大值bptt为35
bptt = 35
def get_bath(source,i):
"""
用于获得每个批次合理大小的源数据和目标数据
:param source: 通过batchify得到的traib_data/val_data/test_data
:param i: 具体的批次
:return:
"""
# 首先我们确定句子长度,bptt和len(source)-1-i中的最小值
# 实质上,前面的批次中都会是bptt的值,只不过最后一个批次中,句子长度
# 可能不够bptt的35个,因此会变为len(source)-1-i的值
seq_len = min(bptt,len(source)-1-i)
# 语言模型训练的源数据的第i批数据将是batchify的结果的切片[i:i+seq_len]
data = source[i:i+seq_len]
# 根据语言模型训练的预料规定,它的目标数据是源数据向后移动一位
# 因为最后目标数据的切片会越界,因此使用view(-1)来保证形状正常
target = source[i+1:i+1+seq_len].view(-1)
return data,target
source = test_data
i = 1
x,y=get_bath(source,i)
print(x)
print(y)
D:\soft\Anaconda\envs\py3.9\python.exe D:/soft/pycharm/pythonProject2/l4transformer.py
<torchtext.legacy.data.field.Field object at 0x000001F6AF53D490>
tensor([[ 3],
[ 12],
[3852],
...,
[ 6],
[ 3],
[ 3]])
tensor([[ 3],
[ 12],
[9609],
...,
[ 3],
[ 3],
[ 3]])
tensor([[ 3],
[ 12],
[635],
...,
[ 6],
[ 3],
[ 3]])
tensor([[ 12, 1053, 355, 134, 37, 7, 4, 0, 835, 9834],
[ 635, 8, 5, 5, 421, 4, 88, 8, 573, 2511],
[ 0, 58, 8, 8, 6, 692, 544, 0, 212, 5],
[ 12, 0, 105, 26, 3, 5, 6, 0, 4, 56],
[ 3, 16074, 21254, 320, 3, 262, 16, 6, 1087, 89],
[ 3, 751, 3866, 10, 12, 31, 246, 238, 79, 49],
[ 635, 943, 78, 36, 12, 475, 66, 10, 4, 924],
[ 0, 2358, 52, 4, 12, 4, 5, 0, 19831, 21],
[ 26, 38, 54, 40, 1589, 3729, 1014, 5, 8, 4],
[ 33, 17597, 33, 1661, 15, 7, 5, 0, 4, 170],
[ 335, 268, 117, 0, 0, 4, 3144, 1557, 0, 160],
[ 106, 4, 4706, 2245, 12, 1074, 13, 2105, 5, 29],
[ 5, 16074, 10, 1087, 12, 137, 251, 13238, 8, 4],
[ 394, 746, 4, 9, 12, 6032, 4, 2190, 303, 12651],
[ 8, 616, 2107, 4, 3, 4, 425, 0, 10, 510],
[ 1339, 112, 23, 335, 3, 22251, 1162, 9, 11, 9],
[ 1212, 468, 6, 820, 9, 7, 1231, 4202, 2866, 382],
[ 6, 24, 104, 6, 4, 4, 7, 10, 9, 588],
[ 31, 190, 0, 0, 230, 267, 4, 273, 278, 6],
[ 34, 25, 47, 26, 1864, 6, 694, 0, 2112, 3],
[ 11, 6, 52, 798, 8, 69, 20, 31, 63, 9],
[ 1800, 25, 2141, 2442, 117, 31, 196, 7290, 4, 298],
[ 15, 171, 15, 17, 1712, 13, 217, 59, 736, 5],
[ 4210, 191, 142, 14, 5251, 939, 59, 38, 10055, 25132],
[ 302, 23, 11718, 11, 11, 599, 382, 317, 8, 13],
[ 16, 1564, 9, 4808, 6, 0, 6, 6, 4, 4],
[ 4, 7, 39, 7, 3934, 5, 9, 3, 8047, 557],
[ 394, 0, 10715, 3580, 8682, 31, 242, 0, 10055, 170],
[ 96, 6, 144, 3403, 4, 13, 1014, 14, 6, 2395],
[ 4, 3, 13729, 14, 40, 0, 5, 18, 676, 3267],
[ 1031, 3, 0, 628, 1589, 22, 10916, 10969, 5, 22548],
[ 9, 12, 6, 84, 15, 49, 3144, 7, 102, 15],
[ 916, 12, 4, 203, 0, 273, 303, 333, 4318, 0],
[ 6, 12, 0, 4842, 5, 17, 4, 47, 4138, 2072],
[ 38, 237, 5, 50, 35, 27, 18530, 244, 20, 6]])
tensor([ 635, 8, 5, 5, 421, 4, 88, 8, 573, 2511,
0, 58, 8, 8, 6, 692, 544, 0, 212, 5,
12, 0, 105, 26, 3, 5, 6, 0, 4, 56,
3, 16074, 21254, 320, 3, 262, 16, 6, 1087, 89,
3, 751, 3866, 10, 12, 31, 246, 238, 79, 49,
635, 943, 78, 36, 12, 475, 66, 10, 4, 924,
0, 2358, 52, 4, 12, 4, 5, 0, 19831, 21,
26, 38, 54, 40, 1589, 3729, 1014, 5, 8, 4,
33, 17597, 33, 1661, 15, 7, 5, 0, 4, 170,
335, 268, 117, 0, 0, 4, 3144, 1557, 0, 160,
106, 4, 4706, 2245, 12, 1074, 13, 2105, 5, 29,
5, 16074, 10, 1087, 12, 137, 251, 13238, 8, 4,
394, 746, 4, 9, 12, 6032, 4, 2190, 303, 12651,
8, 616, 2107, 4, 3, 4, 425, 0, 10, 510,
1339, 112, 23, 335, 3, 22251, 1162, 9, 11, 9,
1212, 468, 6, 820, 9, 7, 1231, 4202, 2866, 382,
6, 24, 104, 6, 4, 4, 7, 10, 9, 588,
31, 190, 0, 0, 230, 267, 4, 273, 278, 6,
34, 25, 47, 26, 1864, 6, 694, 0, 2112, 3,
11, 6, 52, 798, 8, 69, 20, 31, 63, 9,
1800, 25, 2141, 2442, 117, 31, 196, 7290, 4, 298,
15, 171, 15, 17, 1712, 13, 217, 59, 736, 5,
4210, 191, 142, 14, 5251, 939, 59, 38, 10055, 25132,
302, 23, 11718, 11, 11, 599, 382, 317, 8, 13,
16, 1564, 9, 4808, 6, 0, 6, 6, 4, 4,
4, 7, 39, 7, 3934, 5, 9, 3, 8047, 557,
394, 0, 10715, 3580, 8682, 31, 242, 0, 10055, 170,
96, 6, 144, 3403, 4, 13, 1014, 14, 6, 2395,
4, 3, 13729, 14, 40, 0, 5, 18, 676, 3267,
1031, 3, 0, 628, 1589, 22, 10916, 10969, 5, 22548,
9, 12, 6, 84, 15, 49, 3144, 7, 102, 15,
916, 12, 4, 203, 0, 273, 303, 333, 4318, 0,
6, 12, 0, 4842, 5, 17, 4, 47, 4138, 2072,
38, 237, 5, 50, 35, 27, 18530, 244, 20, 6,
13, 1083, 35, 1990, 653, 13, 10, 11, 1538, 56])
进程已结束,退出代码0
小结
学习了什么是语言模型
以一个符合语言规律的序列为输入,模型将利用序列间关系等特征,输出一个在所有词汇上的概率分布这样的模型称为语言模型