Transformer(1):embedding层和位置编码

Embedding层

1. 作用

将输入文本变成可以参与运算的词向量。

2. 方法

有一个词典Vec,储存所有的常见word,标上序号0,1,2,…这种,并且特殊字符也会有序号,比如起始和结尾标识,又比如<unkown>这种标签用来标识词典中不存在的字符word。

然后用一个可以学习的参数矩阵W,其中维度为[V_size, d_Model],V_size是词典大小,d_Model是转换之后word的向量表示,比如transformer里面就是512。

这样每次word转换成词向量,就等价于查询embedding里面的参数矩阵W,比如标号为i的word的词向量就是W的第i行。

3. 手写示例

import torch
import torch.nn as nn
import torch.optim as optim

# 1. embedding 模块
class MyEmbedding(nn.Module):
    def __init__(self, vocab_size, embedding_dim):
        super(MyEmbedding, self).__init__()
        self.weight = nn.Parameter(torch.randn(vocab_size, embedding_dim))
        
    def forward(self, input_ids):
        return self.weight[input_ids
在Vision Transformer中,1D位置嵌入2D位置编码是通过在输入的图像或序列中添加额外的位置信息来实现的。下面是实现1D位置嵌入2D位置编码的代码示例: 1. 1D位置嵌入 ```python import torch import torch.nn as nn class ViT(nn.Module): def __init__(self, img_size=224, patch_size=16, num_classes=1000, dim=768, depth=12, heads=12, mlp_dim=3072, dropout=0.1): super().__init__() self.num_patches = (img_size // patch_size) ** 2 self.patch_size = patch_size self.pos_embedding = nn.Parameter(torch.randn(1, self.num_patches + 1, dim)) self.patch_embed = nn.Conv2d(3, dim, kernel_size=patch_size, stride=patch_size, bias=False) self.cls_token = nn.Parameter(torch.randn(1, 1, dim)) self.dropout = nn.Dropout(dropout) self.transformer = nn.ModuleList([ nn.TransformerEncoderLayer(d_model=dim, nhead=heads, dim_feedforward=mlp_dim, dropout=dropout) for _ in range(depth) ]) self.fc = nn.Linear(dim, num_classes) def forward(self, x): b, c, h, w = x.shape x = self.patch_embed(x).flatten(2).transpose(1, 2) x = torch.cat([self.cls_token.repeat(b, 1, 1), x], dim=1) x = x + self.pos_embedding[:, :(self.num_patches + 1)] x = self.dropout(x) for transformer_layer in self.transformer: x = transformer_layer(x) x = x.mean(dim=1) x = self.fc(x) return x ``` 在这个代码中,`self.pos_embedding` 是一个可学习的参数,其 shape 为 `(1, num_patches + 1, dim)`,其中 `num_patches` 是输入图像被分成的 patch 的数量,`dim` 是 Transformer 的隐藏维度。`self.cls_token` 是一个用于表示整个序列或图像的特殊 token,它也是一个可学习的参数,其 shape 为 `(1, 1, dim)`。在 forward 函数中,我们首先对输入图像进行 patch embedding,然后将 cls token 位置嵌入加到 patch embedding 的结果中。最后,我们将得到的序列输入到 Transformer 中。 2. 2D位置编码 ```python import torch import torch.nn as nn class ViT(nn.Module): def __init__(self, img_size=224, patch_size=16, num_classes=1000, dim=768, depth=12, heads=12, mlp_dim=3072, dropout=0.1): super().__init__() self.num_patches = (img_size // patch_size) ** 2 self.patch_size = patch_size self.pos_embedding = nn.Parameter(torch.randn(1, dim, img_size // patch_size, img_size // patch_size)) self.patch_embed = nn.Conv2d(3, dim, kernel_size=patch_size, stride=patch_size, bias=False) self.cls_token = nn.Parameter(torch.randn(1, 1, dim)) self.dropout = nn.Dropout(dropout) self.transformer = nn.ModuleList([ nn.TransformerEncoderLayer(d_model=dim, nhead=heads, dim_feedforward=mlp_dim, dropout=dropout) for _ in range(depth) ]) self.fc = nn.Linear(dim, num_classes) def forward(self, x): b, c, h, w = x.shape x = self.patch_embed(x).flatten(2).transpose(1, 2) x = torch.cat([self.cls_token.repeat(b, 1, 1), x], dim=1) x = x + self.pos_embedding x = self.dropout(x) for transformer_layer in self.transformer: x = transformer_layer(x) x = x.mean(dim=1) x = self.fc(x) return x ``` 在这个代码中,`self.pos_embedding` 是一个可学习的参数,其 shape 为 `(1, dim, img_size // patch_size, img_size // patch_size)`,其中 `img_size // patch_size` 是输入图像被分成的 patch 的数量。在 forward 函数中,我们首先对输入图像进行 patch embedding,然后将 cls token 位置编码加到 patch embedding 的结果中。最后,我们将得到的序列输入到 Transformer 中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值