1.定义位置嵌入函数,使用fairseq.modules中的LearnedPositionalEmbedding
def PositionalEmbedding(num_embeddings, embedding_dim, padding_idx):
- fairseq模型注册,class Transformer_nonautoregressive(FairseqModel):
@register_model('bert_transformer_seq2seq')
class Transformer_nonautoregressive(FairseqModel):
对于模型使用@register_model(‘bert_transformer_seq2seq’)装饰器来注册
3.fairseq模型参数注册
@register_model_architecture('bert_transformer_seq2seq', 'bert_transformer_seq2seq')
def base_architecture(args):
args.encoder_embed_path = getattr(args, 'encoder_embed_path', None)
args.encoder_embed_dim = getattr(args, 'encoder_embed_dim', 512)
args.encoder_ffn_embed_dim = getattr(args, 'encoder_ffn_embed_dim', args.encoder_embed_dim * 4)
args.encoder_layers = getattr(args, 'encoder_layers', 6)
使用@register_model_architecture来注册模型的参数,称为architecture
使用init_bert_weights,根据modules的不同设定参数
def init_bert_weights(self, module):
""" Initialize the weights.
"""
if isinstance(module, (nn.Linear, nn.Embedding)):
# Slightly different from the TF version which uses truncated_normal for initialization
# cf https://github.com/pytorch/pytorch/pull/5617
module.weight.data.normal_(mean=0.0, std=0.02)
elif isinstance(module, BertLayerNorm):
module.beta.data.zero_()
module.gamma.data.fill_(1.0)
if isinstance(module, nn.Linear) and module.bias is not None:
module.bias.data.zero_()
.data 和.detach
只取出本体tensor数据,舍弃了grad,grad_fn等额外反向图计算过程需保存的额外信息。
a = torch.tensor([1.,2,3], requires_grad = True)
print(a)
b = a.data
print(b)
tensor([1., 2., 3.], requires_grad=True)
tensor([1., 2., 3.])
.new
创建一个新的Tensor,该Tensor的type和device都和原有Tensor一致,且无内容。
实际应用中可用来保证与原数据在一个gpu上,.new()括号中可以指定size,可以直接用原数据的size
new_data=data.new(data.size()).fill_(0)
inputs = torch.randn(m, n)
new_inputs = inputs.new()
new_inputs = torch.Tensor.new(inputs)
torch.triu
(input, diagonal=0, out=None) → Tensor
>>> a = torch.randn(3, 3)
>>> a
tensor([[ 0.2309, 0.5207, 2.0049],
[ 0.2072, -1.0680, 0.6602],
[ 0.3480, -0.5211, -0.4573]])
>>> torch.triu(a)
tensor([[ 0.2309, 0.5207, 2.0049],
[ 0.0000, -1.0680, 0.6602],
[ 0.0000, 0.0000, -0.4573]])
>>> torch.triu(a, diagonal=1)
tensor([[ 0.0000, 0.5207, 2.0049],
[ 0.0000, 0.0000, 0.6602],
[ 0.0000, 0.0000, 0.0000]])
>>> torch.triu(a, diagonal=-1)
tensor([[ 0.2309, 0.5207, 2.0049],
[ 0.2072, -1.0680, 0.6602],
[ 0.0000, -0.5211, -0.4573]])
topk
a.topk()求a中的最大值或最小值,返回两个值,一个是a中的值(最大或最小),一个是这个值的索引。
>>> import torch
>>> a=torch.randn((3,5))
>>> a
tensor([[-0.4790, -0.6308, 0.2370, 0.0380, -0.0579],
[-0.6712, -3.5483, -0.2370, -0.8658, 0.4145],
[-1.4126, -0.8786, -0.4216, -0.0878, -1.4015]])
>>> _,pre=a.topk(1,dim=1,largest=True)
>>> pre
tensor([[2],
[4],
[3]])
>>> _
tensor([[ 0.2370],
[ 0.4145],
[-0.0878]])
>>> _,pre=a.topk(1,dim=1,largest=False)
>>> pre
tensor([[1],
[1],
[0]])
>>> _
tensor([[-0.6308],
[-3.5483],
[-1.4126]])
scatter()
scatter(dim, index, src) 的参数有 3 个
dim:沿着哪个维度进行索引
index:用来 scatter 的元素索引
src:用来 scatter 的源元素,可以是一个标量或一个张量
例如,有一个任务是这样的:有一个batchsize的sequence,sequence_length是一个longtensor代表了每个sequence的长度。另有一个表示对每个sequence的长度预测的矩阵P(bsz,max_seq_len),用来判断每个长度的可能性,现在需要将这个P的每行的第sequence_length[i]的位置加1000,表示他的可能性最大。
实现方法如下:
sequence_length=sequence_length.unsqueeze(1)
P.scatter_(1,sequence_length,1000)
class_num = 10
batch_size = 4
label = torch.LongTensor(batch_size, 1).random_() % class_num
#tensor([[6],
# [0],
# [3],
# [2]])
torch.zeros(batch_size, class_num).scatter_(1, label, 1)
#tensor([[0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
# [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
# [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
# [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.]])