机器学习CV代码练习(七)之图像描述-预测某张图片的描述
·
机器学习CV代码练习(七)之图像描述-预测某张图片的描述
BLEU指标评估产生标题的质量
from nltk.translate.bleu_score import corpus_bleu
#手工产生(标准)为一个句子
references = [[['there','is','a','cat','and','a','dog']]]#手工产生(标准)——三维列表、图像
candidates = [['there','is','a','cat','and','a','pig']]#电脑产生——二维列表
#一组句子和一个句子之间的好坏与差异,是否相似。weights参数指的是:设置不同的n−gram的权重(1−gram,2−gram,3−gram,4−gram)
# 第1个位置数值:用1−gram比较,将单词拆成1个一组,不考虑单词的顺序,将单词打乱,看一样的数量占比;)
# 第2个位置数值:用2-gram比较,将单词拆成2个一组,there is、is a、a cat...看一样的数量占比;)
# 第3个位置数值:用3−gram比较,将单词拆成3个一组,there is a、is a cat...看一样的数量占比;)
# 第4个位置数值:用4−gram比较,将单词拆成4个一组,there is a cat、is a cat and...看一样的数量占比;)
score = corpus_bleu(references,candidates,weights=(0.25,0.25,0.25,0.25))
print(score) #0.8091067115702212。数字越大,两个句子越相似。
#手工产生(标准)为多个句子:原理为-分别于手工产生的句子相比较,取相似度最大的值,可以比较一维列表
references = [[['there','is','a','cat','and','a','dog'],['there','is','a','dog','and','a','cat']]]#手工产生——三维列表、图像
candidates = [['there','is','a','cat','and','a','pig']]#电脑产生——二维列表
#一组句子和一个句子之间的好坏与差异,是否相似。weights参数指的是:设置不同的n−gram的权重(1−gram,2−gram,3−gram,4−gram)
# 第1个位置数值:用1−gram比较,将单词拆成1个一组,不考虑单词的顺序,将单词打乱,看一样的数量占比;)
# 第2个位置数值:用2-gram比较,将单词拆成2个一组,there is、is a、a cat...看一样的数量占比;)
# 第3个位置数值:用3−gram比较,将单词拆成3个一组,there is a、is a cat...看一样的数量占比;)
# 第4个位置数值:用4−gram比较,将单词拆成4个一组,there is a cat、is a cat and...看一样的数量占比;)
score = corpus_bleu(references,candidates,weights=(0.25,0.25,0.25,0.25))
print(score) #0.8091067115702212。数字越大,两个句子越相似。
完整代码:预测一张图片的标题+评估test数据集的生成质量
import util
import numpy as np
from pickle import load
from nltk.translate.bleu_score import corpus_bleu
from keras.models import load_model
from keras.preprocessing.sequence import pad_sequences
def word_for_id(integer, tokenizer):
"""
将一个整数转换为英文单词
:param integer: 一个代表英文的整数
:param tokenizer: 一个预先产生的keras.preprocessing.text.Tokenizer
:return: 输入整数对应的英文单词
"""
for word, index in tokenizer.word_index.items():
if index == integer:
return word
return None
def generate_caption(model, tokenizer, photo_feature, max_length = 40):
"""
根据输入的图像特征产生图像的标题
:param model: 预先训练好的图像标题生成神经网络模型
:param tokenizer: 一个预先产生的keras.preprocessing.text.Tokenizer
:param photo_feature:输入的图像特征, 为VGG16网络修改版产生的特征
:param max_length: 训练数据中最长的图像标题的长度
:return: 产生的图像的标题
"""
in_text = 'startseq'
for i in range(max_length):
sequence = tokenizer.texts_to_sequences([in_text])
sequence = pad_sequences(sequence,maxlen= max_length)[0].reshape(1,40)
# print(photo_feature.shape)
# print(sequence.shape)
# print([photo_feature,sequence])
output = model.predict([photo_feature,sequence])
# print('output',output)
integer = np.argmax(output)
word = word_for_id(integer,tokenizer)
if word is None:
break
in_text = in_text + " " + word
if word == "endseq":
break
return in_text
def generate_caption_run():#调用generate_caption函数
filename = 'Flickr_8k.testImages.txt'
test = util.load_ids(filename)
print('Dataset: %d' % len(test))
test_captions = util.load_clean_captions('descriptions.txt', test)
print('Captions: train number=%d' % len(test_captions))
# photo features
test_features = util.load_photo_features('features.pkl', test)
print('Photos: test=%d' % len(test_features))
filename = "model_0.h5"
model = load_model(filename)
print("load model done...")
# prepare tokenizer
tokenizer = load(open('tokenizer.pkl', 'rb'))
# 神经网络需要的nxm,其实是np.shape眼里的mxn
caption = generate_caption(model,tokenizer,test_features['1258913059_07c613f7ff'].reshape(1,4096),40)
print('1258913059_07c613f7ff 的预测结果result is:' + str(caption))
#根据4个BLEU分数来评估所有test数据集
evaluate_model(model,test_captions,test_features,tokenizer,40)
return caption
def evaluate_model(model, captions, photo_features, tokenizer, max_length = 40):
"""计算训练好的神经网络产生的标题的质量,根据4个BLEU分数来评估
Args:
model: 训练好的产生标题的神经网络
captions: dict, 测试数据集, key为文件名(不带.jpg后缀), value为图像标题list
photo_features: dict, key为文件名(不带.jpg后缀), value为图像特征
tokenizer: 英文单词和整数转换的工具keras.preprocessing.text.Tokenizer
max_length:训练集中的标题的最大长度
Returns:
tuple:
第一个元素为权重为(1.0, 0, 0, 0)的BLEU分数
第二个元素为权重为(0.5, 0.5, 0, 0)的BLEU分数
第三个元素为权重为(0.3, 0.3, 0.3, 0)的BLEU分数
第四个元素为权重为(0.25, 0.25, 0.25, 0.25)的BLEU分数
from nltk.translate.bleu_score import corpus_bleu
#手工产生(标准)为一个句子
references = [[['there','is','a','cat','and','a','dog']]]#手工产生(标准)——三维列表、图像
candidates = [['there','is','a','cat','and','a','pig']]#电脑产生——二维列表
#一组句子和一个句子之间的好坏与差异,是否相似。weights参数指的是:设置不同的n−gram的权重(1−gram,2−gram,3−gram,4−gram)
# 第1个位置数值:用1−gram比较,将单词拆成1个一组,不考虑单词的顺序,将单词打乱,看一样的数量占比;)
# 第2个位置数值:用2-gram比较,将单词拆成2个一组,there is、is a、a cat...看一样的数量占比;)
# 第3个位置数值:用3−gram比较,将单词拆成3个一组,there is a、is a cat...看一样的数量占比;)
# 第4个位置数值:用4−gram比较,将单词拆成4个一组,there is a cat、is a cat and...看一样的数量占比;)
score = corpus_bleu(references,candidates,weights=(0.25,0.25,0.25,0.25))
print(score) #0.8091067115702212。数字越大,两个句子越相似。
#手工产生(标准)为多个句子:原理为-分别于手工产生的句子相比较,取相似度最大的值,可以比较一维列表
references = [[['there','is','a','cat','and','a','dog'],['there','is','a','dog','and','a','cat']]]#手工产生——三维列表、图像
candidates = [['there','is','a','cat','and','a','pig']]#电脑产生——二维列表
#一组句子和一个句子之间的好坏与差异,是否相似。weights参数指的是:设置不同的n−gram的权重(1−gram,2−gram,3−gram,4−gram)
# 第1个位置数值:用1−gram比较,将单词拆成1个一组,不考虑单词的顺序,将单词打乱,看一样的数量占比;)
# 第2个位置数值:用2-gram比较,将单词拆成2个一组,there is、is a、a cat...看一样的数量占比;)
# 第3个位置数值:用3−gram比较,将单词拆成3个一组,there is a、is a cat...看一样的数量占比;)
# 第4个位置数值:用4−gram比较,将单词拆成4个一组,there is a cat、is a cat and...看一样的数量占比;)
score = corpus_bleu(references,candidates,weights=(0.25,0.25,0.25,0.25))
print(score) #0.8091067115702212。数字越大,两个句子越相似。
"""
actual, predicted = list(),list()#actual:给定的多个标题;predict:计算机预测产生的标题
#step over the whole set
for key,caption_list in captions.items():
# generate description
yhat = generate_caption(model,tokenizer,photo_features[key].reshape(1,4096),max_length)
print(key,"的预测结果为:",yhat)
#store actual and predicted
references = [d.split() for d in caption_list]
actual.append(references)#给定的多个标题
predicted.append(yhat.split())#计算机预测产生的标题
#calculate BLEU score
blue1 = corpus_bleu(actual,predicted,weights=(1.0,0,0,0))
blue2 = corpus_bleu(actual, predicted, weights=(0.5, 0.5, 0, 0))
blue3 = corpus_bleu(actual, predicted, weights=(0.3, 0.3, 0.3, 0))
blue4 = corpus_bleu(actual, predicted, weights=(0.25, 0.25, 0.25, 0.25))
print('BLUE-1: %f' % blue1)
print('BLUE-2: %f' % blue2)
print('BLUE-3: %f' % blue3)
print('BLUE-4: %f' % blue4)
return blue1,blue2,blue3,blue4
if __name__ == "__main__":
generate_caption_run()
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)