PyTorch
文章目錄
- PyTorch
- 前言
- 一、nn.Embedding的基本原理
- 二、nn.Embedding的實際應用
- 簡單的例子
- 自然語言處理任務
前言
在深度學習中,詞嵌入(Word Embedding)是一種常見的技術,用于將離散的詞匯或符號映射到連續的向量空間。這種映射使得相似的詞匯在向量空間中具有相似的向量表示,從而可以捕捉詞匯之間的語義關系。在PyTorch中,nn.Embedding模塊提供了一種簡單而高效的方式來實現詞嵌入。
一、nn.Embedding的基本原理
nn.Embedding是一個存儲固定大小的詞典的嵌入向量的查找表。給定一個編號,嵌入層能夠返回該編號對應的嵌入向量。這些嵌入向量反映了各個編號代表的符號之間的語義關系。在輸入一個編號列表時,nn.Embedding會輸出對應的符號嵌入向量列表。
在內部,nn.Embedding實際上是一個參數化的查找表,其中每一行都對應一個符號的嵌入向量。這些嵌入向量在訓練過程中通過反向傳播算法進行更新,以優化模型的性能。因此,nn.Embedding不僅可以用于降低數據的維度,減少計算和存儲開銷,還可以通過訓練學習輸入數據中的語義或結構信息。
二、nn.Embedding的實際應用
簡單的例子
import torch
from torch.nn import Embeddingclass Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()self.emb = Embedding(5, 3)def forward(self,vec):input = torch.tensor([0, 1, 2, 3, 4])emb_vec1 = self.emb(input)# print(emb_vec1) ### 輸出對同一組詞匯的編碼output = torch.einsum('ik, kj -> ij', emb_vec1, vec)return output
def simple_train():model = Model()vec = torch.randn((3, 1))label = torch.Tensor(5, 1).fill_(3)loss_fun = torch.nn.MSELoss()opt = torch.optim.SGD(model.parameters(), lr=0.015)print('初始化emebding參數權重:\n',model.emb.weight)for iter_num in range(100):output = model(vec)loss = loss_fun(output, label)opt.zero_grad()loss.backward(retain_graph=True)opt.step()# print('第{}次迭代emebding參數權重{}:\n'.format(iter_num, model.emb.weight))print('訓練后emebding參數權重:\n',model.emb.weight)torch.save(model.state_dict(),'./embeding.pth')return modeldef simple_test():model = Model()ckpt = torch.load('./embeding.pth')model.load_state_dict(ckpt)model=model.eval()vec = torch.randn((3, 1))print('加載emebding參數權重:\n', model.emb.weight)for iter_num in range(100):output = model(vec)print('n次預測后emebding參數權重:\n', model.emb.weight)if __name__ == '__main__':simple_train() # 訓練與保存權重simple_test()
訓練代碼
import torch
from torch.nn import Embeddingclass Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()self.emb = Embedding(5, 10)def forward(self,vec):input = torch.tensor([0, 1, 2, 3, 4])emb_vec1 = self.emb(input)print(emb_vec1) ### 輸出對同一組詞匯的編碼output = torch.einsum('ik, kj -> ij', emb_vec1, vec)print(output)return outputdef simple_train():model = Model()vec = torch.randn((10, 1))label = torch.Tensor(5, 1).fill_(3)print(label)loss_fun = torch.nn.MSELoss()opt = torch.optim.SGD(model.parameters(), lr=0.015)for iter_num in range(1):output = model(vec)loss = loss_fun(output, label)print('iter:%d loss:%.2f' % (iter_num, loss))opt.zero_grad()loss.backward(retain_graph=True)opt.step()if __name__ == '__main__':simple_train()
自然語言處理任務
在自然語言處理任務中,詞嵌入是一種非常有用的技術。通過將每個單詞表示為一個實數向量,我們可以將高維的詞匯空間映射到一個低維的連續向量空間。這有助于提高模型的泛化能力和計算效率。例如,在文本分類任務中,我們可以使用nn.Embedding將文本中的每個單詞轉換為嵌入向量,然后將這些向量輸入到神經網絡中進行分類。
以下是一個簡單的示例代碼,演示了如何在PyTorch中使用nn.Embedding進行文本分類:
import torch
import torch.nn as nn
# 定義詞嵌入層,詞典大小為10000,嵌入向量維度為128
embedding = nn.Embedding(num_embeddings=10000, embedding_dim=128)
# 假設我們有一個包含5個單詞的文本,每個單詞的編號分別為1, 2, 3, 4, 5
input_ids = torch.tensor([1, 2, 3, 4, 5], dtype=torch.long)
# 通過詞嵌入層將單詞編號轉換為嵌入向量
embedded = embedding(input_ids)
# 輸出嵌入向量的形狀:(5, 128)
print(embedded.shape)
# 定義神經網絡模型
class TextClassifier(nn.Module):def __init__(self, embedding_dim, hidden_dim, num_classes):super(TextClassifier, self).__init__()self.embedding = embeddingself.fc1 = nn.Linear(embedding_dim, hidden_dim)self.fc2 = nn.Linear(hidden_dim, num_classes)def forward(self, input_ids):embedded = self.embedding(input_ids)# 對嵌入向量進行平均池化,得到一個固定長度的向量表示整個文本pooled = embedded.mean(dim=0)# 通過全連接層進行分類logits = self.fc2(self.fc1(pooled))return logits
# 實例化模型并進行訓練...
上述代碼中,我們首先定義了一個詞嵌入層embedding,詞典大小為10000,嵌入向量維度為128。然后,我們創建了一個包含5個單詞的文本,每個單詞的編號分別為1到5。通過調用embedding(input_ids),我們將單詞編號轉換為嵌入向量。最后,我們定義了一個文本分類器模型TextClassifier,其中包含了詞嵌入層、全連接層等組件。在模型的前向傳播過程中,我們首先對嵌入向量進行平均池化,得到一個固定長度的向量表示整個文本,然后通過全連接層進行分類。
除了自然語言處理任務外,nn.Embedding還可以用于圖像處理任務。例如,在卷積神經網絡(CNN)中,嵌入層可以將圖像的像素值映射到一個高維的空間,從而更好地捕捉圖像中的復雜特征和結構。這有助于提高模型的性能和泛化能力。
需要注意的是,在圖像處理任務中,我們通常使用卷積層(nn.Conv2d)或像素嵌入層(nn.PixelEmbed)等模塊來處理圖像數據,而不是直接使用nn.Embedding。