📜  在 Flickr8K 数据集上使用深度学习的图像字幕生成器(1)

📅  最后修改于: 2023-12-03 15:37:20.214000             🧑  作者: Mango

在 Flickr8K 数据集上使用深度学习的图像字幕生成器

本项目介绍了如何使用深度学习模型生成图片描述文本。我们基于 Flickr8K 数据集,使用卷积神经网络(CNN)和循环神经网络(RNN)构建图像字幕生成器。通过学习数据集中的图像和对应的描述文本,模型可以自动生成图像的文字描述。

数据集概述

Flickr8K 数据集包括 8000 张图片,针对每张图片都有 5 个不同的描述文本。该数据集可用于训练模型,也可以在模型训练完成后作为测试集使用。

模型结构

我们的模型采用了 CNN 和 RNN 进行联合训练。具体地,我们使用预训练的 VGG-16 模型提取图像特征,然后将这些特征作为 RNN 的输入,生成相应的文字描述。

# VGG-16 模型
image_model = Sequential()
image_model.add(Conv2D(64, (3, 3), padding='valid', activation='relu', input_shape=(224, 224, 3)))
image_model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
image_model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
image_model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
image_model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
image_model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
image_model.add(Conv2D(256, (3, 3), activation='relu', padding='same'))
image_model.add(Conv2D(256, (3, 3), activation='relu', padding='same'))
image_model.add(Conv2D(256, (3, 3), activation='relu', padding='same'))
image_model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
image_model.add(Conv2D(512, (3, 3), activation='relu', padding='same'))
image_model.add(Conv2D(512, (3, 3), activation='relu', padding='same'))
image_model.add(Conv2D(512, (3, 3), activation='relu', padding='same'))
image_model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
image_model.add(Conv2D(512, (3, 3), activation='relu', padding='same'))
image_model.add(Conv2D(512, (3, 3), activation='relu', padding='same'))
image_model.add(Conv2D(512, (3, 3), activation='relu', padding='same'))
image_model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
image_model.add(Flatten())

# RNN 模型
caption_model = Sequential()
caption_model.add(Embedding(vocab_size, embedding_dim, input_length=max_length))
caption_model.add(LSTM(256, return_sequences=True))
caption_model.add(TimeDistributed(Dense(128, activation='relu')))
caption_model.add(TimeDistributed(Dense(vocab_size)))
caption_model.add(Activation('softmax'))

# 将两个模型合并
merged = Concatenate()([image_model.output, caption_model.output])
merged = LSTM(256, return_sequences=False)(merged)
merged = Dense(vocab_size)(merged)
outputs = Activation('softmax')(merged)

# 建立最终的模型
model = Model(inputs=[image_model.input, caption_model.input], outputs=outputs)
训练过程

我们使用 Keras 框架进行模型训练。在训练过程中,我们使用 SGD 优化器和交叉熵损失函数,并记录训练过程中的损失值和验证集上的精度。

model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
model.fit([X1_train, X2_train], y_train, epochs=20, batch_size=128, validation_data=([X1_test, X2_test], y_test), verbose=2)
生成图像描述

我们可以使用训练好的模型生成任意一张图片的描述。具体地,给定一张图片,我们首先使用 VGG-16 模型提取其特征,然后将特征作为输入传递给训练好的模型,即可得到该图片的描述文本。

# 加载模型
model = load_model('model_weights.h5')

# 加载图片并提取特征
img = load_img('example.jpg', target_size=(224, 224))
img = img_to_array(img)
img = np.expand_dims(img, axis=0)
img = preprocess_input(img)
features = image_model.predict(img)

# 生成图片描述文本
in_text = 'startseq'
for i in range(max_length):
    sequence = tokenizer.texts_to_sequences([in_text])[0]
    sequence = pad_sequences([sequence], maxlen=max_length)
    yhat = model.predict([features, sequence], verbose=0)
    yhat = np.argmax(yhat)
    word = word_for_id(yhat, tokenizer)
    if word is None:
        break
    in_text += ' ' + word
    if word == 'endseq':
        break
print(in_text)

总之,我们可以使用深度学习模型生成图像描述文本。该项目采用 Flickr8K 数据集和卷积神经网络与循环神经网络联合训练的架构。该模型可以自动生成与输入图片相关的描述文本,并具有一定的泛化能力。