【问题标题】:LSTM cells after convolution卷积后的 LSTM 单元
【发布时间】:2017-10-25 00:03:04
【问题描述】:

我需要在两个卷积层之后实现一个 LSTM 层。这是我第一次卷积后的代码:

convo_2 = convolutional_layer(convo_1_pooling, shape=[5, 5, 32, 64])
convo_2_pooling = max_pool_2by2(convo_2)
convo_2_flat = tf.reshape(convo_2_pooling, shape=[-1, 64 * 50 * 25])
cell = rnn.LSTMCell(num_units=100, activation=tf.nn.relu)
cell = rnn.OutputProjectionWrapper(cell, output_size=7)
conv_to_rnn = int(convo_2_flat.get_shape()[1])
outputs, states = tf.nn.dynamic_rnn(cell, convo_2_flat, dtype=tf.float32)

我在最后一行收到此错误:

ValueError: Shape (?, 50, 64) must have rank 2

我必须在convo_2_flat 变量中指明时间步长,对吗?如何?我真的不知道该怎么做。

编辑:
重塑后:

 convo_2_flat = tf.reshape(convo_2_flat, shape=[-1, N_TIME_STEPS, INPUT_SIZE])

在哪里

N_TIME_STEPS = 25
INPUT_SIZE = int(64 * 50 * 25 / N_TIME_STEPS)

我收到此错误:InvalidArgumentError(有关回溯,请参见上文):logits 和标签必须相同大小:logits_size=[5000,7] labels_size=[50,7] 在这一行: 交叉熵 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=outputs)) 在我看来,上次重塑后批量大小发生了变化。

编辑 2:
下面的代码是不是错了?

convo_2_shape = convo_2_pooling.get_shape().as_list()
shape_convo_flat = convo_2_shape[1] * convo_2_shape[2] * convo_2_shape[3]
N_TIME_STEPS = convo_2_shape[1]
INPUT_SIZE = tf.cast(shape_convo_flat / N_TIME_STEPS, tf.int32)
convo_2_out = tf.reshape(convo_2_pooling, shape=[-1, shape_convo_flat])
convo_2_out = tf.reshape(convo_2_out, shape=[-1, N_TIME_STEPS, INPUT_SIZE])

我这样设置N_TIME_STEPS 因为否则我会有一个浮点数INPUT_SIZE 并且tf 会抛出一个错误。

【问题讨论】:

    标签: python tensorflow lstm convolution


    【解决方案1】:

    根据 Tensorflow 文档 (https://www.tensorflow.org/api_docs/python/tf/nn/dynamic_rnn)

    输入应该是以下形状(我这里使用默认),

    [BATCH_SIZE,N_TIME_STEPS,INPUT_SIZE]。因此,您可以如下重塑 convo_2_flat

    #get the shape of the output of max pooling
    shape = convo_2_pooling.get_shape().as_list()
    #flat accordingly
    convo_2_flat = tf.reshape(convo_2_pooling, [-1, shape[1] * shape[2] * shape[3]])
    
    # Here shape[1] * shape[2] * shape[3]] = N_TIME_STEPS*INPUT_SIZE
    
    #reshape according to dynamic_rnn input
    convo_2_flat = tf.reshape(convo_2_flat, shape=[-1, N_TIME_STEPS, INPUT_SIZE])
    
    outputs, states = tf.nn.dynamic_rnn(cell, convo_2_flat, dtype=tf.float32)
    
    # get the output of the last time step
    val = tf.transpose(outputs, [1, 0, 2])
    lstm_last_output = val[-1]
    
    OUTPUT_SIZE = 7 #since you have defined in cell = rnn.OutputProjectionWrapper(cell, output_size=7)
    
    W = {
            'output': tf.Variable(tf.random_normal([OUTPUT_SIZE, N_CLASSES]))
        }
    biases = {
            'output': tf.Variable(tf.random_normal([N_CLASSES]))
        }
    
    #Dense Layer
    pred_Y= tf.matmul(lstm_last_output, W['output']) + biases['output']
    #Softmax Layer
    pred_softmax = tf.nn.softmax(pred_Y)
    
    cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=pred_softmax))
    

    注意输出

    根据文档,dynamic_rnn的输出如下,

    [BATCH_SIZE, N_TIME_STEPS, OUTPUT_SIZE]。因此,每个时间步都有一个输出。在上面的代码中,我只得到了最后一个时间步的输出。或者,您可以考虑一种不同的 rnn 输出架构,如下所述 (How do we use LSTM to classify sequences?),

    希望这会有所帮助。

    【讨论】:

    • 谢谢。问题是:输入大小不是 64 * 50 * 25(来自我的代码)吗?
    • 64 * 50 * 25 = N_TIME_STEPS * INPUT_SIZE,因此,你需要定义这两个参数。
    • 谢谢,现在我遇到了另一个问题,我认为是由重塑引起的。我编辑了这个问题。你能帮帮我吗?
    • 不起作用,它给了我错误的预测数量,大于批量大小。你能解释一下你为什么添加val = tf.transpose(outputs, [1, 0, 2]) lstm_last_output = val[-1]吗?
    • 我对代码进行了一些更改,并在我认为有必要时添加了解释。让我知道代码是否正常工作,您需要进一步的解释。
    猜你喜欢
    • 2019-12-01
    • 1970-01-01
    • 2018-02-07
    • 2023-04-01
    • 1970-01-01
    • 2016-05-17
    • 2019-09-08
    • 2018-12-22
    • 1970-01-01
    相关资源
    最近更新 更多