使用机器学习生成图像描述(上)

简介: 使用机器学习生成图像描述

在本文中,我们将为各种图像生成文字描述

图像描述是为图像提供适当文字描述的过程。作为人类,这似乎是一件容易的任务,即使是五岁的孩子也可以轻松完成,但是我们如何编写一个将输入作为图像并生成标题作为输出的计算机程序呢?

在深度神经网络的最新发展之前,业内最聪明的人都无法解决这个问题,但是在深度神经网络问世之后,考虑到我们拥有所需的数据集,这样做是完全有可能的。

例如,网络模型可以生成与下图相关的以下任何标题,即“A white dog in a grassy area”,“white dog with brown spots”甚至“A dog on grass and some pink flowers ”。

640.png

数据集

我们选择的数据集为“ Flickr 8k”。我们之所以选择此数据,是因为它易于访问且具有可以在普通PC上进行训练的完美大小,也足够训练网络生成适当的标题。数据分为三组,主要是包含6k图像的训练集,包含1k图像的开发集和包含1k图像的测试集。每个图像包含5个标题。示例之一如下:

640.png

 

Achildinapinkdressisclimbingupasetofstairsinanentryway.
Agirlgoingintoawoodenbuilding.
Alittlegirlclimbingintoawoodenplayhouse.
Alittlegirlclimbingthestairstoherplayhouse.
Alittlegirlinapinkdressgoingintoawoodencabin.

数据清理

任何机器学习程序的第一步也是最重要的一步是清理数据并清除所有不需要的数据。在处理标题中的文本数据时,我们将执行基本的清理步骤,例如将计算机中的所有字母都转换为小写字母“ Hey”和“ hey”是两个完全不同的单词,删除特殊标记和标点符号,例如*, (,£,$,%等),并消除所有包含数字的单词。

我们首先为数据集中的所有唯一内容创建词汇表,即8000(图片数量)* 5(每个图像的标题)= 40000标题。我们发现它等于8763。但是这些词中的大多数只出现了1到2次,我们不希望它们出现在我们的模型中,因为这不会使我们的模型对异常值具有鲁棒性。因此,我们将词汇中包含的单词的最少出现次数设置为10个阈值,该阈值等于1652个唯一单词。

我们要做的另一件事是在每个描述中添加两个标记,以指示字幕的开始和结束。这两个标记分别是“ startseq”和“ endseq”,分别表示字幕的开始和结尾。

首先,导入所有必需的库:

importnumpyasnpfromnumpyimportarrayimportpandasaspdimportmatplotlib.pyplotaspltimportstringimportosfromPILimportImageimportglobimportpicklefromtimeimporttimefromkeras.preprocessingimportsequencefromkeras.modelsimportSequentialfromkeras.layersimportLSTM, Embedding, Dense, Flatten, Reshape, concatenate, Dropoutfromkeras.optimizersimportAdamfromkeras.layers.mergeimportaddfromkeras.applications.inception_v3importInceptionV3fromkeras.preprocessingimportimagefromkeras.modelsimportModelfromkerasimportInput, layersfromkeras.applications.inception_v3importpreprocess_inputfromkeras.preprocessing.sequenceimportpad_sequencesfromkeras.utilsimportto_categorical

让我们定义一些辅助函数:

#loaddescriptionsdefload_doc(filename):
file=open(filename, 'r')
text=file.read()
file.close()
returntextdefload_descriptions(doc):
mapping=dict()
forlineindoc.split('\n'):
tokens=line.split()
iflen(line) <2:
continueimage_id, image_desc=tokens[0], tokens[1:]
image_id=image_id.split('.')[0]
image_desc=' '.join(image_desc)
ifimage_idnotinmapping:
mapping[image_id] =list()
mapping[image_id].append(image_desc)
returnmappingdefclean_descriptions(descriptions):
table=str.maketrans('', '', string.punctuation)
forkey, desc_listindescriptions.items():
foriinrange(len(desc_list)):
desc=desc_list[i]
desc=desc.split()
desc= [word.lower() forwordindesc]
desc= [w.translate(table) forwindesc]
desc= [wordforwordindesciflen(word)>1]
desc= [wordforwordindescifword.isalpha()]
desc_list[i] =' '.join(desc)
returndescriptions#savedescriptionstofile, oneperlinedefsave_descriptions(descriptions, filename):
lines=list()
forkey, desc_listindescriptions.items():
fordescindesc_list:
lines.append(key+' '+desc)
data='\n'.join(lines)
file=open(filename, 'w')
file.write(data)
file.close()
#loadcleandescriptionsintomemorydefload_clean_descriptions(filename, dataset):
doc=load_doc(filename)
descriptions=dict()
forlineindoc.split('\n'):
tokens=line.split()
image_id, image_desc=tokens[0], tokens[1:]
ifimage_idindataset:
ifimage_idnotindescriptions:
descriptions[image_id] =list()
desc='startseq '+' '.join(image_desc) +' endseq'descriptions[image_id].append(desc)
returndescriptionsdefload_set(filename):
doc=load_doc(filename)
dataset=list()
forlineindoc.split('\n'):
iflen(line) <1:
continueidentifier=line.split('.')[0]
dataset.append(identifier)
returnset(dataset)
#loadtrainingdatasetfilename="dataset/Flickr8k_text/Flickr8k.token.txt"doc=load_doc(filename)
descriptions=load_descriptions(doc)
descriptions=clean_descriptions(descriptions)
save_descriptions(descriptions, 'descriptions.txt')
filename='dataset/Flickr8k_text/Flickr_8k.trainImages.txt'train=load_set(filename)
train_descriptions=load_clean_descriptions('descriptions.txt', train)

让我们一一解释:

 load_doc:获取文件的路径并返回该文件内的内容

 load_descriptions:获取包含描述的文件的内容,并生成一个字典,其中以图像id为键,以描述为值列表

 clean_descriptions:通过将所有字母都转换为小写字母,忽略数字和标点符号以及仅包含一个字符的单词来清理描述

 save_descriptions:将描述字典作为文本文件保存到内存中

 load_set:从文本文件加载图像的所有唯一标识符

 load_clean_descriptions:使用上面提取的唯一标识符加载所有已清理的描述

数据预处理

接下来,我们对图像和字幕进行一些数据预处理。图像基本上是我们的特征向量,即我们对网络的输入。因此,我们需要先将它们转换为固定大小的向量,然后再将其传递到神经网络中。为此,我们使用了由Google Research [3]创建的Inception V3模型(卷积神经网络)进行迁移学习。该模型在'ImageNet'数据集[4]上进行了训练,可以对1000张图像进行图像分类,但是我们的目标不是进行分类,因此我们删除了最后一个softmax层,并为每张图像提取了2048个固定矢量,如图所示 以下:

640.png

标题文字是我们模型的输出,即我们必须预测的内容。但是预测并不会一次全部发生,而是会逐字预测字幕。为此,我们需要将每个单词编码为固定大小的向量(将在下一部分中完成)。为此,我们首先需要创建两个字典,即“单词到索引”将每个单词映射到一个索引(在我们的情况下为1到1652),以及“索引到单词”将字典将每个索引 映射到其对应的单词字典。我们要做的最后一件事是计算在数据集中具有最大长度的描述的长度,以便我们可以填充所有其他内容以保持固定长度。在我们的情况下,该长度等于34。

字词嵌入

如前所述,我们将每个单词映射到固定大小的向量(即200)中,我们将使用预训练的GLOVE模型。最后,我们为词汇表中的所有1652个单词创建一个嵌入矩阵,其中为词汇表中的每个单词包含一个固定大小的向量。

#Createalistofallthetrainingcaptionsall_train_captions= []
forkey, valintrain_descriptions.items():
forcapinval:
all_train_captions.append(cap)
#Consideronlywordswhichoccuratleast10timesinthecorpusword_count_threshold=10word_counts= {}
nsents=0forsentinall_train_captions:
nsents+=1forwinsent.split(' '):
word_counts[w] =word_counts.get(w, 0) +1vocab= [wforwinword_countsifword_counts[w] >=word_count_threshold]
print('Preprocessed words {} -> {}'.format(len(word_counts), len(vocab)))
ixtoword= {}
wordtoix= {}
ix=1forwinvocab:
wordtoix[w] =ixixtoword[ix] =wix+=1vocab_size=len(ixtoword) +1#oneforappended0's# Load Glove vectorsglove_dir = 'glove.6B'embeddings_index = {}f = open(os.path.join(glove_dir, 'glove.6B.200d.txt'), encoding="utf-8")for line in f:values = line.split()word = values[0]coefs = np.asarray(values[1:], dtype='float32')embeddings_index[word] = coefsf.close()embedding_dim = 200# Get 200-dim dense vector for each of the words in out vocabularyembedding_matrix = np.zeros((vocab_size, embedding_dim))for word, i in wordtoix.items():embedding_vector = embeddings_index.get(word)if embedding_vector is not None:embedding_matrix[i] = embedding_vector

让我们接收下这段代码:

 第1至5行:将所有训练图像的所有描述提取到一个列表中

 第9-18行:仅选择词汇中出现次数超过10次的单词

 第21–30行:创建一个要索引的单词和一个对单词词典的索引。

 第33–42行:将Glove Embeddings加载到字典中,以单词作为键,将vector嵌入为值

 第44–52行:使用上面加载的嵌入为词汇表中的单词创建嵌入矩阵

目录
相关文章
|
2月前
|
机器学习/深度学习 算法 数据可视化
JAMA | 机器学习中的可解释性:SHAP分析图像复刻与解读
JAMA | 机器学习中的可解释性:SHAP分析图像复刻与解读
740 1
|
2月前
|
人工智能 编解码 算法
使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理
在本教程中,您将学习在阿里云交互式建模平台PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理,实现文本驱动的图像编辑功能单卡即可完成AIGC图片风格变化、背景变化和主体变化等功能。让我们一同开启这场旅程,为您的图像编辑添上无限可能性的翅膀吧。
使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理
|
14天前
|
机器学习/深度学习 人工智能 自然语言处理
【CVPR2024】阿里云人工智能平台PAI图像编辑算法论文入选CVPR2024
近期,阿里云人工智能平台PAI发表的图像编辑算法论文在CVPR-2024上正式亮相发表。论文成果是阿里云与华南理工大学贾奎教授领衔的团队共同研发。此次入选标志着阿里云人工智能平台PAI自主研发的图像编辑算法达到了先进水平,赢得了国际学术界的认可。在阿里云人工智能平台PAI算法团队和华南理工大学的老师学生们一同的坚持和热情下,将阿里云在图像生成与编辑领域的先进理念得以通过学术论文和会议的形式,向业界传递和展现。
|
11天前
|
机器学习/深度学习 计算机视觉
【机器学习】LoFTR:革命性图像特征批评技术等领跑者
【机器学习】LoFTR:革命性图像特征批评技术等领跑者
22 1
|
11天前
|
机器学习/深度学习 算法
【机器学习】剪贴画图像等文本引导运动生成技术革新
【机器学习】剪贴画图像等文本引导运动生成技术革新
20 1
|
11天前
|
机器学习/深度学习 自然语言处理 计算机视觉
【机器学习】HQ-Edit引领图像编辑新潮流
【机器学习】HQ-Edit引领图像编辑新潮流
23 1
|
10天前
|
机器学习/深度学习 算法 数据挖掘
机器学习之聚类——MeanShift算法和图像矢量量化
机器学习之聚类——MeanShift算法和图像矢量量化
10 0
|
11天前
|
机器学习/深度学习 算法 PyTorch
【机器学习】稳定扩散在图像生成中的应用
【机器学习】稳定扩散在图像生成中的应用
15 0
|
11天前
|
机器学习/深度学习 算法
【机器学习】BK- SDM与LCM的融合策略在文本到图像生成中的应用
【机器学习】BK- SDM与LCM的融合策略在文本到图像生成中的应用
21 0
|
2月前
|
机器学习/深度学习 算法 数据可视化
【机器学习】描述K-means算法的步骤
【5月更文挑战第11天】【机器学习】描述K-means算法的步骤