Dikkat, bir dizi vektörünü sadece bir vektörde, genellikle bir arama vektörü aracılığıyla birleştirmek için kullanılan bir yöntemdir . Genellikle, ya modele girişler ya da önceki zaman adımlarının gizli durumları veya gizli durumları bir seviye aşağıya (üst üste LSTM'lerde) gelir.vbenuvben
Sonuç, geçerli zaman adımına ilişkin bağlamı içerdiğinden , genellikle bağlam vektörü olarak adlandırılır .c
Bu ilave vektörü daha sonra RNN / LSTM'ye de beslenir (orijinal girdiyle birleştirilebilir). Bu nedenle, bağlam öngörmeye yardımcı olmak için kullanılabilir.c
Bunu yapmanın en basit yolu, olasılık vektörünü ve burada , önceki tüm . Yaygın bir arama vektörü , mevcut gizli durum .p = softmax ( VTu )c = ∑benpbenvbenVvbenuht
Bunda birçok değişiklik var ve istediğiniz kadar karmaşık hale getirebilirsiniz. Örneğin, olarak kullanmak yerine, kişi yerine , burada isteğe bağlı bir sinir ağıdır.vTbenuf( vben, u )f
Dizi-to-dizisi model için yaygın bir ilgi mekanizması kullanır , burada kodlayıcının gizli durumları, ve gizli akım kod çözücünün durumu. ve her iki s de parametredir.p = softmax ( qTtanh( W1vben+ W2ht) )vhtqW
Dikkat fikrinde farklı varyasyonlar gösteren bazı makaleler:
Pointer Networks , kombinasyonel optimizasyon problemlerini çözmek için referans girişlerine dikkat eder.
Tekrarlayan Varlık Ağları , metin okurken farklı varlıklar (insanlar / nesneler) için ayrı hafıza durumlarını korur ve dikkatini kullanarak doğru hafıza durumunu günceller.
Transformatör modelleri de dikkatleri büyük ölçüde kullanır. Dikkat formülasyonları biraz daha geneldir ve aynı zamanda anahtar vektörlerini de içerir : dikkat ağırlıklarının gerçekte anahtarlar ve arama arasında hesaplanması ve bağlam sonra .kbenpvben
Bazı basit testlerden geçmesi gerçeğinin ötesinde doğruluğu garanti edemesem de, bir dikkat biçiminin hızlı bir uygulaması.
Temel RNN:
def rnn(inputs_split):
bias = tf.get_variable('bias', shape = [hidden_dim, 1])
weight_hidden = tf.tile(tf.get_variable('hidden', shape = [1, hidden_dim, hidden_dim]), [batch, 1, 1])
weight_input = tf.tile(tf.get_variable('input', shape = [1, hidden_dim, in_dim]), [batch, 1, 1])
hidden_states = [tf.zeros((batch, hidden_dim, 1), tf.float32)]
for i, input in enumerate(inputs_split):
input = tf.reshape(input, (batch, in_dim, 1))
last_state = hidden_states[-1]
hidden = tf.nn.tanh( tf.matmul(weight_input, input) + tf.matmul(weight_hidden, last_state) + bias )
hidden_states.append(hidden)
return hidden_states[-1]
Dikkatle, yeni gizli durum hesaplanmadan önce sadece birkaç satır ekleriz:
if len(hidden_states) > 1:
logits = tf.transpose(tf.reduce_mean(last_state * hidden_states[:-1], axis = [2, 3]))
probs = tf.nn.softmax(logits)
probs = tf.reshape(probs, (batch, -1, 1, 1))
context = tf.add_n([v * prob for (v, prob) in zip(hidden_states[:-1], tf.unstack(probs, axis = 1))])
else:
context = tf.zeros_like(last_state)
last_state = tf.concat([last_state, context], axis = 1)
hidden = tf.nn.tanh( tf.matmul(weight_input, input) + tf.matmul(weight_hidden, last_state) + bias )
tam kod