nn.Embedding的前向傳播與反向傳播
nn.Embedding
的前向計算過程
embedding module 的前向過程其實是一個索引(查表)的過程
表的形式是一個 matrix(embedding.weight, learnable parameters)
matrix.shape: (v, h)
v:vocabulary size=num_embedding
h:hidden dimension=embedding_dim
僅從數學的角度來說(方便推導模型),具體索引的過程,可以通過 one hot + 矩陣乘法的形式實現的
input.shape: (b, s)
> b:batch size
> s:seq len當執行下行代碼時,會進行如下計算 embed = embedding(input) > input.shape(b,s) e.g [[0, 2, 2,1]]
> 最終的維度變化情況:(b, s) ==> (b, s, h)1.(b, s) 經過 one hot => (b, s, v)
inputs: [[0, 2, 2, 1 , 1]]
inputs One-Hot: 數值分類(0-4 => 五分類) 0:[1,0,0,0,0][[[1,0,0,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,1,0,0,0],[0,1,0,0,0]]]
matrix(embedding.weight):[[ 1.0934, 1.7521, -1.9529, -1.0145, 0.5770],[-0.4371, -0.4270, -0.4908, -0.3988, 0.9695],[ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],[ 0.7268, -0.4491, -0.8089, 0.7516, 1.2716],[ 0.7785, -0.4336, -0.7542, -0.1953, 0.9711]]
2.(b, s, v) @ (v, h) ==> (b, s, h)
x(b, s, h):[[[ 1.0934, 1.7521, -1.9529, -1.0145, 0.5770],[ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],[ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],[-0.4371, -0.4270, -0.4908, -0.3988, 0.9695],[-0.4371, -0.4270, -0.4908, -0.3988, 0.9695]]]
但本質上,embedding(input)
是一個內存尋址的過程:
假設 inputs 是一個包含詞索引的張量,i是數值化文本 inputs上的Token,weight 是嵌入矩陣。對于每個索引 i,嵌入向量 v_i 對應的計算過程是:v_i=embedding.weight[i]
nn.Embedding
的反向傳播過程
只有前向傳播中用到的索引會接收梯度。
假如反向傳播過來的梯度是 [0.1,0.1,0.3] ,原始的embedding矩陣= [[1. ,1. ,1.],[1. ,1. ,1.]] , lr=0.1
那么 反向傳播以后embedding的參數就為 [[1. ,1. ,1.],[1. ,1. ,1.]] - 1 * [[0.1,0.1,0.3],[0.,0.,0.]]
即 [[0.99. ,0.99 ,0.97],[1. ,1. ,1.]]