Я работаю с RNN и механизмами внимания.
В отличие от мягкого внимания (которое взвешивает временные шаги RNN по тензору внимания и суммирует их), я хочу выбрать наиболее k
важные временные шаги и использовать другие методы для их объединения.
Таким образом, у меня есть три тензора:
RNNMatrix
, с формой (None, time_steps, cell_num)
, где None
- размер партии AttMatrix
, с формой (None, time_steps)
IdxMatrix
, с формой (None, k)
, каждая строка является указателем наиболее k важных временных шагов, получим от AttMatrix
В идеале я могу получить *От 1024 * в форме (None, k, cell_num)
до RNNMatrix
и IdxMatrix
.
Простой способ получить IdxMatrix
использует tf.nn.top_k
.Мой код ниже:
selected_att_num = 10
def My_select_layer(ip, k_num):
LSTM_out = ip[0]
Attention = ip[1]
idx = tf.nn.top_k(Attention, k=k_num, sorted = True).indices
# gen row index
row_idx = tf.range(tf.shape(Attention)[0])
# repeat k times
row_idx_repeat = tf.keras.backend.repeat(tf.reshape(row_idx,(-1,1)), k_num)
# gen index for gather_nd
row_idx_repeat_reshape = tf.reshape(row_idx_repeat, (-1,k_num))
idx_stacked = tf.stack([row_idx_repeat_reshape, idx], axis=-1)
return tf.gather_nd(LSTM_out, idx_stacked)
_input = Input(shape = (data_length, data_dim))
LSTM_out = LSTM(cells, return_sequences=True)(_input )
# compute att for each step
Attention = Activation('tanh')(LSTM_out)
Attention = Dense(1, use_bias=False)(Attention)
Attention = Flatten()(Attention)
Attention = Activation('softmax', name='attention')(Attention)
LSTM_out_gathered = Lambda(My_select_layer,arguments={'k_num':selected_att_num})([LSTM_out , Attention])
Модель хорошо работает и выдает ошибку, когда я обучаю ее:
ValueError: Операция имеет None
для градиента.Пожалуйста, убедитесь, что все ваши операции имеют определенный градиент (то есть являются дифференцируемыми).Обычные операции без градиента: K.argmax, K.round, K.eval.
Я почти уверен, что эта ошибка связана с моим слоем Lambda, скорее всего, с переменной indices
из tf.nn.top_k
.
Но я не знаю, как это исправить.
Или, операция 'выбрать тензор по индексу' теоретически недифференцируема?Если да, то есть ли обходной путь?
В худшем случае, может ли обучение с подкреплением удержать это?
Я также часто ищу в Интернете и нахожу очень похожий вопрос , заданныйДаниэль МёллерОднако Даниэль не показывает больше подробностей о том, как он решает эту проблему.