Преобразование позиционного кодирования Attention из PyTorch в Keras - PullRequest
0 голосов
/ 31 мая 2019

Я пытаюсь реализовать позиционное кодирование из Внимание - это все, что вам нужно , следуя этому хранилищу .Есть два конкретных блока кода, которые мне нужно будет добавить в мою модель, где оба находятся в этом файле .

Во-первых, мне нужно добавить функцию, которая преобразует массив в синусоиду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, верно?

Спасибо.

...