Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Pytork中嵌入_Python_Pytorch_Word Embedding - Fatal编程技术网

Python 在Pytork中嵌入

Python 在Pytork中嵌入,python,pytorch,word-embedding,Python,Pytorch,Word Embedding,我已经检查了PyTorch教程以及与Stackoverflow类似的问题 我感到困惑;pytorch()中的嵌入是否会使相似的单词彼此更接近?我需要把所有的句子都给它吗?或者它只是一个查找表,我需要对模型进行编码?您可以将nn.Embedding视为一个查找表,其中关键字是单词索引,值是相应的单词向量。但是,在使用它之前,您应该指定查找表的大小,并自己初始化单词向量。下面的代码示例演示了这一点 将torch.nn导入为nn #vocab_size是训练集、val和测试集中的字数 #vector_

我已经检查了PyTorch教程以及与Stackoverflow类似的问题


我感到困惑;pytorch()中的嵌入是否会使相似的单词彼此更接近?我需要把所有的句子都给它吗?或者它只是一个查找表,我需要对模型进行编码?

您可以将
nn.Embedding
视为一个查找表,其中关键字是单词索引,值是相应的单词向量。但是,在使用它之前,您应该指定查找表的大小,并自己初始化单词向量。下面的代码示例演示了这一点

将torch.nn导入为nn
#vocab_size是训练集、val和测试集中的字数
#vector_size是您正在使用的单词向量的维度
嵌入=nn.嵌入(声音大小、向量大小)
#初始化单词向量,预训练的权重是
#大小的numpy数组(vocab_size、vector_size)和
#预训练的_权重[i]检索
#词汇表中的第i个单词
embed.weight.data.copy_(torch.fromnumpy(预训练的_权重))
#然后将单词索引转换为实际的单词向量
vocab={“some”:0,“words”:1}
word_索引=[some”,“words”]]中w的[vocab[w]
单词向量=嵌入(单词索引)

nn.嵌入
包含维度的张量
(词汇大小,向量大小)
,即词汇的大小x每个向量嵌入的维度,以及执行查找的方法

创建嵌入层时,会随机初始化张量。只有当你训练它时,相似的单词之间才会出现这种相似性。除非您已经用以前训练过的模型(如GloVe或Word2Vec)覆盖了嵌入的值,但这是另一回事

因此,一旦定义了嵌入层,定义并编码了词汇表(即为词汇表中的每个单词指定一个唯一的编号),就可以使用nn.embedding类的实例来获得相应的嵌入

例如:

import torch
from torch import nn
embedding = nn.Embedding(1000,128)
embedding(torch.LongTensor([3,4]))

将返回与词汇表中的单词3和4对应的嵌入向量。由于没有训练过模型,因此它们将是随机的。

啊!我想这部分还是不见了。显示当您设置嵌入层时,您会自动获得权重,稍后您可以使用
nn.Embedding.from\u预训练(重量)

输出:

<class 'torch.nn.modules.sparse.Embedding'>
Embedding(10, 4)
torch.Size([10, 4])
tensor([[-0.7007,  0.0169, -0.9943, -0.6584],
        [-0.7390, -0.6449,  0.1481, -1.4454],
        [-0.1407, -0.1081,  0.6704, -0.9218],
        [-0.2738, -0.2832,  0.7743,  0.5836],
        [ 0.4950, -1.4879,  0.4768,  0.4148],
        [ 0.0826, -0.7024,  1.2711,  0.7964],
        [-2.0595,  2.1670, -0.1599,  2.1746],
        [-2.5193,  0.6946, -0.0624, -0.1500],
        [ 0.5307, -0.7593, -1.7844,  0.1132],
        [-0.0371, -0.5854, -1.0221,  2.3451]], grad_fn=<EmbeddingBackward>)
torch.Size([3, 4])
tensor([[-0.7390, -0.6449,  0.1481, -1.4454],
        [-0.1407, -0.1081,  0.6704, -0.9218],
        [-0.2738, -0.2832,  0.7743,  0.5836]], grad_fn=<EmbeddingBackward>)
torch.Size([2, 3])

tensor([[0.1000, 0.2000, 0.3000],
        [0.4000, 0.5000, 0.6000]])

嵌入(10,4)
火炬尺寸([10,4])
张量([-0.7007,0.0169,-0.9943,-0.6584],
[-0.7390, -0.6449,  0.1481, -1.4454],
[-0.1407, -0.1081,  0.6704, -0.9218],
[-0.2738, -0.2832,  0.7743,  0.5836],
[ 0.4950, -1.4879,  0.4768,  0.4148],
[ 0.0826, -0.7024,  1.2711,  0.7964],
[-2.0595,  2.1670, -0.1599,  2.1746],
[-2.5193,  0.6946, -0.0624, -0.1500],
[ 0.5307, -0.7593, -1.7844,  0.1132],
[-0.0371,-0.5854,-1.0221,2.3451]],梯度fn=)
火炬尺寸([3,4])
张量([-0.7390,-0.6449,0.1481,-1.4454],
[-0.1407, -0.1081,  0.6704, -0.9218],
[-0.2738,-0.2832,0.7743,0.5836]],梯度fn=)
火炬尺寸([2,3])
张量([[0.1000,0.2000,0.3000],
[0.4000, 0.5000, 0.6000]])

最后一部分是,嵌入层权重可以通过梯度下降来学习。

torch.nn。嵌入只需创建一个查找表,以获得给定单词索引的单词嵌入

from collections import Counter
import torch.nn as nn

# Let's say you have 2 sentences(lowercased, punctuations removed) :
sentences = "i am new to PyTorch i am having fun"

words = sentences.split(' ')
    
vocab = Counter(words) # create a dictionary
vocab = sorted(vocab, key=vocab.get, reverse=True)
vocab_size = len(vocab)

# map words to unique indices
word2idx = {word: ind for ind, word in enumerate(vocab)} 

# word2idx = {'i': 0, 'am': 1, 'new': 2, 'to': 3, 'pytorch': 4, 'having': 5, 'fun': 6}

encoded_sentences = [word2idx[word] for word in words]

# encoded_sentences = [0, 1, 2, 3, 4, 0, 1, 5, 6]

# let's say you want embedding dimension to be 3
emb_dim = 3 
现在,嵌入层可以初始化为:

emb_layer = nn.Embedding(vocab_size, emb_dim)
word_vectors = emb_layer(torch.LongTensor(encoded_sentences))
这将从标准正态分布(即0均值和单位方差)初始化嵌入。因此,这些词向量没有任何“关联性”的意义

单词_向量是大小为(9,3)的火炬张量。(因为我们的数据中有9个单词)

emb_层有一个称为权重的可训练参数,默认情况下,该参数设置为训练。您可以通过以下方式进行检查:

emb_layer.weight.requires_grad
这是真的。如果您不想在模型培训期间培训嵌入(例如,当您使用预培训的嵌入时),可以通过以下方式将其设置为False:

emb_layer.weight.requires_grad = False
如果您的词汇量为10000,并且您希望使用预先培训过的嵌入(例如Word2Vec)初始化嵌入,请按照以下步骤操作:

emb_layer.load_state_dict({'weight': torch.from_numpy(emb_mat)})
这里,emb_mat是一个大小为(10000300)的Numpy矩阵,包含词汇表中10000个单词中每个单词的300维Word2vec单词向量


现在,嵌入层加载了Word2Vec单词表示。

所以我仍然不知道在整个训练过程中学习这些随机初始化的嵌入的方法。这是一个简单的CBOW或Skip-gram过程还是其他什么?重点是nn.Embedding不在乎你用什么方法来训练单词embeddings,它只是一个“矩阵”来存储训练过的嵌入。使用nn.Embedding加载外部单词嵌入(如手套或FastText)时,这些外部单词嵌入的职责是确定训练方法。如果您选择在训练期间微调单词向量,这些词向量被视为模型参数,并通过反向传播进行更新。是
nn。嵌入
是可训练层吗?是的,
nn。嵌入
也是模型参数层,默认情况下可训练,您也可以通过冻结其梯度使其不可训练。例如,如果我有一个神经机器翻译模型,而我不使用预先训练的嵌入,那么嵌入层将随机初始化单词向量并将这些向量与翻译模型一起训练,确切地说,它们将是随机的,并且将是模型的可训练参数。我主要想知道在经过训练的模型中学习到的嵌入是如何应用于测试数据的。例如,我有大约20000个单词,我已经把它们转换成了数字,并进行了嵌入。现在,在测试集中,如果我有一个[3,2,5,4]序列,模型权重是否已经包含了一种进行因子分解和嵌入的方法?我只是不太确定这门课的数学
emb_layer.load_state_dict({'weight': torch.from_numpy(emb_mat)})