Background

分别使用CNN和LSTM对图像和文字进行处理:

将两个神经网络结合:

应用领域

图像搜索

安全

鉴黄

涉猎知识

  • 数字图像处理

    • 图像读取
    • 图像缩放
    • 图像数据纬度变换
  • 自然语言处理
    • 文字清洗
    • 文字嵌入(Embedding)
  • CNN卷积神经网络
    • 图像特征提取
    • 迁移学习(Transfer Learning)
  • LSTM递归神经网络
    • 文字串(sequence)特征提取
  • DNN深度神经网络
    • 从图像特征和文字串(sequence)的特征预测下一个单词

使用数据集

Framing Image Description as a Ranking Task:Data, Models, and Evaluation Metrics,2013.

  • Flickr8K
  • 8000个图像,每幅图5个标题,描述图像里面的事物和事件
  • 不包含著名人物和地点
  • 分为3个集合:6000个训练图像,1000个开发图像,1000个测试图像

数据示例

  • A child in a pink dress is climbing up a set of stairs in an entry way.
  • A girl going into a wooden building .
  • A little girl climbing into a wooden playhouse.
  • A little girl climbing the stairs to her playhouse.
  • A little girl in a pink dress going into a wooden cabin

目标

自动生成英文标题,与人类生成的标题越相似越好。

衡量两个句子的==相似度(BLEU)==,一个句子与其他几个句子的相似度==(Corpus BLEU)==

  • BLEU:Bilingual Evaluation Understudy(双语评估替换)。
  • BLEU是一个比较候选文本翻译与其他一个或多个参考翻译的评价分数。尽管他是为翻译工作而开发的,但是仍然可以用于评估自动生成的文本质量

VGG16网络模型

Very Deep Convplutional Networks For Large-Scale Visual Recognition

  • Pre-trained model:Oxford Visual Geometry Group赢得2014ImageNet竞赛
  • 用于图像分类,讲输入图像分为1000个类别

绿色标注为VGG网络。可以看出,该网络有16个权值层,5个池化层

编写代码实现网络(练习)

准备框架

from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
def generate_vgg16():
"""
搭建VGG16神经网络
:return:VGG16神经网络
""" pass if __name__ =='__main__':
model = generate_vgg16()
model.summary()

编辑输入

VGG16输入为(224,224,RGB)的图像

input_shape = (224, 224, 3)

部分网络结构

model = Sequential([
Conv2D(64, (3, 3), input_sahpe=input_shape,padding='same', activation='relu'),
# 第一层二维卷积层
# 第一个参数表示有64个滤波器
# 第二个参数表示滤波器的大小(3*3)
# 输入类型为我们定义的类型
# 输入长和宽的关系是相同same
# 激活函数使用relu
Conv2D(64, (3, 3), padding='same', activation='relu'),
# 第二层二维卷积层
# 第一个参数表示有64个滤波器
# 第二个参数表示滤波器的大小(3*3)
# 第二层不需要指定输入类型,因为一定是第一层输出的类型
# 输入长和宽的关系是相同same
# 激活函数使用relu
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
# 第三层是二维最大池化层
Conv2D(128, (3, 3), padding='same', activation='relu'),
Conv2D(128, (3, 3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(256, (3, 3), padding='same', activation='relu'),
Conv2D(256, (3, 3), padding='same', activation='relu'),
Conv2D(256, (3, 3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(512, (3, 3), padding='same', activation='relu'),
Conv2D(512, (3, 3), padding='same', activation='relu'),
Conv2D(512, (3, 3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(512, (3, 3), padding='same', activation='relu'),
Conv2D(512, (3, 3), padding='same', activation='relu'),
Conv2D(512, (3, 3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Flatten(),
# Maxpooling层和全连接层直角要加入flatten
Dense(4096, activation='relu'),
Dense(4096, activation='relu'),
Dense(1000, activation='softmax')
])

Maxpooling层和全连接层之间要使用Flatten。

总代码为:

from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.layers import Conv2D
from keras.layers import MaxPooling2D def generate_vgg16():
"""
搭建VGG16神经网络
:return:VGG16神经网络
"""
input_shape = (224, 224, 3)
# 输入类型,224*224的RGB图片
model = Sequential([
Conv2D(64, (3, 3), input_shape=input_shape,padding='same', activation='relu'),
# 第一层二维卷积层
# 第一个参数表示有64个滤波器
# 第二个参数表示滤波器的大小(3*3)
# 输入类型为我们定义的类型
# 输入长和宽的关系是相同same
# 激活函数使用relu
Conv2D(64, (3, 3), padding='same', activation='relu'),
# 第二层二维卷积层
# 第一个参数表示有64个滤波器
# 第二个参数表示滤波器的大小(3*3)
# 第二层不需要指定输入类型,因为一定是第一层输出的类型
# 输入长和宽的关系是相同same
# 激活函数使用relu
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
# 第三层是二维最大池化层
Conv2D(128, (3, 3), padding='same', activation='relu'),
Conv2D(128, (3, 3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(256, (3, 3), padding='same', activation='relu'),
Conv2D(256, (3, 3), padding='same', activation='relu'),
Conv2D(256, (3, 3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(512, (3, 3), padding='same', activation='relu'),
Conv2D(512, (3, 3), padding='same', activation='relu'),
Conv2D(512, (3, 3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(512, (3, 3), padding='same', activation='relu'),
Conv2D(512, (3, 3), padding='same', activation='relu'),
Conv2D(512, (3, 3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Flatten(),
# Maxpooling层和全连接层直角要加入flatten
Dense(4096, activation='relu'),
Dense(4096, activation='relu'),
Dense(1000, activation='softmax')
])
return model if __name__ == '__main__':
model = generate_vgg16()
model.summary()

运行可见输出:

看图说话项目

本项目所需的所有数据集和网络如下:

链接:https://pan.baidu.com/s/1nP856AdlTmcRSPez2--u5A

密码:vs7b

图像特征提取

将flicker8K的图像文件转为图像特征,保存为字典pickle文件

  • 从给定的VGG16网络结构文件(JS文件)和网络权值文件,创建VGG16网络
  • 修改网络结构(去除最后一层)
  • 利用修改的网络结构,提取flicker8K数据集中所有的图像特征,利用字典保存,key为文件名(不带.jpg后缀),value为一个网络的输出
  • 将字典保存为features.pkl文件(使用pickle库)

理想网络模型

简化网络模型

从图像到特征

迁移学习(transfer learning)

  • VGG16 CNN原本的目标是分类,基于ImageNet数据集进行训练,训练所需的时间比较大,需要4个GPU训练3星期左右
  • 可以调整VGG16的网络结构为图像标题生成服务
  • VGG16最后一层是将倒数第二层4096纬的输出转为1000纬的输出作为1000类别的分类概率
  • 我们可以通过去除最后一层,将倒数第二层的4096纬的输出作为图像标题生成模型的图像特征

代码实现

from keras.models import model_from_json
from PIL import Image as pil_image
from keras import backend as K
import numpy as np
from pickle import dump
from os import listdir
import os
from keras.models import Model
import keras
from tqdm import tqdm def load_img_as_np_array(path, target_size):
"""从给定文件[加载]图像,[缩放]图像大小为给定target_size,返回[Keras支持]的浮点数numpy数组. # Arguments
path: 图像文件路径
target_size: 元组(图像高度, 图像宽度). # Returns
numpy 数组.
"""
img = pil_image.open(path) # 打开文件
img = img.resize(target_size,pil_image.NEAREST) # NEARSET 是一种插值方法
return np.asarray(img, dtype=K.floatx()) #转化为向量 def preprocess_input(x):
"""预处理图像用于网络输入, 将图像由RGB格式转为BGR格式.
将图像的每一个图像通道减去其均值
均值BGR三个通道的均值分别为 103.939, 116.779, 123.68 # Arguments
x: numpy 数组, 4维.
data_format: Data format of the image array. # Returns
Preprocessed Numpy array.
"""
# 'RGB'->'BGR', https://www.scivision.co/numpy-image-bgr-to-rgb/
x = x[..., ::-1]
mean = [103.939, 116.779, 123.68] x[..., 0] -= mean[0]
x[..., 1] -= mean[1]
x[..., 2] -= mean[2] return x def load_vgg16_model():
"""从当前目录下面的 vgg16_exported.json 和 vgg16_exported.h5 两个文件中导入 VGG16 网络并返回创建的网络模型
# Returns
创建的网络模型 model
"""
json_file = open("vgg16_exported.json","r")
loaded_model_json = json_file.read()
json_file.close() model = model_from_json(loaded_model_json)
model.load_weights("vgg16_exported.h5") return model def extract_features(directory):
"""提取给定文件夹中所有图像的特征, 将提取的特征保存在文件features.pkl中,
提取的特征保存在一个dict中, key为文件名(不带.jpg后缀), value为特征值[np.array] Args:
directory: 包含jpg文件的文件夹 Returns:
None
"""
model = load_vgg16_model()
# 去除模型最后一层
model.layers.pop()
model = Model(inputs=model.inputs, outputs=model.layers[-1].output)
print("Extracting...") features = dict()
pbar = tqdm(total=len(listdir(directory)), desc="进度", ncols=100)
for fn in listdir(directory):
print("\tRead file:", fn)
fn_path = directory + '/' + fn # 返回长、宽、通道的三维张量
arr = load_img_as_np_array(fn_path, target_size=(224,224)) # 改变数组的形态,增加一个维度(批处理)—— 4维
arr = arr.reshape((1, arr.shape[0], arr.shape[1], arr.shape[2]))
# 预处理图像为VGG模型的输入
arr = preprocess_input(arr)
# 计算特征
feature = model.predict(arr, verbose=0) print("\tprocessed...",end='')
id = os.path.splitext(fn)[0]
features[id] = feature
print("Saved. ", id)
pbar.update(1) print("Complete extracting.")
return features if __name__ == '__main__':
# 提取Flicker8k数据集中所有图像的特征,保存在一个文件中, 大约一小时的时间,最后的文件大小为127M
# 下载zip文件,解压缩到当前目录的子文件夹Flicker8k_Dataset, 注意上传完成的作业时不要上传这个数据集文件
directory = './Flicker8k_Dataset'
features = extract_features(directory)
print('提取特征的文件个数:%d' % len(features))
print(keras.backend.image_data_format())
#保存特征到文件
dump(features, open('features.pkl', 'wb'))

(CV学习笔记)看图说话(Image Captioning)-1的更多相关文章

  1. (CV学习笔记)看图说话(Image Captioning)-2

    实现load_img_as_np_array def load_img_as_np_array(path, target_size): """从给定文件[加载]图像,[缩 ...

  2. 学习笔记TF060:图像语音结合,看图说话

    斯坦福大学人工智能实验室李飞飞教授,实现人工智能3要素:语法(syntax).语义(semantics).推理(inference).语言.视觉.通过语法(语言语法解析.视觉三维结构解析)和语义(语言 ...

  3. Multimodal —— 看图说话(Image Caption)任务的论文笔记(一)评价指标和NIC模型

    看图说话(Image Caption)任务是结合CV和NLP两个领域的一种比较综合的任务,Image Caption模型的输入是一幅图像,输出是对该幅图像进行描述的一段文字.这项任务要求模型可以识别图 ...

  4. (CV学习笔记)Attention

    Attention(注意力机制) Attention for Image Attention for Machine Translation Self-Attention 没有image-Attent ...

  5. Windows phone 8 学习笔记(5) 图块与通知

    原文:Windows phone 8 学习笔记(5) 图块与通知 基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标.一般一个应用必须有一个默认 ...

  6. iOS学习笔记20-地图(二)MapKit框架

    一.地图开发介绍 从iOS6.0开始地图数据不再由谷歌驱动,而是改用自家地图,当然在国内它的数据是由高德地图提供的. 在iOS中进行地图开发主要有三种方式: 利用MapKit框架进行地图开发,利用这种 ...

  7. [看图说话]在VMware Workstation 9中安装Mac OS X 10.8 Mountain Lion

    本文环境: CPU:Intel Core i7 920: OS:Windows 7: 内存:8G: 玩Hackintosh各有各的理由,不管什么理由,利用虚拟机安装Mac OS X都是一个可行的办法. ...

  8. Windows phone 8 学习笔记(5) 图块与通知(转)

    基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标.一般一个应用必须有一个默认图块,还可以有若干个次要图块.另外,通知与图块的关系比较密切,我们 ...

  9. BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记看另一篇吧】

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Stat ...

随机推荐

  1. 从一个想法看 FreeBSD 是商业化还是学院派

    在某知名计算机网络论坛上我看到一个帖子,说自己想根据 FreeBSD 做一个移动的终端操作系统,就像安卓,苹果的 IOS 一样的. 逆向思维当初开发安卓的时候不可能没有考虑过 FreeBSD,因为无论 ...

  2. 解决springMVC https环境 jstlview redirect时变为http请求的问题

    <property name="redirectHttp10Compatible" value="false" />

  3. [POJ2828] Buy Tickets(待续)

    [POJ2828] Buy Tickets(待续) 题目大意:多组测试,每组给出\(n\)条信息\((a,b)\),表示\(b\)前面有\(a\)个人,顺序靠后的信息优先级高 Solution.1 由 ...

  4. 1 [main] DEBUG Sigar - no sigar-amd64-winnt.dll in java.library.path org.hyperic.sigar.SigarException: no sigar-amd64-winnt.dll in java.library.path

    github上一个java项目,在myeclipse中运行正常,生成jar后,运行报错: 1 [main] DEBUG Sigar - no sigar-amd64-winnt.dll in java ...

  5. Python图像处理库——PIL

    PIL全称Python Image Library,是python官方的图像处理库,包含各种图像处理模块.Pillow是PIL的一个派生分支,包含与PIL相同的功能,并且更灵活.python3.0之后 ...

  6. Flutter Widget中的State

    一.Flutter 的声明式视图开发 在原生系统(Android.iOS)或原生JavaScript 开发的话,应该知道视图开发是命令式的,需要精确地告诉操作系统或浏览器用何种方式去做事情. 比如,如 ...

  7. 第13 章 : Kubernetes 网络概念及策略控制

    Kubernetes 网络概念及策略控制 本文将主要分享以下 5 方面的内容: Kubernetes 基本网络模型: Netns 探秘: 主流网络方案简介: Network Policy 的用处: 思 ...

  8. 生产环境中mysql数据库由主从关系切换为主主关系

    目录 一.清除原从数据库数据及主从关系 1.1.关闭主从数据库原有的主从关系 1.2.清除从数据库原有数据 二.将主库上的数据备份到从库 2.1.备份主库数据到从库 2.2.在从库使用tsc.sql文 ...

  9. Dynamics CRM与ADFS安装到同一台服务器后ADFS服务与Dynamics CRM沙盒服务冲突提示808端口占用问题

    当我们安装Dynamics CRM的产品时如果是单台服务器部署而且部署了IFD的情况会遇到一个问题就是ADFS服务的监听端口和Dynamics CRM沙盒服务的端口冲突了. 这样会导致两个服务中的一个 ...

  10. OOJML系列总结

    目录 0x0 JML理论相关 0.0 概念及作用 0.1 JML语法学习 0x1 使用openJml以及JMLUnitNG 1.0 使用openjml 1.1使用JMLUnitNG 0x2 作业架构设 ...