首页 > 解决方案 > 如何使用 Keras/Tensorflow 实现“所见即所得”论文中给出的“行编码器”?

问题描述

我最近开始处理一项任务,我试图从方程的图像中生成方程。此处给出了实现,但它在LUA其中,我无法理解。所以我尝试做一些事情,tensorflow 2因为模型与你得到的就是你所看到的完全一样:A Visual Markup Decompiler。为了做到这一点,我将论文中的模型设为:

base_model = tf.keras.applications.InceptionV3(include_top=False,weights='imagenet')
inp = base_model.input
out = base_model.layers[-1].output # use only the last layer. It'll provide us (8,8,2048)
cnn_part = tf.keras.Model(inp, out)

class BahdanauAttention(tf.keras.Model):
  def __init__(self, units):
    super(BahdanauAttention, self).__init__()
    self.W1 = tf.keras.layers.Dense(units)
    self.W2 = tf.keras.layers.Dense(units)
    self.V = tf.keras.layers.Dense(1)

  def call(self, features, hidden):
    hidden_with_time_axis = tf.expand_dims(hidden, 1)
    attention_hidden_layer = (tf.nn.tanh(self.W1(features) + self.W2(hidden_with_time_axis)))
    score = self.V(attention_hidden_layer)
    attention_weights = tf.nn.softmax(score, axis=1)
    context_vector = attention_weights * features
    context_vector = tf.reduce_sum(context_vector, axis=1)

    return context_vector, attention_weights

到目前为止,这还算不错。现在是Show attend and tell与本文不同的部分。我们不能使用DenseLayer 并将输出Embedding Layer直接传递给他们,因为他们特别说过:

在基于注意力的图像描述中(Xu et al. 2015),图像特征网格可以直接输入解码器。对于 OCR,输入解码器的视觉特征包含重要的相对顺序信息。因此,我们尝试使用一个额外的 RNN 编码器模块来重新编码网格的每一行

他们后来也说过:

在这个模型中,新的特征网格 V~ 是通过在输入的每一行上运行 RNN 来从 V 创建的。递归地对所有行 h ∈ {1, . . . , H0} 和列 w ∈ {1, . . . , W0},新特征定义为 V~ h,w = RNN(V~ h,w−1, Vh,w)。为了捕获垂直方向的顺序信息,我们为每一行使用可训练的初始隐藏状态 V~h,0,我们将其命名为位置嵌入。

这就是他们想说的:

在此处输入图像描述

请帮助我实现模型结构。

我有一个模糊的想法,我必须做一些事情,比如使用社区帮助:

rnn_input = tf.keras.layers.Reshape((batch_size*height, width, channels))(convnet_output) # given by VGG
rnn_output = tf.keras.layers.RNN(hidden_dim, return_sequences=True)(rnn_input)

但我不确定如何使用Attention + Decoder它?有人可以帮忙吗。

我认为您可以Decoder Model用作:

class RNN_Decoder(tf.keras.Model):
  def __init__(self, embedding_dim, units, vocab_size):
    super(RNN_Decoder, self).__init__()
    self.units = units

    self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
    self.lstm = tf.keras.layers.LSTM(self.units,return_sequences=True,return_state=True,recurrent_initializer='glorot_uniform')
    self.fc1 = tf.keras.layers.Dense(self.units)
    self.fc2 = tf.keras.layers.Dense(vocab_size)

    self.attention = BahdanauAttention(self.units)

  def call(self, x, features, hidden):
    context_vector, attention_weights = self.attention(features, hidden)
    x = self.embedding(x)
    x = tf.concat([tf.expand_dims(context_vector, 1), x], axis=-1)
    output, state = self.lstm(x)
    x = self.fc1(output)
    x = tf.reshape(x, (-1, x.shape[2]))
    x = self.fc2(x)
    return x, state, attention_weights

  def reset_state(self, batch_size):
    return tf.zeros((batch_size, self.units))

encoder = CNN_Encoder(embedding_dim)
decoder = RNN_Decoder(embedding_dim, units, vocab_size)

optimizer = tf.keras.optimizers.Adam()
loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True,reduction='none')

def loss_function(real, pred):
  mask = tf.math.logical_not(tf.math.equal(real, 0))
  loss_ = loss_object(real, pred)
  mask = tf.cast(mask, dtype=loss_.dtype)
  loss_ *= mask
  return tf.reduce_mean(loss_)

标签: tensorflowkerasdeep-learningcomputer-visionconv-neural-network

解决方案


推荐阅读