# mypy: 允许未类型化定义
来自
打字
导入
可选
导入
火炬
来自
火炬
导入
张量
来自 torch.nn
导入
功能性
作为 F,
初始化
来自
torch.nn 参数
导入
参数
来自
.模块
导入
模块
__all__ = [嵌入,
嵌入包]
[文档]
类
嵌入(
模块):
r简单的查找表,存储固定字典和大小嵌入。
此模块通常用于存储词嵌入并使用索引检索它们。
模块的输入是一个索引列表,输出是对应的词嵌入。
词嵌入。
Args:
num_embeddings(整数):嵌入字典的大小
embedding_dim(整数):每个嵌入向量的大小
padding_idx(int,可选):如果指定,则:attr:`padding_idx`处的条目不参与梯度计算;
因此,在训练过程中,:attr:`padding_idx`处的嵌入向量不会被更新
即它保持为固定的“填充”。对于新构建的 Embedding,
在:attr:`padding_idx`处的嵌入向量将默认为全零,
但也可以更新为另一个值作为填充向量。
the starting index position of each bag (sequence) in :attr:`input`。
如果给定,则将范数大于 :attr:`max_norm` 的每个嵌入向量重新归一化,使其范数为 :attr:`max_norm`。
norm_type (浮点数,可选): 用于计算 :attr:`max_norm` 选项的 p-norm 的 p 值。默认 ``2``。
scale_grad_by_freq (布尔值,可选): 如果提供,则将梯度按 mini-batch 中单词的频率的倒数进行缩放。默认 ``False``。
the words in the mini-batch. Default ``False``.
sparse(布尔值,可选):如果为 ``True``,则相对于 :attr:`weight` 矩阵的梯度将是一个稀疏张量。
更多有关稀疏梯度的详细信息,请参阅注释。
属性:
weight(Tensor):该模块的可学习权重,形状为(num_embeddings,embedding_dim)
从 :math:`\mathcal{N}(0, 1)` 初始化
形状:
- 输入::math:`(*)`, 形状任意的 IntTensor 或 LongTensor,包含要提取的索引
- 输出::math:`(*, H)`,其中 `*` 是输入形状,:math:`H=\text{embedding\_dim}`
.. 注意::
请注意,只有有限数量的优化器支持
稀疏梯度:目前是 :class:`optim.SGD` (`CUDA` 和 `CPU`)
class:`optim.SparseAdam` (`CUDA` 和 `CPU`)以及 :class:`optim.Adagrad` (`CPU`)
.. 注意::
当 :attr:`max_norm` 不为 ``None`` 时,:class:`Embedding` 的前向方法将修改
attr:`weight` 张量。由于梯度计算所需的张量不能被
在原地修改,在对 `Embedding.weight` 执行可微操作之前
调用 :class:`Embedding` 的前向方法时,需要克隆 `Embedding.weight`
attr:`max_norm` 不为 `None`。例如:
n, d, m = 3, 5, 7
embedding = nn.Embedding(n, d, max_norm=1.0)
W = torch.randn((m, d), requires_grad=True)
idx = torch.tensor([1, 2])
a = embedding.weight.clone() @ W.t() # weight must be cloned for this to be differentiable
b = embedding(idx) @ W.t() # 修改权重
out = (a.unsqueeze(0) + b.unsqueeze(1))
loss = out.sigmoid().prod()
loss.backward()
示例:
>>> # 包含 10 个大小为 3 的张量的嵌入模块
>>> embedding = nn.Embedding(10, 3)
>>> # 两个样本的 4 个索引批次
>>> input = torch.LongTensor([[1, 2, 4, 5], [4, 3, 2, 9]])
>>> # xdoctest: +IGNORE_WANT("非确定性")
>>> embedding(input)
tensor([[[ -0.0251, -1.6902, 0.7172],
[-0.6431, 0.0748, 0.6969],
[1.4970, 1.3448, -0.9685]
[-0.3677, -2.7265, -0.1685]
[[1.4970, 1.3448, -0.9685], [1.4970, 1.3448, -0.9685]]
[0.4362, -0.4004, 0.9400]
[-0.6431, 0.0748, 0.6969]
[ 0.9124, -2.3616, 1.1151]
>>> 示例中使用 padding_idx
>>> embedding = nn.Embedding(10, 3, padding_idx=0)
>>> input = torch.LongTensor([[0, 2, 0, 5]])
>>> embedding(input)
tensor([[[ 0.0000, 0.0000, 0.0000],
[ 0.1535, -2.0309, 0.9315],
[0.0000, 0.0000, 0.0000]
[-0.1655, 0.9897, 0.0635]]])
>>> # 示例:更改 `pad` 向量
>>> padding_idx = 0
>>> embedding = nn.Embedding(3, 3, padding_idx=padding_idx)
>>> embedding.weight
包含参数:
tensor([[ 0.0000, 0.0000, 0.0000],
[-0.7895, -0.7089, -0.0364],
[[0.6778, 0.5803, 0.2678]], requires_grad=True)
>>> with torch.no_grad():
... embedding.weight[padding_idx] = torch.ones(3)
>>> embedding.weight
包含参数:
tensor([[ 1.0000, 1.0000, 1.0000],
[-0.7895, -0.7089, -0.0364]
[0.6778, 0.5803, 0.2678], requires_grad=True
"源代码"
常量 = [
num_embeddings,
embedding_dim,
"padding_idx",
"max_norm",
"norm_type",
"scale_grad_by_freq",
"稀疏",
]
num_embeddings: 整型
嵌入维度:
整型
填充索引:
可选[int]
最大范数:
可选[float]
归一化类型:
浮点数
按频率缩放梯度:
布尔类型
重量:
张量
冻结:
布尔类型
稀疏:
布尔类型
def 初始化(
self,
嵌入数量: int,
嵌入维度: int,
填充索引:
可选[int] =
无,
最大范数:
可选[float] =
无,
归一化类型:
浮点数 = 2.0,
按频率缩放梯度:
布尔类型 =
错误,
稀疏:
布尔类型 =
错误,
权重:
可选[
张量] =
无,
冻结:
布尔类型 =
错误,
设备=
无,
数据类型=
无,
) -> 无:
工厂参数 = {
"设备":
设备, "dtype":
数据类型}
超级().
初始化()
self.嵌入数量 =
嵌入数量
self.嵌入维度 =
嵌入维度
如果 padding_idx
是 not
无:
如果 padding_idx > 0:
断言 (
padding_idx < self.嵌入数量
), "Padding_idx 必须在 num_embeddings 范围内"
elif padding_idx < 0:
断言 (
padding_idx >= -self.嵌入数量
), "Padding_idx 必须在 num_embeddings 范围内"
padding_idx = self.嵌入数量 + padding_idx
self.padding_idx = padding_idx
self.max_norm = max_norm
self.规范类型 =
规范类型
self.scale_grad_by_freq = scale_grad_by_freq
如果 _weight
是
无:
self.权重 =
参数(
火炬.
空的((
嵌入数量, embedding_dim), **
工厂参数),
需要梯度=not
冻结,
)
self.重置参数()
否则:
断言
列表(
重量.shape) == [
嵌入数量,
嵌入维度,
]
权重的形状与 num_embeddings 和 embedding_dim 不匹配
self.权重 =
参数(
权重,
需要梯度=not
冻结)
self.稀疏的 =
稀疏的
def 重置参数(self) ->
无:
初始化.
正常的(self.
重量)
self.用零填充填充索引()
def 用零填充填充索引(self) ->
无:
如果 self.padding_idx
是 not
无:
与
火炬.
不梯度():
self.重量[self.
填充索引].
填充_(0)
def 前向(self,
输入:
张量) ->
张量:
返回 F.
嵌入(
输入,
self.重量,
self.填充索引,
self.最大范数,
self.归一化类型,
self.按频率缩放梯度,
self.稀疏,
)
def 额外表示(self) ->
字符串:
s = "{num_embeddings}, {embedding_dim}"
如果 self.padding_idx
是 not
无:
s += ", padding_idx="{padding_idx}"
如果 self.max_norm
是 not
无:
s += ", 最大范数="
{最大范数}"
如果 self.
规范类型 != 2:
s += ", 范数类型="{norm_type}"
如果 self.
缩放梯度频率
是 not
错误:
s += ",按频率调整梯度="
{按频率调整梯度}"
如果 self.
稀疏的
是 not
错误:
s += ",稀疏=True"
返回 s.
格式(**self.
字典)
[文档] @classmethod
def from_pretrained(
类,
嵌入,
冻结=True,
填充索引=
无,
最大范数=
无,
归一化类型=2.0,
按频率缩放梯度=
错误,
稀疏=
错误,
):
r从给定的二维 FloatTensor 创建嵌入实例。
Args:
嵌入(Tensor):包含嵌入权重的 FloatTensor。
第一维传递给嵌入作为 num_embeddings,第二维作为 embedding_dim。
freeze (bool, 可选): 如果为 ``True``,则张量在学习过程中不会更新。
等同于 ``embedding.weight.requires_grad = False``。默认:``True``。
padding_idx(int,可选):如果指定,则:attr:`padding_idx`处的条目不参与梯度计算;
因此,在训练过程中,:attr:`padding_idx`处的嵌入向量不会被更新
即保持为固定的“填充”。
max_norm (float, 可选): 请参阅模块初始化文档。
norm_type (float, 可选): 请参阅模块初始化文档。默认 ``2``。
scale_grad_by_freq (布尔值,可选): 请参阅模块初始化文档。默认 ``False``。
sparse (布尔值,可选): 请参阅模块初始化文档。
示例:
>>> # 包含预训练权重的 FloatTensor
>>> weight = torch.FloatTensor([[1, 2.3, 3], [4, 5.1, 6.3]])
>>> embedding = nn.Embedding.from_pretrained(weight)
>>> # 获取索引 1 的嵌入
>>> input = torch.LongTensor([1])
>>> # xdoctest: +IGNORE_WANT("非确定性")
>>> embedding(input)
tensor([[4.0000, 5.1000, 6.3000]])
"源代码"
断言 (
嵌入.
暗淡() == 2
), 嵌入参数预期为二维
行,
列 =
嵌入.
形状
嵌入 =
类(
嵌入数量=
行,
嵌入维度=
列(复数),
权重=
嵌入,
冻结=
冻结,
填充索引=
填充索引,
最大范数=
最大范数,
归一化类型=
归一化类型,
按频率缩放梯度=
按频率缩放梯度,
稀疏=
稀疏,
)
返回
嵌入
[文档]
类 EmbeddingBag(
模块):
r计算不实例化中间嵌入的嵌入“包”的总和或平均值。
对于长度恒定的包,没有:attr:`per_sample_weights`,没有索引等于:attr:`padding_idx`,
并且对于 2D 输入,此类
* 使用 `mode="sum"` 等同于 `torch.nn.Embedding` 后跟 `torch.sum(dim=1)`,
使用 `mode="mean"` 等同于 `:class:`~torch.nn.Embedding` 后跟 `torch.mean(dim=1)`,
使用 `mode="max"` 等同于 `:class:`~torch.nn.Embedding` 后跟 `torch.max(dim=1)`。
然而,`:class:`~torch.nn.EmbeddingBag` 相比使用这些链式操作在时间和内存效率上要高得多。
操作。
EmbeddingBag 还支持将样本权重作为参数传递给前向传播。
在执行加权降维之前,此操作放大了嵌入的输出。指定的 ``mode``。
如果传递了 :attr:`per_sample_weights`,则仅支持 ``"sum"" 模式,该模式根据 :attr:`per_sample_weights` 计算加权总和。
仅支持 ``"sum"" 模式,该模式根据 :attr:`per_sample_weights` 计算加权总和。
仅支持 ``"sum"" 模式,该模式根据 :attr:`per_sample_weights` 计算加权总和。
Args:
num_embeddings (int): 嵌入字典的大小
embedding_dim (int): 每个嵌入向量的大小
the starting index position of each bag (sequence) in :attr:`input`。
如果给定,则将范数大于 :attr:`max_norm` 的每个嵌入向量重新归一化,使其范数为 :attr:`max_norm`。
norm_type (浮点数,可选): 用于计算 :attr:`max_norm` 选项的 p-norm 的 p 值。默认 ``2``。
scale_grad_by_freq (布尔值,可选): 如果提供,这将通过梯度的频率的倒数来缩放梯度。
the words in the mini-batch. Default ``False``.
注意:当 ``mode="max"`` 时,此选项不受支持。
mode (str, 可选): ``"sum"``, ``"mean"`` 或 ``"max"``。指定减少袋的方式。
``"sum"`` 计算加权求和,考虑 :attr:`per_sample_weights`。``"mean"`` 计算值的平均值
``"sum"`` 计算加权求和,考虑 :attr:`per_sample_weights`。``"mean"`` 计算值的平均值
在包中,`"max"` 计算每个包的最大值。
默认: ``"mean"``
稀疏(布尔值,可选):如果为 `True`,则相对于 `:attr:`weight` 矩阵的梯度将是一个稀疏张量。详见
稀疏梯度的更多详细信息。注意:当 `mode="max"` 时,此选项不受支持。
不支持。
include_last_offset (bool, 可选): 如果为 ``True``,则 :attr:`offsets` 有一个额外的元素,该元素
等价于 `indices` 的大小。这与 CSR 格式相匹配。
padding_idx (int, 可选): 如果指定,则 :attr:`padding_idx` 位置的条目不贡献梯度;因此,:attr:`padding_idx` 的嵌入向量不会更新。
padding_idx (int, 可选): 如果指定,则 :attr:`padding_idx` 位置的条目不贡献梯度;因此,:attr:`padding_idx` 的嵌入向量不会更新。
在训练期间,即它保持为固定的 "pad"。对于新构建的
EmbeddingBag,:attr:`padding_idx` 处的嵌入向量将默认为全
零向量,但可以更新为另一个值作为填充向量。
注意,在 :attr:`padding_idx` 的嵌入向量被排除在外。
。
属性:
权重(Tensor):该模块的可学习权重,形状为 `(num_embeddings, embedding_dim)`。
从 :math:`\mathcal{N}(0, 1)` 初始化。
示例:
>>> # 包含 10 个大小为 3 的张量的 EmbeddingBag 模块
>>> embedding_sum = nn.EmbeddingBag(10, 3, mode='sum')
>>> # 两个样本的 4 个索引批次
>>> input = torch.tensor([1, 2, 4, 5, 4, 3, 2, 9], dtype=torch.long)
>>> offsets = torch.tensor([0, 4], dtype=torch.long)
>>> # xdoctest: +IGNORE_WANT("非确定性")
>>> embedding_sum(input, offsets)
tensor([[-0.8861, -5.4350, -0.0523],
[ 1.1306, -2.5798, -1.0044]])
>>> # 示例使用 padding_idx
>>> embedding_sum = nn.EmbeddingBag(10, 3, mode='sum', padding_idx=2)
>>> input = torch.tensor([2, 2, 2, 2, 4, 3, 2, 9], dtype=torch.long)
>>> offsets = torch.tensor([0, 4], dtype=torch.long)
>>> embedding_sum(input, offsets)
tensor([[ 0.0000, 0.0000, 0.0000],
[-0.7082, 3.2145, -2.6251]])
>>> # An EmbeddingBag can be loaded from an Embedding like so
>>> embedding = nn.Embedding(10, 3, padding_idx=2)
>>> embedding_sum = nn.EmbeddingBag.from_pretrained(
>>> embedding.weight,
padding_idx=embedding.padding_idx,
mode='sum')
"源代码"
常量 = [
num_embeddings,
embedding_dim,
"max_norm",
"norm_type",
"scale_grad_by_freq",
模式,
"稀疏",
"include_last_offset",
"padding_idx",
]
嵌入数量:
整型
嵌入维度:
整型
最大范数:
可选[float]
归一化类型:
浮点数
按频率缩放梯度:
布尔类型
重量:
张量
模式:
字符串
稀疏:
布尔类型
include_last_offset: 布尔类型
填充索引:
可选[int]
def 初始化(
self,
嵌入数量: int,
嵌入维度: int,
最大范数:
可选[float] =
无,
归一化类型:
浮点数 = 2.0,
按频率缩放梯度:
布尔类型 =
错误,
模式:
字符串 =
平均值,
稀疏:
布尔类型 =
错误,
权重:
可选[
张量] =
无,
include_last_offset: 布尔类型 =
错误,
填充索引:
可选[int] =
无,
设备=
无,
数据类型=
无,
) -> 无:
工厂参数 = {
"设备":
设备, "dtype":
数据类型}
超级().
初始化()
self.嵌入数量 =
嵌入数量
self.嵌入维度 =
嵌入维度
self.max_norm = max_norm
self.规范类型 =
规范类型
self.scale_grad_by_freq = scale_grad_by_freq
如果 padding_idx
是 not
无:
如果 padding_idx > 0:
断言 (
padding_idx < self.num_embeddings
), "padding_idx 必须在 num_embeddings 范围内"
elif padding_idx < 0:
断言 (
padding_idx >= -self.num_embeddings
), "padding_idx 必须在 num_embeddings 范围内"
padding_idx = self.num_embeddings + padding_idx
self.padding_idx = padding_idx
如果 _weight
是
无:
self.权重 =
参数(
火炬.
空的((
嵌入数量,
嵌入维度), **
工厂参数)
)
self.重置参数()
否则:
断言
列表(
_权重.shape) == [
嵌入数量,
嵌入维度,
]
权重形状与 num_embeddings 和 embedding_dim 不匹配
self.权重 =
参数(
_权重)
self.模式 =
模式
self.稀疏的 =
稀疏的
self.包含最后一个偏移量 =
包含最后一个偏移量
def 重置参数(self) ->
无:
初始化.
正常的(self.
重量)
self._填充填充索引为零()
def _填充填充索引为零(self) ->
无:
如果 self.padding_idx
是 not
无:
与
火炬.
不梯度():
self.重量[self.
填充索引].
填充_(0)
[文档] def 前向(
self,
输入:Tensor,
偏移量:Optional[Tensor] = None,
每个样本的权重:Optional[Tensor] = None,
)-> Tensor:
嵌入包的前向传递。
参数:
输入(张量):包含嵌入矩阵索引包的张量。
偏移量(张量,可选):仅在 `input` 为 1D 时使用。`offsets` 决定
每个包(序列)在 :attr:`input` 中的起始索引位置
per_sample_weights(Tensor,可选):一个浮点/双精度权重张量,或 None
以指示所有权重都应视为 ``1``。如果指定,:attr:`per_sample_weights`
必须与输入具有完全相同的形状,并被视为具有相同的
如果 `offsets` 不为 `None`。仅支持 `mode='sum'` 模式。
返回值:
张量输出形状为 `(B, embedding_dim)`。
.. 注意:
一些关于 `input` 和 `offsets` 的说明:
- :attr:`input` 和 :attr:`offsets` 必须是同一类型,要么是 int,要么是 long
- 如果 :attr:`input` 是形状为 `(B, N)` 的 2D,它将被视为 `B` 个袋子(序列)
每个长度为 `N` 的固定长度,这将返回 `B` 个值,以某种方式聚合
根据 :attr:`mode` 的不同。在这种情况下,:attr:`offsets` 被忽略,并且必须为 ``None``。
如果 :attr:`input` 是形状为 `(N)` 的 1D,它将被视为多个包(序列)的连接。
因此,:attr:`offsets` 必须是一个包含每个包在 :attr:`input` 中起始索引位置的 1D 张量。
因此,对于形状为 `(B)` 的 :attr:`offsets`,
":attr:`输入` 将被视为拥有 ``B`` 个包。空包(即长度为 0 的包)将
返回填充为零的向量。
"""
返回 F.embedding_bag(
输入,
self.weight,
偏移量,
self.max_norm,
self.norm_type,
self.scale_grad_by_freq,
self.mode,
self.sparse,
per_sample_weights,
self.include_last_offset,
self.padding_idx,
)
def 额外表示(self) ->
字符串:
s = "{num_embeddings}, {embedding_dim}"
如果 self.max_norm
是 not
无:
s += ", 最大范数="{max_norm}"
如果 self.
规范类型 != 2:
s += ", norm_type="{norm_type}"
如果 self.scale_grad_by_freq
是 not
错误:
s += ", scale_grad_by_freq="{scale_grad_by_freq}"
s += ", 模式="
{模式}"
如果 self.padding_idx
是 not
无:
s += ", 填充索引="
{填充索引}"
返回 s.
格式(**{k:
表示(v)
为 k, v
在 self.
字典.
项目()})
[文档] @classmethod
def 预训练(
类,
嵌入:
张量,
冻结:
布尔类型 = True,
最大范数:
可选[float] =
无,
归一化类型:
浮点数 = 2.0,
按频率缩放梯度:
布尔类型 =
错误,
模式:
字符串 =
平均值,
稀疏:
布尔类型 =
错误,
include_last_offset: 布尔类型 =
错误,
填充索引:
可选[int] =
无,
) -> "嵌入袋":
r"""从给定的二维 FloatTensor 创建 EmbeddingBag 实例。
Args:
embeddings (Tensor):FloatTensor 包含 EmbeddingBag 的权重。
第一维度作为 'num_embeddings' 传递给 EmbeddingBag,第二维度作为 'embedding_dim'。
freeze (bool,可选):如果为 ``True``,则张量在训练过程中不会被更新。
等同于 ``embeddingbag.weight.requires_grad = False``。默认:``True``。
max_norm (浮点数,可选): 请参阅模块初始化文档。默认: ``None``
norm_type (浮点数,可选): 请参阅模块初始化文档。默认 ``2``.
scale_grad_by_freq (布尔值,可选): 请参阅模块初始化文档。默认 ``False``.
mode (字符串,可选): 请参阅模块初始化文档。默认: ``"mean"``
sparse (bool, 可选): 请参阅模块初始化文档。默认:``False``。
include_last_offset (bool, 可选): 请参阅模块初始化文档。默认:``False``。
padding_idx (int, 可选): 请参阅模块初始化文档。默认:``None``。
示例:
>>> # FloatTensor 包含预训练权重
>>> weight = torch.FloatTensor([[1, 2.3, 3], [4, 5.1, 6.3]])
>>> embeddingbag = nn.EmbeddingBag.from_pretrained(weight)
>>> # 获取索引 1 的嵌入
>>> input = torch.LongTensor([[1, 0]])
>>> # xdoctest: +IGNORE_WANT("非确定性")
>>> embeddingbag(input)
张量([[ 2.5000, 3.7000, 4.6500]])
"源代码"
断言 (
嵌入.
暗淡() == 2
), 嵌入参数预期为二维
行,
列 =
嵌入.
形状
嵌入包 =
类(
嵌入数量=
行,
嵌入维度=
列(复数),
_权重=
嵌入,
最大范数=
最大范数,
归一化类型=
归一化类型,
按频率缩放梯度=
按频率缩放梯度,
模式=
模式,
稀疏=
稀疏,
include_last_offset=include_last_offset,
填充索引=
填充索引,
)
嵌入包.
重量.requires_grad = not
冻结
返回
嵌入包