【问题标题】:Image Captioning with Tensorflow outputting the same caption for all imagesImage Captioning with Tensorflow 为所有图像输出相同的标题
【发布时间】:2022-11-29 05:30:02
【问题描述】:

我正在使用带有 TensorFlow 的 Flick8k 数据集开发一个图像字幕模型,我遇到了一个问题,即模型为每个图像输出相同的字幕。

我正在使用 Xception 网络首先提取所有图像的特征向量。然后,我创建了一个包含特征向量以及经过清理和矢量化的字幕的 TF 数据集。

以下是生成数据集的代码,其中 encoded_img_train/test 是特征向量列表,cap_train/test 是向量化字幕列表。

def create_dataset(images, captions, batch_size):
  def map_func(decoder_input, decoder_output, feature):
    x = {'decoder_in': decoder_input, 'encoder_in': feature}
    y = {'decoder_out': decoder_output}
    return x, y
  
  decoder_input = []
  decoder_output = []
  for caption in captions:
    in_seq = [token_start] + caption[:-1]
    out_seq = caption[1:] + [token_end]
    # Add padding to input captions
    in_seq = tf.keras.preprocessing.sequence.pad_sequences([in_seq], maxlen=38, padding='post')[0]
    # Add padding to output captions
    out_seq = tf.keras.preprocessing.sequence.pad_sequences([out_seq], maxlen=38, padding='post')[0]

    decoder_input.append(in_seq)
    decoder_output.append(out_seq)

  dataset = tf.data.Dataset.from_tensor_slices((decoder_input, decoder_output, images))
  dataset = dataset.map(map_func)
  dataset = dataset.repeat()
  dataset = dataset.shuffle(1000).batch(64)
  dataset = dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)

  return dataset

train_dataset = create_dataset(encoded_img_train,cap_train,BATCH_SIZE)
val_dataset = create_dataset(encoded_img_test,cap_test,BATCH_SIZE)

这是我的模型

inputs1 = Input(shape=(2048,), name='encoder_in')
fe1 = tf.keras.layers.Dropout(0.5)(inputs1)
fe2 = tf.keras.layers.Dense(units, activation='relu', name='encoder_dense')(inputs1)

inputs2 = tf.keras.layers.Input(shape=(None,), name='decoder_in')
se1 = tf.keras.layers.Embedding(input_dim=vocab_size, output_dim=embedding_dim)(inputs2)
decoder_gru1 = GRU(units, name='decoder_gru1',
                   return_sequences=True)(se1)
decoder_gru2 = GRU(units, name='decoder_gru2',
                   return_sequences=True)(decoder_gru1)
decoder_gru3 = GRU(units, name='decoder_gru3',
                   return_sequences=True)(decoder_gru2)
decoder_dense = Dense(vocab_size, activation='linear', name='decoder_out')(decoder_gru3)

model = tf.keras.models.Model(inputs=[inputs1, inputs2], outputs=decoder_dense)
model.summary()

这就是我训练模型的方式

optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)

model.compile(loss='sparse_categorical_crossentropy', optimizer=optimizer)

epochs = 20
history = model.fit(train_dataset,validation_data=val_dataset, epochs=epochs, validation_steps=3, steps_per_epoch=steps_per_epoch)

最后这就是我从图像生成预测的方式

def generate_caption(image_id,true_caption,max_tokens=30):

    encoder_input = features[image_id]
    encoder_input = np.expand_dims(encoder_input, axis=0)

    shape = (1, max_tokens)
    decoder_input = np.zeros(shape=shape, dtype=np.int)

    token_id = token_start
  
    output=[]

    count_tokens = 0

    while token_id != token_end and count_tokens < max_tokens:
        
        decoder_input[0, count_tokens] = token_id

        input_data ={'encoder_in':encoder_input ,'decoder_in': decoder_input}
        
        predict = model.predict(input_data)
        
        token_id = np.argmax(predict[0, count_tokens, :])
        
        output.append(token_id)
        
        count_tokens += 1
    
    print('Predicted caption',tokenizer.sequences_to_texts([output]))
    print(len(output))
    print('True captions',tokenizer.sequences_to_texts([true_caption]))
    
    img = mpimg.imread(image_path+image_id)
    imgplot = plt.imshow(img)
    plt.show()
    
generate_caption(img_test[1],cap_test[1])

在训练期间,训练损失稳定在 2.17 左右,当对图像生成预测时,输出如下:

这个解决方案的整体架构是不是错了?还是我缺少一些东西来使这项工作顺利进行?

【问题讨论】:

    标签: python tensorflow machine-learning keras


    【解决方案1】:

    我遇到了同样的问题,你找到答案了吗?

    【讨论】:

      猜你喜欢
      • 2020-06-11
      • 2016-10-09
      • 2022-10-04
      • 2020-10-27
      • 2017-02-25
      • 1970-01-01
      • 1970-01-01
      • 2020-02-04
      • 2019-12-02
      相关资源
      最近更新 更多