将输入张量与负 1 张量的倍数连接起来
Concatenate input tensor with multiple of neg 1 tensors
相似的帖子: 首先,这两个帖子即使不一样也很相似。我试图徒劳地实施这些。所以我可能错过了一些东西,因为我对 Keras 缺乏经验。
,
问题:
我有一个数据生成器,可以将数据输入各种模型以评估模型性能并学习 Keras。
model.fit_generator(generator=img_gen.next_train(), ....
此生成器生成的输入之一是形状为 [batch_size、num_letters] 的张量 "labels"。这个张量是
的第一个输入
K.ctc_batch_cost(labels, ....
类似于 image_ocr.py 第 369 行。
上面的"keras example"创建了一个RNN/GRU,其中RNN的每个输出步骤都是ctc的一个输入,其中RNN中有num_letters个步骤,标签是形状 (?, num_letters)。这对我目前测试过的前 6 个模型来说效果很好。
我正在测试一个新模型,其中 RNN/GRU 输出的每个步骤都是对 ctc 的“1 到 n”输入,并将其留给训练以优化每个步骤的输出。所以我的 ctc 在第一次输入张量时需要 shape=(?,num_letters*n) 但数据生成器生成 shape=(?, num_letters).
旁注:我模型中的 RNN 实际上产生了一个整体形状 =(?, n, num_letters)。我知道如何将其转换为 (?, n*num_letters).
解决方案 1 是 hack,更改生成器,使其对于正在测试的模型是唯一的。该生成器将生成形状为 =(?,num_letters*n) 的张量。我不喜欢这样,因为生成器也在评估中,并希望它对于每个被评估的模型都是不变的。
解决方案 2 是一个 hack,创建一个封装原始生成器并增加生成的输出的生成器。
解决方案 3: 让模型输入 shape=(?, num_letters) 并连接必要的填充,因此形状为 (?,num_letters*n) ctc 想要的。
这是我试过的:
num_letters = 3
n = 5
keras_tensor_input = keras.layers.Input( shape=[num_letters], dtype='float32' )
print("keras_tensor_input = ", keras_tensor_input)
# keras_tensor_input = Tensor("input_1:0", shape=(?, 3), dtype=float32)
# note ? is batch size
keras_tensor_neg_1 = keras.backend.constant( -1, dtype='float32', shape=[num_letters] )
print("keras_tensor_neg_1 = ", keras_tensor_neg_1)
# keras_tensor_neg_1 = Tensor("Const_1:0", shape=(3,), dtype=float32)
# note no batch size
keras_tensor_neg_1_tiled = keras.backend.tile(keras_tensor_neg_1, (n-1))
print("keras_tensor_neg_1_tiled = ", keras_tensor_neg_1_tiled)
# keras_tensor_neg_1_tiled = Tensor("Tile_2:0", shape=(12,), dtype=float32)
# note no batch size, but now the correct fill length
# FAILED attempt to put in a batch size
layer_const_neg_1 = keras.layers.Lambda(lambda x: keras_tensor_neg_1_tiled ,output_shape=[(n-1)*num_letters] )
keras_tensor_neg_1_prime = layer_const_neg_1(keras_tensor_neg_1)
print("keras_tensor_neg_1_prime = ", keras_tensor_neg_1_prime)
# keras_tensor_neg_1_prime = Tensor("Tile_2:0", shape=(12,), dtype=float32)
# CRASH AT NEXT STEP BECAUSE NO ? in keras_tensor_neg_1_prime
# concatenate the input from the generator and the padding
keras_tensor_concat = keras.layers.Concatenate()( inputs = [keras_tensor_input, keras_tensor_neg_1_prime] )
print("keras_tensor_concat = ", keras_tensor_concat)
my_model = keras.models.Model( inputs=[keras_tensor_input], output=keras_tensor_concat)
# dummy optimizer, loss, and metric just to allow compile to pass
my_model.compile(optimizer='rmsprop',loss='categorical_crossentropy', metrics=['accuracy'])
# a batch of size 1, for a tensor of shape =[3]
d1 = numpy.array([[1, 2, 3]])
out = my_model.predict( [ d1 ] )
print(out)
备注:
- 本可以制作恒定形状=[num_letters*(n-1)] 并丢弃图块,但仍然存在缺少批量大小的相同问题。
- 如果我将 batch_size 作为第一维,那么它仍然无法抱怨 (?, 3) can not be concatenated with (1, 12)
提前谢谢你。
我找到了模型的解决方案
# a batch of size 1, for a tensor of shape =[3]
d1 = numpy.array([[1, 2, 3]])
并作为输出生成
out = my_model.predict( [ d1 ] )
print(out)
# [[ 1. 2. 3. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1.]]
最大的教训是keras.layers想要作为输入,其他keras.layers的输出。因此 keras.backend 中的功能,如 tile 必须包含在 keras.layers.Lambda[=37= 中] 在将它们作为 keras.layer.
的输入之前
感谢
解决方法如下:
# instantiate a Keras tensor ... as per document https://keras.io/layers/core/
keras_tensor_input = keras.layers.Input( shape=[num_letters], dtype='float32' )
print("keras_tensor_input = ", keras_tensor_input)
# keras_tensor_input = Tensor("input_1:0", shape=(?, 3), dtype=float32)
#
keras_tensor_neg_1 = keras.layers.Lambda(lambda x: -keras.backend.ones_like(x) )(keras_tensor_input)
print("keras_tensor_neg_1 = ", keras_tensor_neg_1)
# keras_tensor_neg_1 = Tensor("lambda_1/Neg:0", shape=(?, 3), dtype=float32)
# note batch size, just like keras_tensor_input
#
keras_tensor_neg_1_tiled = keras.layers.Lambda(lambda x: keras.backend.tile(x, (1, n-1)))(keras_tensor_neg_1)
print("keras_tensor_neg_1_tiled = ", keras_tensor_neg_1_tiled)
# keras_tensor_neg_1_tiled = Tensor("Tile_2:0", shape=(12,), dtype=float32)
# note batch size, just like keras_tensor_input
# concatenate the input from the generator and the padding
keras_tensor_concat = keras.layers.Concatenate()( inputs = [keras_tensor_input, keras_tensor_neg_1_tiled] )
print("keras_tensor_concat = ", keras_tensor_concat)
# keras_tensor_concat = Tensor("concatenate_1/concat:0", shape=(?, 15), dtype=float32)
my_model = keras.models.Model( inputs=keras_tensor_input, output=keras_tensor_concat)
# dummy optimizer, loss, and metric so I can compile and test the model
my_model.compile(optimizer='rmsprop',loss='categorical_crossentropy', metrics=['accuracy'])
# a batch of size 1, for a tensor of shape =[3]
d1 = numpy.array([[1, 2, 3]])
out = my_model.predict( [ d1 ] )
print(out)
# [[ 1. 2. 3. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1.]]
相似的帖子: 首先,这两个帖子即使不一样也很相似。我试图徒劳地实施这些。所以我可能错过了一些东西,因为我对 Keras 缺乏经验。
问题: 我有一个数据生成器,可以将数据输入各种模型以评估模型性能并学习 Keras。
model.fit_generator(generator=img_gen.next_train(), ....
此生成器生成的输入之一是形状为 [batch_size、num_letters] 的张量 "labels"。这个张量是
的第一个输入K.ctc_batch_cost(labels, ....
类似于 image_ocr.py 第 369 行。
上面的"keras example"创建了一个RNN/GRU,其中RNN的每个输出步骤都是ctc的一个输入,其中RNN中有num_letters个步骤,标签是形状 (?, num_letters)。这对我目前测试过的前 6 个模型来说效果很好。
我正在测试一个新模型,其中 RNN/GRU 输出的每个步骤都是对 ctc 的“1 到 n”输入,并将其留给训练以优化每个步骤的输出。所以我的 ctc 在第一次输入张量时需要 shape=(?,num_letters*n) 但数据生成器生成 shape=(?, num_letters).
旁注:我模型中的 RNN 实际上产生了一个整体形状 =(?, n, num_letters)。我知道如何将其转换为 (?, n*num_letters).
解决方案 1 是 hack,更改生成器,使其对于正在测试的模型是唯一的。该生成器将生成形状为 =(?,num_letters*n) 的张量。我不喜欢这样,因为生成器也在评估中,并希望它对于每个被评估的模型都是不变的。
解决方案 2 是一个 hack,创建一个封装原始生成器并增加生成的输出的生成器。
解决方案 3: 让模型输入 shape=(?, num_letters) 并连接必要的填充,因此形状为 (?,num_letters*n) ctc 想要的。
这是我试过的:
num_letters = 3
n = 5
keras_tensor_input = keras.layers.Input( shape=[num_letters], dtype='float32' )
print("keras_tensor_input = ", keras_tensor_input)
# keras_tensor_input = Tensor("input_1:0", shape=(?, 3), dtype=float32)
# note ? is batch size
keras_tensor_neg_1 = keras.backend.constant( -1, dtype='float32', shape=[num_letters] )
print("keras_tensor_neg_1 = ", keras_tensor_neg_1)
# keras_tensor_neg_1 = Tensor("Const_1:0", shape=(3,), dtype=float32)
# note no batch size
keras_tensor_neg_1_tiled = keras.backend.tile(keras_tensor_neg_1, (n-1))
print("keras_tensor_neg_1_tiled = ", keras_tensor_neg_1_tiled)
# keras_tensor_neg_1_tiled = Tensor("Tile_2:0", shape=(12,), dtype=float32)
# note no batch size, but now the correct fill length
# FAILED attempt to put in a batch size
layer_const_neg_1 = keras.layers.Lambda(lambda x: keras_tensor_neg_1_tiled ,output_shape=[(n-1)*num_letters] )
keras_tensor_neg_1_prime = layer_const_neg_1(keras_tensor_neg_1)
print("keras_tensor_neg_1_prime = ", keras_tensor_neg_1_prime)
# keras_tensor_neg_1_prime = Tensor("Tile_2:0", shape=(12,), dtype=float32)
# CRASH AT NEXT STEP BECAUSE NO ? in keras_tensor_neg_1_prime
# concatenate the input from the generator and the padding
keras_tensor_concat = keras.layers.Concatenate()( inputs = [keras_tensor_input, keras_tensor_neg_1_prime] )
print("keras_tensor_concat = ", keras_tensor_concat)
my_model = keras.models.Model( inputs=[keras_tensor_input], output=keras_tensor_concat)
# dummy optimizer, loss, and metric just to allow compile to pass
my_model.compile(optimizer='rmsprop',loss='categorical_crossentropy', metrics=['accuracy'])
# a batch of size 1, for a tensor of shape =[3]
d1 = numpy.array([[1, 2, 3]])
out = my_model.predict( [ d1 ] )
print(out)
备注:
- 本可以制作恒定形状=[num_letters*(n-1)] 并丢弃图块,但仍然存在缺少批量大小的相同问题。
- 如果我将 batch_size 作为第一维,那么它仍然无法抱怨 (?, 3) can not be concatenated with (1, 12)
提前谢谢你。
我找到了模型的解决方案
# a batch of size 1, for a tensor of shape =[3]
d1 = numpy.array([[1, 2, 3]])
并作为输出生成
out = my_model.predict( [ d1 ] )
print(out)
# [[ 1. 2. 3. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1.]]
最大的教训是keras.layers想要作为输入,其他keras.layers的输出。因此 keras.backend 中的功能,如 tile 必须包含在 keras.layers.Lambda[=37= 中] 在将它们作为 keras.layer.
的输入之前感谢
解决方法如下:
# instantiate a Keras tensor ... as per document https://keras.io/layers/core/
keras_tensor_input = keras.layers.Input( shape=[num_letters], dtype='float32' )
print("keras_tensor_input = ", keras_tensor_input)
# keras_tensor_input = Tensor("input_1:0", shape=(?, 3), dtype=float32)
#
keras_tensor_neg_1 = keras.layers.Lambda(lambda x: -keras.backend.ones_like(x) )(keras_tensor_input)
print("keras_tensor_neg_1 = ", keras_tensor_neg_1)
# keras_tensor_neg_1 = Tensor("lambda_1/Neg:0", shape=(?, 3), dtype=float32)
# note batch size, just like keras_tensor_input
#
keras_tensor_neg_1_tiled = keras.layers.Lambda(lambda x: keras.backend.tile(x, (1, n-1)))(keras_tensor_neg_1)
print("keras_tensor_neg_1_tiled = ", keras_tensor_neg_1_tiled)
# keras_tensor_neg_1_tiled = Tensor("Tile_2:0", shape=(12,), dtype=float32)
# note batch size, just like keras_tensor_input
# concatenate the input from the generator and the padding
keras_tensor_concat = keras.layers.Concatenate()( inputs = [keras_tensor_input, keras_tensor_neg_1_tiled] )
print("keras_tensor_concat = ", keras_tensor_concat)
# keras_tensor_concat = Tensor("concatenate_1/concat:0", shape=(?, 15), dtype=float32)
my_model = keras.models.Model( inputs=keras_tensor_input, output=keras_tensor_concat)
# dummy optimizer, loss, and metric so I can compile and test the model
my_model.compile(optimizer='rmsprop',loss='categorical_crossentropy', metrics=['accuracy'])
# a batch of size 1, for a tensor of shape =[3]
d1 = numpy.array([[1, 2, 3]])
out = my_model.predict( [ d1 ] )
print(out)
# [[ 1. 2. 3. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1.]]