Transformer代碼詳解與項目實戰之Position Encoding

因爲Transformer模型並不包括任何的循環(recurrence)或卷積,所以給模型添加位置編碼,爲模型提供一些關於單詞在句子中相對位置的信息。
位置信息實現方式有兩種:1、在模型中訓練得到;2、直接使用公式計算。論文中使用的第二種方式,此處對第二種方式進行解析。
在這裏插入圖片描述
如圖所示:pos代表單詞在句子中的位置,i代表單詞向量中每一個數值的位置。一般,句子長度使用seq_len表示,詞向量長度使用num_units或depth表示。
具體實現代碼如下:

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

def positional_encoding(seq_len, num_units, visualization=False):
	"""
	:param seq_len: 語句的長度
	:param num_units: 詞向量的長度
	:param visualization: 是否畫圖展示位置編碼內容
	:return: [1,seq_len,num_units]
	"""
	def __get_angles(pos, i, d_model):
		"""
		:param pos: 單詞在語句中的位置序列,爲[seq_len,1]矩陣
		:param i: 詞向量中的位置序列,爲[1,d_model]矩陣
		:param d_model: 詞向量的長度
		:return: [seq_len,d_model]
		"""
		angle_rates = 1 / np.power(10000, (2 * (i // 2)) / np.float32(d_model))
		return pos * angle_rates

	#np.arange(seq_len)[:, np.newaxis]:使用seq_len長度序列產生向量,然後擴展一維,變成兩維向量
	pos_encoding = __get_angles(np.arange(seq_len)[:, np.newaxis],
							  np.arange(num_units)[np.newaxis, :],
							  num_units)

	#分別對奇數位置和偶數位置的數據進行sin和cos計算
	#方法一、雙層遍歷的方法
	# for i in range(pos_encoding.shape[0]):
	# 	for j in range(pos_encoding.shape[1]):
	# 		if j % 2 == 0:
	# 			pos_encoding[i][j] = np.sin(pos_encoding[i][j])
	# 		else:
	# 			pos_encoding[i][j] = np.cos(pos_encoding[i][j])

	#方法二:第二維按層計算
	pos_encoding[:, 0::2] = np.sin(pos_encoding[:, 0::2])
	pos_encoding[:, 1::2] = np.cos(pos_encoding[:, 1::2])

	pos_encoding = pos_encoding[np.newaxis, ...]

	if visualization:
		plt.figure(figsize=(12, 8))
		plt.pcolormesh(pos_encoding[0], cmap='RdBu')
		plt.xlabel('Depth')
		plt.xlim((0, num_units))
		plt.ylabel('Position')
		plt.colorbar()
		plt.show()

	return tf.cast(pos_encoding, tf.float32)

if "__main__" == __name__:

    positional_encoding(5, 8, visualization=True)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章