PyTorch笔记 - Attention Is All You Need
Posted SpikeKing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PyTorch笔记 - Attention Is All You Need相关的知识,希望对你有一定的参考价值。
Transformer:
- 模型结构:
- Encoder:
- Position Embedding:引入位置信息,DNN结构,默认没有考虑位置信息
- Multi-head Self-attention:模型中计算量最大的部分,Head(头)的数量是8,任意两两字符之间,计算相关性。
- LayerNorm & Residual:层归一化,和残差连接
- Feedforward Nenual Network:Self-attention位置混合,FFN通道混合,类似通道分离卷积(空间混合)和1x1卷积(通道混合),第1层2028,第2层512
- Decoder:Teacher Forcing
- Casual(因果) Multi-head Self-attention,下三角矩阵
- Memory-base Multi-head Cross-attention,Decoder是Query,Encoder是Key和Value,Key是转置
- Encoder:
- 使用类型:
- Encoder only:BERT、分类任务、非流式任务
- Decoder only:**GPT(Generative Pre-trained Transformer)**系列、语言建模、自回归生成任务、流式任务
- Encoder-Decoder:机器翻译、语音识别
- 特定:
- 无先验假设,例如局部关联性、有序建模
- 核心在于自注意力机制,平方复杂度
- 数据量的要求与先验假设的程度成反比
先验假设(归纳偏置) 与 数据(样本)量,成反比:
- 归纳偏置(Inductive Bias):在学习算法中,当学习器去预测其未遇到过的输入结果时,所做的一些假设的集合。
- Transformer计算量以序列长度的平方成正比。
- 基于先验假设,优化模型,例如降低计算量,要注入先验假设。
- Transformer长时建模性长,并行计算,对比与RNN或LSTM
Transformer的Loss函数
PyTorch中,CrossEntropy的输入,期望Class放在第2维,Batch放在第1维,可以是类别索引(Class indices),也可以是类别的概率(Probabilities for each class)。
reduction默认是mean,例如6个单词的平均交叉熵。reduction是none,默认交叉熵:先做softmax,再做-ln(prob)
参考:CLIP算法的Loss详解 和 交叉熵CrossEntropy实现
# 定义softmax函数
def softmax(x):
return np.exp(x) / np.sum(np.exp(x))
# 利用numpy计算
def cross_entropy_np(x, y):
x_softmax = [softmax(x[i]) for i in range(len(x))]
x_log = [np.log(x_softmax[i][y[i]]) for i in range(len(y))]
loss = - np.sum(x_log) / len(y)
return loss
# 测试逻辑
x = [[1.9269, 1.4873, 0.9007, -2.1055]]
y = [[2]]
v1 = cross_entropy_np(x, y)
print(f"v1: v1")
x = torch.unsqueeze(torch.Tensor(x), dim=0)
x = x.transpose(1, 2) # CrossEntropy输入期望: Class放在第2维,Batch放在第1维
y = torch.Tensor(y)
y = y.to(torch.long) # label的类型为long
v2 = F.cross_entropy(x, y, reduction="none")
print(f"v2: v2")
随机种子:torch.manual_seed(42)
,每个rand之前,都需要添加
构建序列建模的Mask,如下:
import torch
import torch.nn as nn
import torch.nn.functional as F
import random
import numpy as np
# batch_size=2, seqlen=3, vocab_size=4
torch.manual_seed(42)
logits = torch.randn(2, 3, 4)
logits = logits.transpose(1, 2)
print(f'[Info] logits.shape: logits.shape')
print(f'[Info] logits: \\nlogits')
# logits_softmax = F.softmax(logits, dim=1)
# print(f'[Info] logits_softmax: \\nlogits_softmax')
# batch_size=2, vocab_size=4
torch.manual_seed(42)
label = torch.randint(0, 4, (2, 3))
print(f'[Info] label.shape: label.shape')
print(f'[Info] label: \\nlabel')
# loss: torch.nn.CrossEntropyLoss -> F.cross_entropy
# (2x4x3) + (2x3) = (2x3)
val = F.cross_entropy(logits, label, reduction="none")
print(f"[Info] val.shape: val.shape")
print(f"[Info] val: \\nval")
# 在loss中, 增加mask, 与ignore_index参数功能类似,默认值是-100
tgt_len = torch.Tensor([2,3]).to(torch.int32)
mask = [F.pad(torch.ones(L), (0, max(tgt_len)-L)) for L in tgt_len]
mask = torch.stack(mask)
print(f"[Info] mask: \\nmask")
val = F.cross_entropy(logits, label, reduction="none") * mask
print(f"[Info] val.shape: val.shape")
print(f"[Info] val: \\nval")
# 与ignore_index参数功能类似,默认值是-100
label[0, 2] = -100
val = F.cross_entropy(logits, label, reduction="none")
print(f"[Info] val.shape: val.shape")
print(f"[Info] val: \\nval")
以上是关于PyTorch笔记 - Attention Is All You Need的主要内容,如果未能解决你的问题,请参考以下文章
PyTorch笔记 - Attention Is All You Need
PyTorch笔记 - Attention Is All You Need
PyTorch笔记 - Attention Is All You Need
PyTorch笔记 - Seq2Seq + Attention 算法