文章目录
-
- [1、Environment construction](#1、Environment construction)
-
- [1.1 macos conda](#1.1 macos conda)
- [1.2 macos PyTorch](#1.2 macos PyTorch)
- [1.3 iTerm settings](#1.3 iTerm settings)
- [1.4 install jupyter](#1.4 install jupyter)
- [2、beam search](#2、beam search)
-
- [2.1 greedy search](#2.1 greedy search)
- [2.2 exhaustive search](#2.2 exhaustive search)
- [2.3 beam search](#2.3 beam search)
- [3、Attention score](#3、Attention score)
-
- [3.1 Masking softmax operation](#3.1 Masking softmax operation)
- [3.2 Additive attention](#3.2 Additive attention)
- [3.3 Zoom dot product attention](#3.3 Zoom dot product attention)
- [3.4 brief summary](#3.4 brief summary)
- [4、Transformer framework](#4、Transformer framework)
-
- [4.1 Multi head attention](#4.1 Multi head attention)
- [4.2 Masked multi head attention](#4.2 Masked multi head attention)
- [4.3 Location based feedforward network](#4.3 Location based feedforward network)
- [4.5 Normalization of layers](#4.5 Normalization of layers)
- [4.6 Communication](#4.6 Communication)
- [4. 7 Prediction](#4. 7 Prediction)
- [4.8 brief summary](#4.8 brief summary)
- [5、Bug resolution](#5、Bug resolution)
-
- [5.1 error: subprocess-exited-with-error](#5.1 error: subprocess-exited-with-error)
- [5.2 macos run old items test torch](#5.2 macos run old items test torch)
- [5.3 Run 'conda init' before 'conda activate'](#5.3 Run 'conda init' before 'conda activate')
- [5.4 d2l items run test](#5.4 d2l items run test)
- [5.5 'pkgutil' has no attribute 'ImpImporter'. mean: 'zipimporter'](#5.5 'pkgutil' has no attribute 'ImpImporter'. mean: 'zipimporter')
- [5.6 connection broken by 'ConnectTimeoutError...](#5.6 connection broken by 'ConnectTimeoutError...)
1、Environment construction
- macOS 主力建设,目前还有大部分项目都是在windows上运行,现在开始慢慢适应,并进行迁移。
1.1 macos conda
- 在macos 尝试用安装win方式安装conda
- 初见成效现在选择安装镜像
1.2 macos PyTorch
- 在官网选择对应版本即可,注意⚠️选择conda 命令安装,不要选择pip 命令安装。
python
conda install pytorch::pytorch torchvision torchaudio -c pytorch
1.3 iTerm settings
- 关于在iTrem 命令行使用conda 命令找不到的情况解决
个人理解:在iTerm中报错,但是在系统自带的终端没有报错。联想到在win中的环境变量的问题。
- 在终端输入以下命令进入"编辑环境变量"
- 关于vim的使用在Linux学习中已使用
python
vim ~/.zshrc
最后输入下面代码进行保存
python
source ~/.zshrc
1.4 install jupyter
python
pip3 --default-timeout=600 install jupyter
- 准备启动jupyter,输入
jupyter notebook
即可
启动成功 🚀
2、beam search
- 束搜索Beam Search 是一种启发式图搜索算法,常用于解决序列生成任务,如机器翻译、语音识别、文本摘要等。它是对广度优先搜索的一种优化,通过减少搜索宽度来提高搜索效率,同时尽量保证找到的解的质量。
基本思想
束搜索的基本思想是在每一步扩展中,不是扩展所有可能的节点,而是只扩展有限数目(称为束宽,Beam Width)的最有可能产生最优解的节点。这样,束搜索就可以在有限的计算资源下,尽可能找到最优解或近似最优解。
- 在序列生成问题中,常用的方法是一个个词元地进行生成,但是先前步生成的词元会影响之后词元的概率分布,为此,我们需要使用搜索算法来得到一个较好的序列
2.1 greedy search
贪心搜索即每个时间步都选择具有最高条件概率的词元。
y t ′ = argmax y ∈ Y P ( y ∣ y 1 , ... , y t ′ − 1 , c ) y_{t'} = \operatorname*{argmax}{y \in \mathcal{Y}} P(y \mid y_1, \ldots, y{t'-1}, \mathbf{c}) yt′=y∈YargmaxP(y∣y1,...,yt′−1,c)
我们的目标是找到一个最有序列,他的联合概率,也就是每步之间的条件概率的乘积,最大。
∏ t ′ = 1 T ′ P ( y t ′ ∣ y 1 , ... , y t ′ − 1 , c ) \prod_{t'=1}^{T'} P(y_{t'} \mid y_1, \ldots, y_{t'-1}, \mathbf{c}) t′=1∏T′P(yt′∣y1,...,yt′−1,c)
然而,贪心搜索很可能搜索到的不是最优解,例如:
左侧的搜索方式为贪心搜索,每次找到当前条件概率最大的选项进行预测,但是这样可能会导致之后的条件概率较小,从而导致最终的联合概率较小,生成的序列不优。
- 而右侧的选择方式虽然在第二步选择了较小的选项,但之后在第三步时有了条件概率为0.6选项,最终结果反而更好。
2.2 exhaustive search
穷举搜索枚举所有可能的输出序列及其概率,然后选择概率最大的作为最终的输出,枚举搜索可以保证得到最优解,但是计算复杂度很高,难以实现
这里直接是暴力求解
2.3 beam search
- 束搜索综合了贪心搜索和穷举搜索,在能接受的计算成本下得到比贪心搜索更好的结果。
束搜索有一个超参数,名为束宽(beam size) k k k,束搜索的具体流程如下:
-
1:在第一时间步选择条件概率最高的k个选项
-
2:对随后的每个时间步,基于上一时间步的k个候选输出序列预测这一时间步的所有可能选项的条件概率,从中取k个最大的
-
3:最后基于每步得到的序列,删去截止符和其后元素,获得最终候选序列集合,取出加权条件概率最大的
加权条件概率公式如下:
1 L α log P ( y 1 , ... , y L ∣ c ) = 1 L α ∑ t ′ = 1 L log P ( y t ′ ∣ y 1 , ... , y t ′ − 1 , c ) , \frac{1}{L^\alpha} \log P(y_1, \ldots, y_{L}\mid \mathbf{c}) = \frac{1}{L^\alpha} \sum_{t'=1}^L \log P(y_{t'} \mid y_1, \ldots, y_{t'-1}, \mathbf{c}), Lα1logP(y1,...,yL∣c)=Lα1t′=1∑LlogP(yt′∣y1,...,yt′−1,c),
式中 1 L α \frac{1}{L^\alpha} Lα1用于调整长序列的评估值使得长短序列间的比较公平
束宽k的选择:
- k=1时实际为贪心搜索
- k越小搜索速度越快,但结果越差,k越大则搜索速度越慢,但结果越好
束搜索只在测试时使用
3、Attention score
- 使用高斯核来对查询和键之间的关系建模。我们可以将 高斯核函数部分视为注意力评分函数,简称评分函数,然后把这个函数的输出结果输入到softmax函数中进行运算。 通过上述步骤,我们将得到与键对应的值的概率分布 (即注意力权重)。 最后,注意力汇聚的输出就是基于这些注意力权重的值的加权和。
3.1 Masking softmax operation
- 正如上面提到的,softmax操作用于输出一个概率分布作为注意力权重。 在某些情况下,并非所有的值都应该被纳入到注意力汇聚中。 例如,为了在 点击跳转中高效处理小批量数据集, 某些文本序列被填充了没有意义的特殊词元 。 为了仅将有意义的词元作为值来获取注意力汇聚, 我们可以指定一个有效序列长度(即词元的个数), 以便在计算softmax时过滤掉超出指定范围的位置。 通过这种方式,我们可以在下面的
masked_softmax
函数中 实现这样的掩蔽softmax操作(masked softmax operation), 其中任何超出有效长度的位置都被掩蔽并置为0。
python
def masked_softmax(X, valid_lens):
"""通过在最后一个轴上掩蔽元素来执行softmax操作"""
# X:3D张量,valid_lens:1D或2D张量
if valid_lens is None:
return nn.functional.softmax(X, dim=-1)
else:
shape = X.shape
if valid_lens.dim() == 1:
valid_lens = torch.repeat_interleave(valid_lens, shape[1])
else:
valid_lens = valid_lens.reshape(-1)
# 最后一轴上被掩蔽的元素使用一个非常大的负值替换,从而其softmax输出为0
X = d2l.sequence_mask(X.reshape(-1, shape[-1]), valid_lens,
value=-1e6)
return nn.functional.softmax(X.reshape(shape), dim=-1)
3.2 Additive attention
- 一般来说,当查询和键是不同长度的矢量时, 我们可以使用加性注意力作为评分函数。
python
class AdditiveAttention(nn.Module):
"""加性注意力"""
def __init__(self, key_size, query_size, num_hiddens, dropout, **kwargs):
super(AdditiveAttention, self).__init__(**kwargs)
self.W_k = nn.Linear(key_size, num_hiddens, bias=False)
self.W_q = nn.Linear(query_size, num_hiddens, bias=False)
self.w_v = nn.Linear(num_hiddens, 1, bias=False)
self.dropout = nn.Dropout(dropout)
def forward(self, queries, keys, values, valid_lens):
queries, keys = self.W_q(queries), self.W_k(keys)
# 在维度扩展后,
# queries的形状:(batch_size,查询的个数,1,num_hidden)
# key的形状:(batch_size,1,"键-值"对的个数,num_hiddens)
# 使用广播方式进行求和
features = queries.unsqueeze(2) + keys.unsqueeze(1)
features = torch.tanh(features)
# self.w_v仅有一个输出,因此从形状中移除最后那个维度。
# scores的形状:(batch_size,查询的个数,"键-值"对的个数)
scores = self.w_v(features).squeeze(-1)
self.attention_weights = masked_softmax(scores, valid_lens)
# values的形状:(batch_size,"键-值"对的个数,值的维度)
return torch.bmm(self.dropout(self.attention_weights), values)
3.3 Zoom dot product attention
- 使用点积可以得到计算效率更高的评分函数, 但是点积操作要求查询和键具有相同的长度d。 假设查询和键的所有元素都是独立的随机变量, 并且都满足零均值和单位方差, 那么两个向量的点积的均值为0,方差为d。 为确保无论向量长度如何, 点积的方差在不考虑向量长度的情况下仍然是1, 我们将点积除以√d,在下面的缩放点积注意力的实现中,我们使用了暂退法进行模型正则化。
python
#@save
class DotProductAttention(nn.Module):
"""缩放点积注意力"""
def __init__(self, dropout, **kwargs):
super(DotProductAttention, self).__init__(**kwargs)
self.dropout = nn.Dropout(dropout)
# queries的形状:(batch_size,查询的个数,d)
# keys的形状:(batch_size,"键-值"对的个数,d)
# values的形状:(batch_size,"键-值"对的个数,值的维度)
# valid_lens的形状:(batch_size,)或者(batch_size,查询的个数)
def forward(self, queries, keys, values, valid_lens=None):
d = queries.shape[-1]
# 设置transpose_b=True为了交换keys的最后两个维度
scores = torch.bmm(queries, keys.transpose(1,2)) / math.sqrt(d)
self.attention_weights = masked_softmax(scores, valid_lens)
return torch.bmm(self.dropout(self.attention_weights), values)
3.4 brief summary
- 将注意力汇聚的输出计算可以作为值的加权平均,选择不同的注意力评分函数会带来不同的注意力汇聚操作。
- 当查询和键是不同长度的矢量时,可以使用可加性注意力评分函数。当它们的长度相同时,使用缩放的"点-积"注意力评分函数的计算效率更高。
4、Transformer framework
- 机器学习中的Transformer是一种基于自注意力机制的深度学习模型
一、定义与背景
- Transformer是一种完全摒弃了传统的循环神经网络(RNN)和卷积神经网络(CNN)结构的模型 ,它通过自注意力机制来计算输入序列中不同位置之间的依赖关系。这种模型架构在处理序列数据时展现出了强大的并行计算能力和对长距离依赖关系的捕捉能力。
二、模型架构
- Transformer模型主要由编码器(Encoder)和解码器(Decoder)两部分组成,每个部分都包含多个相同的层。具体来说:
编码器:将输入序列(如一句话)转化为一系列上下文表示向量(Contextualized Embedding)。每一层编码器都由自注意力层(Self-Attention Layer)和前馈全连接层(Feedforward Layer)组成,通过多层堆叠来提取序列的深层特征。
解码器:将编码器的输出和目标序列(如翻译后的句子)作为输入,生成目标序列中每个位置的概率分布。解码器同样包含多个层,但每一层除了自注意力层和前馈全连接层外,还增加了一个编码器-解码器注意力层(Encoder-Decoder Attention Layer),用于将解码器当前位置的输入与编码器的所有位置进行交互,以获得与目标序列有关的信息。
三、核心机制
- 自注意力机制:Transformer的核心部分,允许模型在处理序列时,将输入序列中的每个元素与其他元素进行比较,以便在不同上下文中正确地处理每个元素。具体计算过程包括查询矩阵Q、键矩阵K和值矩阵V的生成,以及通过点积运算和softmax函数计算注意力权重,最终得到加权和向量作为输出。
多头注意力机制 :为了进一步提高模型的性能,Transformer引入了多头注意力机制。通过将自注意力机制应用于多组不同的Q、K、V矩阵,模型能够学习到序列中不同位置的多种表示,从而捕捉到更丰富的上下文信息。
位置编码:由于Transformer模型本身不包含循环或卷积结构,无法直接捕捉序列中的位置信息。因此,Transformer通过位置编码将位置信息嵌入到输入向量中,以确保模型能够理解序列中元素的顺序。
- 基于encoder-decoder架构来处理序列对
- 跟使用注意力的seq2seq不同,transformer是纯基于注意力
4.1 Multi head attention
-
对同一key,value,query,希望抽取不同的信息
- 例如短距离关系和长距离关系
-
多头注意力使用h个独立的注意力池化
- 合并各个头(head)输出得到最终输出
4.2 Masked multi head attention
- 解码器对序列中一个元素输出的时候,不应该考虑该元素之后的元素
- 可以用掩码来实现
- 也就是计算 x i x_i xi输出的时候,假装当前序列长度为i
4.3 Location based feedforward network
- 将输入形状变化(b,n,d)变换成(bn,d);输出形状由(bn,d)变成(b,n,d)
- 作用两个全连接层
- 等价于两层核窗口为1的一维卷积层(全连接)
4.5 Normalization of layers
- 批量归一化对每个特征/通道里元素进行归一化
- 不适合序列长度会变的nlp应用
- 层归一化对每个样本里面的元素进行归一化( layer norm )
4.6 Communication
- 将编码器输出作为解码中第i个transformer块中多头注意力的key和value
- query来自目标序列
- 意味着编码器和解码器中块的个数,输出维度都是一样的
4. 7 Prediction
- 预测第t+1个输出时
- 解码器中输入前t个预测值(顺序)
- 在自注意力中,前t个预测值作为key和value,第t个预测值还作为query
4.8 brief summary
-
transformer是一个纯使用注意力的encoder-decoder
-
编码器和解码器都有n个transformer块
-
每个块里面使用多头注意力,基于位置的前馈网络,层归一化
-
多头注意力,concat和相加取平均怎么选择?
- 老师认为concat保留的信息更全面,更好
-
为什么在获取词向量之后,需要对词向量进行缩放(乘以embedding size的开方之后再加上PE)
- embedding之后,向量长度变长,元素值变小,乘以之后可以保证在-1,1之间,和position大小差不多
-
num of head是什么?
- 类似卷积的多通道,多个attention关注的是不同的特征
5、Bug resolution
5.1 error: subprocess-exited-with-error
解决方法:
- 直接重新安装合适版本的setuptools即可。
python
pip uninstall setuptools
pip install setuptools==69.0.0
pip install <your-package>
python
sudo pip install -e .
bash
pip install --upgrade setuptools
5.2 macos run old items test torch
在新环境中运行旧项目,先测试一下torch
进入安装 pytorch 的环境中,然后查看环境
bash
pip install torch==2.3.1 torchvision==0.18.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
成功运行
5.3 Run 'conda init' before 'conda activate'
首先运行 conda init --system --all
其次运行 conda init zsh
即重置终端
- 操作成功,已成功进入虚拟环境
5.4 d2l items run test
5.5 'pkgutil' has no attribute 'ImpImporter'. mean: 'zipimporter'
- AttributeError: module 'pkgutil' has no attribute 'ImpImporter'. Did you mean: 'zipimporter'?
[end of output] - ModuleNotFoundError: No module named 'd2l'
解决办法
1、从PyPI下载d2l源码。
2、解压缩源码,更改setup.py文件里的requirements。
bash
requirements = [
'jupyter==1.0.0',
'numpy==1.26.3',
'matplotlib==3.8.2',
'matplotlib-inline==0.1.6',
'requests==2.31.0',
'pandas==2.2.0',
'scipy==1.12.0'
]
3、安装修改后的源码:python3 setup.py install。
5.6 connection broken by 'ConnectTimeoutError...
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError...
Python
pip install [whatyouwant] -i url
- 只要把[whatyouwant]替换成自己需要的包就好啦!搞定!
其实问题本身大家看报错就能看出来,主要就是连接超时了,所以我们只要用一些国内的pip源就可以完美的解决。
下面有几个国内的pip源,供大家参考:
阿里云 http://mirrors.aliyun.com/pypi/simple/
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/