【发布时间】:2020-05-20 15:58:10
【问题描述】:
我想创建一个自定义注意力层,用于随时输入,该层返回所有时间输入的加权平均值。
例如,我希望形状为[32,100,2048] 的输入张量进入层,我得到形状为[32,100,2048] 的张量。我写的图层如下:
import tensorflow as tf
from keras.layers import Layer, Dense
#or
from tensorflow.keras.layers import Layer, Dense
class Attention(Layer):
def __init__(self, units_att):
self.units_att = units_att
self.W = Dense(units_att)
self.V = Dense(1)
super().__init__()
def __call__(self, values):
t = tf.constant(0, dtype= tf.int32)
time_steps = tf.shape(values)[1]
initial_outputs = tf.TensorArray(dtype=tf.float32, size=time_steps)
initial_att = tf.TensorArray(dtype=tf.float32, size=time_steps)
def should_continue(t, *args):
return t < time_steps
def iteration(t, values, outputs, atts):
score = self.V(tf.nn.tanh(self.W(values)))
# attention_weights shape == (batch_size, time_step, 1)
attention_weights = tf.nn.softmax(score, axis=1)
# context_vector shape after sum == (batch_size, hidden_size)
context_vector = attention_weights * values
context_vector = tf.reduce_sum(context_vector, axis=1)
outputs = outputs.write(t, context_vector)
atts = atts.write(t, attention_weights)
return t + 1, values, outputs, atts
t, values, outputs, atts = tf.while_loop(should_continue, iteration,
[t, values, initial_outputs, initial_att])
outputs = outputs.stack()
outputs = tf.transpose(outputs, [1,0,2])
atts = atts.stack()
atts = tf.squeeze(atts, -1)
atts = tf.transpose(atts, [1,0,2])
return t, values, outputs, atts
对于input= tf.constant(2, shape= [32, 100, 2048], dtype= tf.float32),我得到了
在 tf2 中输出 shape = [32,100,2048],在 tf1 中输出 [32,None, 2048]。
对于输入 input= Input(shape= (None, 2048)),我在 tf1 中得到带有 shape = [None, None, 2048] 的输出,但出现错误
TypeError: 'Tensor' 对象不能被解释为整数
在 tf2 中。
最后,在这两种情况下,我都不能在我的模型中使用这个层,因为我的模型输入是Input(shape= (None, 2048)),我得到了错误
AttributeError: 'NoneType' 对象没有属性 '_inbound_nodes'
在 tf1 和 tf2 中,我得到与上述相同的错误,我使用 Keras 函数方法创建模型。
【问题讨论】:
-
这里添加关注的简单方法:stackoverflow.com/a/62949137/10375049
标签: tensorflow keras deep-learning