Что такое штраф за внимание в речевой бумаге? (Обновлено) - PullRequest
0 голосов
/ 08 января 2020

github: https://github.com/sephiroce/tfsr/tree/exprimental

Я пытаюсь воспроизвести точность распознавания, описанную в статье для преобразования речи [1]. Наказание за внимание - техника, которую я не мог полностью понять. Это описание штрафа за внимание в статье.

«Кроме того, мы поощряли внимание модели к более близким позициям, добавляя больший штраф к весам внимания более удаленных пар позиций».

Я понял, что это означает добавление меньших отрицательных значений для большего отклонения от диагонали в масштабированных логитах внимания (до маскирования), за исключением первого многоголовочного внимания в декодерах.

Это фрагмент кода для вычисления внимания weights.

  # Q * trans(K): (..., seq_len_q, seq_len_k)
  matmul_qk = tf.matmul(query, key, transpose_b=True)

  # scaled matmul_qk: ( Q * trans(K) ) / sqrt(d_k)
  dimension_of_key = tf.cast(tf.shape(key)[-1], tf.float32)
  scaled_attention_logits = matmul_qk / tf.math.sqrt(dimension_of_key)

  # add the mask to the scaled tensor
  if mask is not None:
    scaled_attention_logits += (mask * -1e9)

  # softmax is normalized on the last axis (seq_len_k) so that the scores
  # add up to 1.
  attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1)

  # Adding penalty to attention weights and linearly re-normalize it.
  if attention_penalty is not None and att_penalty_scale > 0:
    attention_weights += (attention_penalty * att_penalty_scale)
    attention_weights += tf.math.abs(tf.math.reduce_min(attention_weights))
    inv_sum = 1 / tf.math.reduce_sum(attention_weights, axis=-1)
    attention_weights = tf.einsum('ijlm,ijl->ijlm', attention_weights, inv_sum)

Фрагмент исходного кода ниже предназначен для создания матрицы штрафов за внимание. Я не смог найти никакого эффективного способа создания матрицы штрафов за внимание для вторых весов внимания с несколькими головками в декодерах, поскольку карты внимания не диагональны. Таким образом, сначала я пытаюсь применить наказание за внимание к кодировщикам. Исходный код назначает линейно более высокие штрафы для более удаленных элементов от диагонали.
Существует два гиперпараметра, таких как Внимание_Пеналь__салон (это похоже на penalty_values, который предложил Йиндржих) и ширина диагональной линии.
Я мог бы добавить такую ​​опцию, как stripe_step_size. В настоящее время stripe_step_size можно интерпретировать как 1.

def create_attention_penalty(inp_len, tar_len, num_heads, attention_penalty_width):
  max_inp_len = tf.cast(tf.math.reduce_max(inp_len), tf.int32)
  n_batch = tf.shape(inp_len)[0]

  enc_att_penalty = tf.ones([n_batch, num_heads, max_inp_len, max_inp_len])

  accum = tf.zeros(([n_batch, num_heads, max_inp_len, max_inp_len]))
  for i in range(attention_penalty_width - 1, max_inp_len - 1):
    accum += tf.linalg.band_part(enc_att_penalty, i, i, name=None) - 1

  enc_att_penalty = accum

  return enc_att_penalty, None

Несмотря на то, что я реализовал, как я понимаю, я не смог добиться какого-либо улучшения точности. И есть еще одна обратная сторона этой реализации. Скорость тренировки становилась все медленнее.

В) Как эффективно применять этот метод штрафов за внимание к квадратным и неквадратным весам внимания?

Ссылка
[1] Линхао Донг, Шуан Сюй , Бо Сюй, Речевой преобразователь: неповторяющаяся модель последовательности-последовательности для распознавания речи, ICASSP 2018, https://ieeexplore.ieee.org/document/8462506

1 Ответ

0 голосов
/ 13 января 2020

Я думаю, вы это хорошо понимаете. Они, вероятно, сделали полосу вокруг диагонали, что-то вроде:

attention_penalty = (1 - tf.linalg.band_part(scaled_attention_logits, stripe_size, stripe_size)) * penalty

Однако вам, вероятно, нужно больше экспериментировать с тем, какими должны быть strip_size и penalty_values, потому что в статье не сказано много. Или вы можете попробовать написать авторам.

...