- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
import
torch
from
torch.nn
import
Embedding
from
torch.nn
import
Linear
import
numpy
as
np
torch
.
manual_seed
(
1
)
<torch._C.Generator at 0x7f89641806d0>
最近遇到的网络模型许多都已Embedding层作为第一层,但回想前几年的网络,多以Linear层作为第一层。两者有什么区别呢?
Embedding层的作用是将有限集合中的元素,转变成指定size的向量。这个有限集合可以使NLP中的词汇表,可以使分类任务中的label,当然无论是什么,最终都要以元素索引传递给Embedding。 例如,将包含3个元素的词汇表W={'优', '良', '差'}中的每个元素转换为5维向量。如下所示:
# 先定义一个Embedding层:
emb
=
Embedding
(
num_embeddings
=
3
,
embedding_dim
=
5
)
# 转换第一个元素
emb
(
torch
.
tensor
([
0
],
dtype
=
torch
.
int64
))
tensor([[ 0.6589, 0.4041, 1.1573, -2.3446, -0.1704]], grad_fn=<EmbeddingBackward0>)
# 转换第二个元素
emb
(
torch
.
tensor
([
1
],
dtype
=
torch
.
int64
))
tensor([[ 0.6609, -0.1838, -1.8531, 2.6256, -0.9550]], grad_fn=<EmbeddingBackward0>)
# 转换第三个元素
emb
(
torch
.
tensor
([
2
],
dtype
=
torch
.
int64
))
tensor([[-0.3594, 0.0348, -1.0858, -0.6675, 1.9936]], grad_fn=<EmbeddingBackward0>)
如果超出词库规模,就会产生异常错误:
# 转换第四个元素
emb
(
torch
.
tensor
([
3
],
dtype
=
torch
.
int64
))
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) Cell In [29], line 2 1 # 转换第四个元素 ----> 2 emb ( torch . tensor ( [ 3 ] , dtype = torch . int64 ) ) File ~/apps/anaconda3/envs/pytorch_1_13_0/lib/python3.10/site-packages/torch/nn/modules/module.py:1190 , in Module._call_impl (self, *input, **kwargs) 1186 # If we don't have any hooks, we want to skip the rest of the logic in 1187 # this function, and just call forward. 1188 if not ( self . _backward_hooks or self . _forward_hooks or self . _forward_pre_hooks or _global_backward_hooks 1189 or _global_forward_hooks or _global_forward_pre_hooks): -> 1190 return forward_call ( * input , * * kwargs ) 1191 # Do not call functions when jit is used 1192 full_backward_hooks, non_full_backward_hooks = [], [] File ~/apps/anaconda3/envs/pytorch_1_13_0/lib/python3.10/site-packages/torch/nn/modules/sparse.py:160 , in Embedding.forward (self, input) 159 def forward ( self , input : Tensor) - > Tensor: --> 160 return F . embedding ( 161 input , self . weight , self . padding_idx , self . max_norm , 162 self . norm_type , self . scale_grad_by_freq , self . sparse ) File ~/apps/anaconda3/envs/pytorch_1_13_0/lib/python3.10/site-packages/torch/nn/functional.py:2210 , in embedding (input, weight, padding_idx, max_norm, norm_type, scale_grad_by_freq, sparse) 2204 # Note [embedding_renorm set_grad_enabled] 2205 # XXX: equivalent to 2206 # with torch.no_grad(): 2207 # torch.embedding_renorm_ 2208 # remove once script supports set_grad_enabled 2209 _no_grad_embedding_renorm_(weight, input , max_norm, norm_type) -> 2210 return torch . embedding ( weight , input , padding_idx , scale_grad_by_freq , sparse ) IndexError : index out of range in self
初始时,所有向量表示都是随机的,但却并非一成不变的,例如在NLP任务中,随着网络的训练,表示'优'与'良'的两个向量相似度会逐渐减小,而表示'优'与'差'的两个向量相似度会逐渐增大.
接下来我们详细说说pytorch中Embedding层的使用方法。Embedding类主要参数如下:
num_embeddings (int) - 嵌入字典的大小,即共有多少个元素需要转换 。
embedding_dim (int) - 每个嵌入向量的大小,即转换后获得向量的size 。
padding_idx (int, optional) - 如果提供的话,输出遇到此下标时用零填充 。
max_norm (float, optional) - 如果提供的话,会重新归一化词嵌入,使它们的范数小于提供的值 。
norm_type (float, optional) - 对于max_norm选项计算p范数时的p 。
scale_grad_by_freq (boolean, optional) - 如果提供的话,会根据字典中单词频率缩放梯度 。
weight weight (Tensor) -形状为(num_embeddings, embedding_dim)的模块中可学习的权值 。
Embedding是怎么实现的呢?其实,在初始化Embedding层时,Embedding会根据默认随机初始化num_embeddings * embedding_dim的正态分布的权重。以上面例子为例,我们看看它的参数:
emb
.
weight
Parameter containing: tensor([[ 0.6589, 0.4041, 1.1573, -2.3446, -0.1704], [ 0.6609, -0.1838, -1.8531, 2.6256, -0.9550], [-0.3594, 0.0348, -1.0858, -0.6675, 1.9936]], requires_grad=True)
仔细观察这些权重值,每一行都与上方{'优', '良', '差'}对应。当我们在emb中输入张量torch.tensor([0])时,输出了第一行,当我们在emb中输入张量torch.tensor([1])时,输出了第二行。所以,我们可以猜测,Embedding的工作原理就是初始化一个指定shape的矩阵,在进行转换是,根据输入的tensor值,索引矩阵的行。确实如此,Embedding源码就是这么做的.
当然,Embedding的权重参数也不一定非得随机初始化,也可以手动指定。如下所示,我们先手动初始化一个3 * 5的矩阵,然后将其作为Embedding的权重参数:
# 随机初始化一个3 * 5 的矩阵
emb_weight
=
torch
.
rand
(
3
,
5
,
requires_grad
=
True
)
这里需要注意,手动初始化参数时,最好设置requires_grad=True,后续训练时才能更新权重.
emb_weight
tensor([[0.4766, 0.1663, 0.8045, 0.6552, 0.1768], [0.8248, 0.8036, 0.9434, 0.2197, 0.4177], [0.4903, 0.5730, 0.1205, 0.1452, 0.7720]], requires_grad=True)
# 通过这个预先定义的矩阵,初始化Embedding层
emb2
=
Embedding
.
from_pretrained
(
emb_weight
)
# 转换第一个元素
emb2
(
torch
.
tensor
([
0
],
dtype
=
torch
.
int64
))
tensor([[0.7576, 0.2793, 0.4031, 0.7347, 0.0293]])
# 查看所有权重参数
emb2
.
weight
Parameter containing: tensor([[0.7576, 0.2793, 0.4031, 0.7347, 0.0293], [0.7999, 0.3971, 0.7544, 0.5695, 0.4388], [0.6387, 0.5247, 0.6826, 0.3051, 0.4635]])
这种手动指定参数参数话Embedding层的方式在迁移学习中非常实用,例如在NLP任务中,我们可以使用开源的词向量模型进行初始化,使得我们的模型更快收敛.
Linear层是最古老、最基础的一种网络结构了,作用是对输入向量进行线性变换,输出指定size的向量。例如,将size为3的向量,转为size为5的向量:
# 初始化一个Linear层
lin
=
Linear
(
in_features
=
3
,
out_features
=
5
)
# 随机初始化一个size为3的向量
x
=
torch
.
rand
(
3
)
x
tensor([0.7140, 0.2676, 0.9906])
x
.
shape
torch.Size([3])
# 经Linear层进行转换
y
=
lin
(
x
)
y
tensor([ 0.1443, 0.7431, -0.1405, -0.3098, -0.1214], grad_fn=<AddBackward0>)
y
.
shape
torch.Size([5])
Linear类就3个参数:
参数也简单,不多说。我们来介绍Linear的工作原理。Linear的本质就是矩阵相乘,公式如下: $$Y=XW^T+B$$ 式中,$X$是我们输入的向量,$W$是Linear层的权重参数,$B$是偏置向量。我们分别输出看看:
w
=
lin
.
weight
w
Parameter containing: tensor([[-0.0520, 0.0837, -0.0023], [ 0.5047, 0.1797, -0.2150], [-0.3487, -0.0968, -0.2490], [-0.1850, 0.0276, 0.3442], [ 0.3138, -0.5644, 0.3579]], requires_grad=True)
b
=
lin
.
bias
b
Parameter containing: tensor([ 0.1613, 0.5476, 0.3811, -0.5260, -0.5489], requires_grad=True)
我们尝试进行手动运算:
x
.
matmul
(
w
.
T
)
+
b
tensor([ 0.1443, 0.7431, -0.1405, -0.3098, -0.1214], grad_fn=<AddBackward0>)
看,结果与上方直接使用Linear层进行转换也是一样的.
Linear层的参数也可以进行手动修改:
lin_weight
=
torch
.
rand
(
3
,
5
,
requires_grad
=
True
)
lin_weight
tensor([[0.0555, 0.8639, 0.4259, 0.7812, 0.6607], [0.1251, 0.6004, 0.6201, 0.1652, 0.2628], [0.6705, 0.5896, 0.2873, 0.3486, 0.9579]], requires_grad=True)
from
torch.nn
import
Parameter
不过必须转为Parameter才能成功:
lin
.
weight
=
Parameter
(
lin_weight
)
Embedding只针对数据集规模有限的离散型数据,Linear即可用于离散型数据,也可用于连续型数据,且对数据集规模无限制。对于Embedding能实现的功能,Liner都能实现,只不过需要先进性一次手动one-hot编码.
Embedding本质是通过元素的索引,获取矩阵对应行作为输出,而Linear本质是矩阵相乘.
最后此篇关于Pytorch之Embedding与Linear的爱恨纠葛的文章就讲到这里了,如果你想了解更多关于Pytorch之Embedding与Linear的爱恨纠葛的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我想替换以下特定于 Mozilla 的 CSS 规则: background: -moz-linear-gradient(center top , #F5F5F5, #E4E4E4); 使用标准 li
我正在将 MatLab 程序转换为 Python,我无法理解为什么 scipy.interpolate.interp2d(linear) 给出的结果与 MatLab interp2(linear) 不
我目前在自然语言处理方面开发的应用程序存在严重的性能问题。基本上,对于给定的文本,它会收集各种数据并进行一些数字运算。 对于每一个句子,它的作用完全相同。用于收集统计数据的算法不会随着先前读取的数据而
我正在为一个基本的 Android 计算器开发水平 View ,我有一个名为 linearLayout2 的 LinearLayout > 我试图将它放在 linearLayout3 之上,其中包含数
我为按钮的背景使用了一些 CSS,但它在 Firefox、Chrome 和 IE 中看起来不同。 我正在使用 -webkit-linear-gradient 和 -moz-linear-gradien
TL;DR -webkit-linear-gradient 正在打破 -moz-linear-gradient 听说是个难题,我使用的是带有两个 handle 的 Jquery Slider 插件,我
我突然想到,例如,假设我们有二维 N 点的训练数据。我们知道我们总是可以天真地构建一个决策树,以便我们可以对每个数据点进行分类。 (可能我们过拟合了,深度可以到2N) 但是,我们知道如果数据集是线性可
我对插值函数的一般求根问题感兴趣。 假设我有以下 (x, y)数据: set.seed(0) x = x[i]) & (rroots <= x[i + 1])] ## next piece
我有一个线性优化目标来最大化 EE+FF,其中 EE 和 FF 每个都包含一些 C 和 D。 使用我编写的代码,我可以让求解器找到: EE_quantity: 0, FF_quantity: 7 ..
我一直在寻找这个问题,但我无法理解这个问题的含义。 问题: Write a program in any language to determine how your computer handles
我在 Python 中有一个简单的线性多元回归,如下所示: X_train,X_test,y_train,y_test=train_test_split(x_cols,df['Volume'],tes
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 10年前关闭。 Improve this
对于大型稀疏迭代(共轭梯度、MINRES、GMRES 等)线性代数系统求解,有哪些更好的库?我经常编写自己的程序,但我很想知道人们更喜欢哪种“现成的”软件包。我听说过 PETSc、TAUCS、IML+
这是我的全部问题: 信息: *最大限度。总投资:125美元 *支付是购买的单位x支付/单位的总和 *每笔投资成本:买入成本+成本/单位x单位数量(如果您购买至少一个单位) *费用为每笔投资费用之和 限
我有两个变量:x>= 0 和 y 二进制(0 或 1),我有一个常数 z >= 0。如何使用线性约束来描述以下条件: If x = z then y = 1 else y = 0. 我试图通过定义另一
我正在尝试做一些逻辑上应该可以做的事情。但是,我不确定如何在线性规划领域内做到这一点。我正在使用 ZMPL/SCIP,但这对大多数人来说应该是可读的。 set I := {1,2,3,4,5}; pa
我正在为我的期中考试做准备,我正在解决算法书中的一些问题,但似乎无法弄清楚以下问题: 在实数 a 和 b 上找出线性规划的充分必要条件 max: x+y ax + by 0 (a) 是不可行的。 (b
我正在做一个 Java 项目,我必须计算一个多元线性回归,但我希望得到的参数是非负的。是否有现有的商业友好许可图书馆来做这样的事情?我一直在寻找非负最小二乘库,但没有成功。 最佳答案 好吧,我找不到任
密集线性代数在现实世界中的常见应用是什么? 使用线性代数作为人机之间的通用语言,可以轻松描述和高效计算许多问题。尽管这些系统通常需要稀疏矩阵的解,而不是稠密矩阵。违反此规则的常见应用有哪些? 我很好奇
我如何找到 广义特征值、向量 使用 Eigen3 图书馆? 在 Octave ,matlab,特征值函数的形式是:[V, lambda] = eig (A, B) . 我只能找到 this 类(cla
我是一名优秀的程序员,十分优秀!