一、什麼是torch.nn.embedding
torch.nn.embedding是PyTorch的一個模塊,是神經網絡中一個重要的embedding層,廣泛應用於自然語言處理(NLP)中。對於一段文本,可以將每個單詞用一個向量表示,向量的長度由用戶指定,這些向量組成的矩陣就稱為“embedding矩陣”。通過embedding層的轉換,可以將原始信息變成計算機可用的向量,並幫助神經網絡結構自動學習語義信息。
關於embedding的實現方式,比較常見的有One-Hot編碼、預訓練向量和自適應embedding。One-Hot編碼是將每個單詞表示為一個稀疏的高維向量,向量的維度為單詞表的大小。預訓練向量是將每個單詞表示為一個維度固定的稠密向量,這些向量可以通過線性變換等方式預先訓練獲得。自適應embedding則是通過神經網絡在訓練過程中動態學習單詞的嵌入向量。
import torch.nn as nn import torch # 定義一個embedding矩陣 emb = nn.Embedding(num_embeddings=100, embedding_dim=10) # 隨機生成一個長度為5的序列 input_seq = torch.randint(low=0, high=100, size=(1, 5)) # 將序列映射為embedding表示 emb_seq = emb(input_seq) print(emb_seq)
這段代碼定義了一個embedding矩陣,將矩陣的大小設置為(100, 10),表示有100個單詞,每個單詞用10維的向量表示。接着,使用torch.randint隨機生成一個長度為5的序列,並將其映射為對應的embedding向量。最終,輸出了一個大小為(1, 5, 10)的矩陣。
二、torch.nn.embedding的使用方法
1、num_embeddings和embedding_dim
torch.nn.embedding的參數中,num_embeddings表示詞表的大小,即最大單詞數。embedding_dim表示每個單詞使用的嵌入維度大小。一般而言,embedding_dim的大小與模型的複雜度和單詞量成正比。num_embeddings和embedding_dim的設置對訓練效果有很大的影響,需要根據實際情況進行調節。
import torch.nn as nn import torch # 定義一個embedding矩陣 emb = nn.Embedding(num_embeddings=100, embedding_dim=10) print(emb.weight.shape)
這段代碼定義了一個embedding矩陣,將矩陣的大小設置為(100, 10),表示有100個單詞,每個單詞用10維的向量表示。接着,使用emb.weight.shape輸出了矩陣的大小。
2、padding_idx
在自然語言處理中,一般會將不同長度的文本轉換為固定長度的向量。然而,如果直接在不同長度之間加入0來實現padding,則可能導致模型計算時出錯。padding_idx這個參數則是用來解決此問題的,它指定了padding的單詞在embedding矩陣中的下標。這樣,在實際計算時就可以跳過這個下標對應的單詞。
import torch.nn as nn import torch # 定義一個embedding矩陣 emb = nn.Embedding(num_embeddings=100, embedding_dim=10, padding_idx=0) # 定義一個長度為4的序列,其中包含0 input_seq = torch.tensor([0, 1, 2, 0]) # 將序列映射為embedding表示 emb_seq = emb(input_seq) print(emb_seq)
這段代碼定義了一個embedding矩陣,將矩陣的大小設置為(100, 10),padding_idx為0。接着,定義一個長度為4的序列,其中包含0,並將其映射為對應的embedding向量。最終,輸出了一個大小為(4, 10)的矩陣。
3、max_norm和norm_type
在訓練中,我們可以使用max_norm和norm_type這兩個參數控制嵌入向量的大小。max_norm指定了最大的範數大小,norm_type指定使用哪種範數計算向量大小。通過限制嵌入向量的大小,可以避免過度參數化,進而克服過擬合問題。
import torch.nn as nn import torch # 定義一個embedding矩陣,指定max_norm和norm_type emb = nn.Embedding(num_embeddings=100, embedding_dim=10, max_norm=1.0, norm_type=2.0) # 隨機生成一個長度為5的序列 input_seq = torch.randint(low=0, high=100, size=(1, 5)) # 將序列映射為embedding表示 emb_seq = emb(input_seq) print(emb_seq)
這段代碼定義了一個embedding矩陣,將矩陣的大小設置為(100, 10),max_norm為1,norm_type為2。接着,使用torch.randint隨機生成一個長度為5的序列,並將其映射為對應的embedding向量。最終,輸出了一個大小為(1, 5, 10)的矩陣。
三、torch.nn.embedding的應用場景
1、文本分類
在文本分類任務中,需要將每個單詞轉換為一個向量,並將整個文本表示為一個向量。可以使用torch.nn.embedding將每個單詞映射為一個指定維度的向量,並將這些向量按照順序連接成一個新的向量作為整個文本的表示。
import torch.nn as nn import torch # 定義一個embedding矩陣 emb = nn.Embedding(num_embeddings=100, embedding_dim=10) # 定義一個長度為5的序列 input_seq = torch.tensor([1, 2, 3, 4, 5]) # 將序列映射為embedding表示 emb_seq = emb(input_seq) # 對embedding結果進行池化操作 pooled_seq = torch.mean(emb_seq, dim=0) # 獲取整個文本的表示向量 text_repr = pooled_seq.unsqueeze(0) print(text_repr)
這段代碼定義了一個embedding矩陣,將矩陣的大小設置為(100, 10)。接着,定義一個長度為5的序列,並將其映射為對應的embedding向量。接着,使用torch.mean對embedding結果進行池化操作,並通過unsqueeze(0)將結果轉換為一個大小為(1, 10)的矩陣,作為整個文本的表示向量。
2、語言模型
在語言模型任務中,需要根據先前的單詞預測下一個單詞。可以使用torch.nn.embedding將每個單詞映射為一個指定維度的向量,並訓練一個RNN等模型,將先前的單詞作為輸入,預測下一個單詞。
import torch.nn as nn import torch # 定義一個embedding矩陣 emb = nn.Embedding(num_embeddings=100, embedding_dim=10) # 定義一段文本 input_seq = torch.tensor([1, 2, 3, 4, 5]) # 將整個文本映射為embedding表示 emb_seq = emb(input_seq) # 定義一個RNN模型 rnn = nn.RNN(input_size=10, hidden_size=20, batch_first=True) # 將embedding結果作為模型的輸入 output, hidden = rnn(emb_seq.unsqueeze(0)) print(output)
這段代碼定義了一個embedding矩陣,將矩陣的大小設置為(100, 10)。接着,定義一段文本,並將其映射為對應的embedding向量。接着,定義一個RNN模型,將embedding結果作為模型的輸入,得到模型的輸出。
3、詞嵌入可視化
使用torch.nn.embedding,可以將一個單詞表示為一個固定維度的向量。該向量包含了單詞的詞義信息。我們可以使用PCA等降維方法,將這些向量可視化在二維或三維空間中,從而直觀地了解單詞在語義上的相似性。
import torch.nn as nn import torch import matplotlib.pyplot as plt from sklearn.decomposition import PCA # 定義一個embedding矩陣 emb = nn.Embedding(num_embeddings=100, embedding_dim=10) # 得到嵌入向量集合 embeddings = emb.weight.detach().numpy() # 使用PCA進行降維 pca = PCA(n_components=2) pca_embeddings = pca.fit_transform(embeddings) # 繪製散點圖 words = ['word_%d'%i for i in range(100)] x = pca_embeddings[:,0] y = pca_embeddings[:,1] plt.scatter(x, y) for i, word in enumerate(words): plt.annotate(word, (x[i], y[i])) plt.show()
這段代碼定義了一個embedding矩陣,將矩陣的大小設置為(100, 10)。接着,使用PCA對矩陣降維。最後,通過matplotlib的scatter函數繪製散點圖,並在每個點上添加對應的點名。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/285131.html