TensorFlow Keras MaxPool2D在CTC损失时中断LSTM?

2024-09-27 00:14:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将一个CNN层与2个LSTM层和ctc_批次_损失成本捆绑在一起,但我遇到了一些问题。我的模型应该可以处理灰度图像

在调试过程中,我发现如果我只使用一个CNN层,使输出大小等于输入大小+LSTM和CTC,那么模型能够训练:

# === Without MaxPool2D ===
inp = Input(name='inp', shape=(128, 32, 1))

cnn = Conv2D(name='conv', filters=1, kernel_size=3, strides=1, padding='same')(inp)

# Go from Bx128x32x1 to Bx128x32 (B x TimeSteps x Features)
rnn_inp = Reshape((128, 32))(maxp)

blstm = Bidirectional(LSTM(256, return_sequences=True), name='blstm1')(rnn_inp)
blstm = Bidirectional(LSTM(256, return_sequences=True), name='blstm2')(blstm)

# Softmax.
dense = TimeDistributed(Dense(80, name='dense'), name='timedDense')(blstm)
rnn_outp = Activation('softmax', name='softmax')(dense)

# Model compiles, calling fit works!

但是,当我添加一个将维度减半的MaxPool2D层时,我会得到一个错误sequence_length(0) <= 64,类似于前面介绍的here

# === With MaxPool2D ===
inp = Input(name='inp', shape=(128, 32, 1))

cnn = Conv2D(name='conv', filters=1, kernel_size=3, strides=1, padding='same')(inp)
maxp = MaxPool2D(name='maxp', pool_size=2, strides=2, padding='valid')(cnn) # -> 64x16x1

# Go from Bx64x16x1 to Bx64x16 (B x TimeSteps x Features)
rnn_inp = Reshape((64, 16))(maxp)

blstm = Bidirectional(LSTM(256, return_sequences=True), name='blstm1')(rnn_inp)
blstm = Bidirectional(LSTM(256, return_sequences=True), name='blstm2')(blstm)

# Softmax.
dense = TimeDistributed(Dense(80, name='dense'), name='timedDense')(blstm)
rnn_outp = Activation('softmax', name='softmax')(dense)

# Model compiles, but calling fit crashes with:
# InvalidArgumentError: sequence_length(0) <= 64
#    [[{{node ctc_loss_1/CTCLoss}}]]

Tags: nametruesizereturncnndenseinplstm
1条回答
网友
1楼 · 发布于 2024-09-27 00:14:22

在为这个问题苦苦挣扎了大约3天后,我在StackOverflow上发布了上面的问题。在发布这些问题大约两个小时后,我终于找到了答案

TL;灾难恢复解决方案:

如果您正在使用ctc_batch_cost

确保将输入RNN的序列的长度(时间步数)作为input_length参数的输入

如果您正在使用ctc_loss

确保您正在传递进入RNN的序列的长度(时间步数)作为logit_length参数的输入

解决方案:

解决方案在于文档,文档相对来说比较稀疏,对于像我这样的机器学习新手来说可能很神秘

TensorFlow documentation for ctc_batch_cost案文如下:

tf.keras.backend.ctc_batch_cost(
    y_true, y_pred, input_length, label_length
)

...

input_length tensor (samples, 1) containing the sequence length for each batch item in y_pred.

...

input_length对应于来自ctc_loss函数的TensorFlow documentationlogit_length

tf.nn.ctc_loss(
    labels, logits, label_length, logit_length, logits_time_major=True, unique=None,
    blank_index=None, name=None
)

...

logit_length tensor of shape [batch_size] Length of input sequence in logits.

...

那就是它点击的地方,在单词logit上。因此input_lengthlogit_length的参数应该是一个张量/容器(在我的例子中是numpy数组),其长度为序列的长度(即时间步数),作为输入进入RNN(在我的例子中是LSTM)

我最初犯的错误是,将所需长度视为作为整个网络输入的灰度图像的宽度(CNN+MaxPool2D+RNN),但由于MaxPool2D层为RNN的输入创建了不同维度的张量,因此ctc损失函数崩溃

现在,fit跑步时不会发生碰撞

相关问题 更多 >

    热门问题