Keras 将输入张量与neg 1张量的倍数串联

Keras 将输入张量与neg 1张量的倍数串联,keras,tf.keras,Keras,Tf.keras,相似的帖子:首先,这两篇帖子即使不相同,也是相似的。我试图实现这些目标,但徒劳无功。所以我错过了一些东西,可能是因为我在Keras方面缺乏经验。 , 问题: 我有一个数据生成器,可以将数据输入各种模型,以评估模型性能并学习KERA model.fit_generator(generator=img_gen.next_train(), .... 此生成器生成的输入之一是形状为[batch\u size,num\u letters]的张量“labels”。这个张量是 K.ctc_batch_co

相似的帖子:首先,这两篇帖子即使不相同,也是相似的。我试图实现这些目标,但徒劳无功。所以我错过了一些东西,可能是因为我在Keras方面缺乏经验。 ,

问题: 我有一个数据生成器,可以将数据输入各种模型,以评估模型性能并学习KERA

model.fit_generator(generator=img_gen.next_train(), ....
此生成器生成的输入之一是形状为[batch\u size,num\u letters]的张量“labels”。这个张量是

K.ctc_batch_cost(labels, .... 
与第369行类似

上述“keras示例”创建了一个RNN/GRU,其中RNN的每个输出步骤都是ctc的一个输入,RNN中有num_字母步骤,标签的形状为(?,num_字母)。到目前为止,这在我测试的前6款车型上运行良好

我正在测试一个新模型,其中RNN/GRU输出的每个步骤都是ctc的“1到n”输入,并将其留给培训以优化每个步骤的输出。因此,我的ctc在第一次输入时需要一个shape=(?,num_字母*n)的张量,但数据生成器生成shape=(?,num_字母)

旁注:我的模型中的RNN实际上生成一个整体形状=(?,n,num_字母)。我知道如何将其转换为(?,n*num_字母)

解决方案1是一种黑客攻击,请更改生成器,使其对于正在测试的此型号是唯一的。此生成器将生成形状=(?,num_字母*n)的张量。我不喜欢这样,因为生成器也在被评估中,并且希望它对于每个被评估的模型都是常量

解决方案2是一种破解,创建一个生成器,封装原始生成器并增加生成的输出

解决方案3:让模型输入shape=(?,num_字母)并连接必要的填充,以便形状是ctc想要的(?,num_字母*n)

以下是我尝试过的:

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)
# 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)

# https://stackoverflow.com/questions/53865471/using-subtract-layer-in-keras
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

# https://stackoverflow.com/questions/53250533/how-to-use-tile-function-in-keras
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.]]
注意事项:

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)
# 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)

# https://stackoverflow.com/questions/53865471/using-subtract-layer-in-keras
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

# https://stackoverflow.com/questions/53250533/how-to-use-tile-function-in-keras
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.]]
  • 本可以使形状保持不变=[num_letters*(n-1)]并放下瓷砖,但缺少批量大小的问题仍然存在
  • 如果我将batch_size作为第一个维度,那么它仍然失败,因为(?,3)不能与(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中进行包装,然后才能将其作为输入提供给keras.layer

    多谢各位

    解决方案如下:

    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)
    
    # 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)
    
    # https://stackoverflow.com/questions/53865471/using-subtract-layer-in-keras
    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
    
    # https://stackoverflow.com/questions/53250533/how-to-use-tile-function-in-keras
    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.]]