Я пытаюсь реализовать позиционное кодирование из Внимание - это все, что вам нужно , следуя этому хранилищу .Есть два конкретных блока кода, которые мне нужно будет добавить в мою модель, где оба находятся в этом файле .
Во-первых, мне нужно добавить функцию, которая преобразует массив в синусоидуone:
def get_sinusoid_encoding_table(n_position, d_hid, padding_idx=None):
''' Sinusoid position encoding table '''
def cal_angle(position, hid_idx):
return position / np.power(10000, 2 * (hid_idx // 2) / d_hid)
def get_posi_angle_vec(position):
return [cal_angle(position, hid_j) for hid_j in range(d_hid)]
sinusoid_table = np.array([get_posi_angle_vec(pos_i) for pos_i in range(n_position)])
sinusoid_table[:, 0::2] = np.sin(sinusoid_table[:, 0::2]) # dim 2i
sinusoid_table[:, 1::2] = np.cos(sinusoid_table[:, 1::2]) # dim 2i+1
if padding_idx is not None:
# zero vector for padding dimension
sinusoid_table[padding_idx] = 0.
return torch.FloatTensor(sinusoid_table)
После этого мне нужно вызвать слой позиционного кодирования, который будет добавлен вместе со слоем встраивания:
n_position = len_max_seq + 1
self.src_word_emb = nn.Embedding(
n_src_vocab, d_word_vec, padding_idx=Constants.PAD)
self.position_enc = nn.Embedding.from_pretrained(
get_sinusoid_encoding_table(n_position, d_word_vec, padding_idx=0),
freeze=True)
self.layer_stack = nn.ModuleList([
EncoderLayer(d_model, d_inner, n_head, d_k, d_v, dropout=dropout)
for _ in range(n_layers)])
##### Later on, during forward phase #####
enc_output = self.src_word_emb(src_seq) + self.position_enc(src_pos)
Но вот мои сомнения о том, какпреобразование этого кода в Keras:
1) Первый блок кода показывает, что таблица синусоид преобразуется в резак FloatTensor.Какой класс / объект я должен преобразовать эту таблицу в Keras?Я не смог найти FloatTensor или Tensor в Keras или keras.layers
2) Правильно ли n_position = len_max_seq + 1
?Это подразумевает, что он получит всю длину последовательности, добавит единицу и затем использует ее как позицию, не так ли это вне диапазона?Я предполагаю, что это будет работать только при работе с промежуточной кодировкой, зная, что это только текущий размер последовательности, а не окончательный.Возможно, неправильный регистр именования переменных?
3) В чем разница между nn.Embedding
и nn.Embedding.from_pretrained
?Почему этот код использует последний для кодирования позиционной кодировки?Я держу пари, что, поскольку это результат математической операции, а не обычного веса, обновление веса Keras его не должно касаться.В таком случае, эквивалент Keras будет использовать keras.layers.Embedding(input_dim, output_dim, trainable=False, weights=[get_sinusoid_encoding_table])
?
Кроме того, я думаю, что я должен добавить оба слоя, используя keras.layers.add, верно?
Спасибо.