Inception
0. Google Inception模型简介
Inception为Google开源的CNN模型,至今已经公开四个版本,每一个版本都是基于大型图像数据库ImageNet中的数据训练而成。因此我们可以直接利用Google的Inception模型来实现图像分类。本篇文章主要以Inception_v3模型为基础。Inception v3模型大约有2500万个参数,分类一张图像就用了50亿的乘加指令。在一台没有GPU的现代PC上,分类一张图像转眼就能完成。
1. Google Inception模型发展
以下为Inception四个版本所对应的论文,末尾为ILSVRC中的Top-5错误率:
2. 下载Inception_v3模型
Inception_v3模型源码下载
当然,要想自己从头训练一个Inception_v3模型是可以的,但费时费力,没有必要。当然,在已经训练好的Inception_v3模型上修修改改retrain是没有问题的,具体将在后续文中提到。
解压下载好的压缩文件,如下:
文件列表
classify_image_graph_def.pb文件为Inception_v3本体
imagenet_2012_challenge_label_map_proto.pbtxt文件内容如下所示:
imagenet_2012_challenge_label_map_proto.pbtxt
包含target_class与target_class_string,前者为分类代码,从1~1000,共1k类,记为Node_ID;后者为一编号字符串“n********”,可以理解为“地址”或者“桥梁”,记为UID。
imagenet_synset_to_human_label_map.txt文件内容如下:
imagenet_synset_to_human_label_map.txt
包含UID与类别的映射,这种类别文字标签记为human_string。
3. 准备工作
随便从网上下载一张图片,命名为husky.jpg:
husky.jpg
下面的代码就将使用Inception_v3模型对这张哈士奇图片进行分类。
4. 代码
先创建一个类NodeLookup来将softmax概率值映射到标签上;然后创建一个函数create_graph()来读取并新建模型;最后读取哈士奇图片进行分类识别:
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
#import re
import os
model_dir='C:/Users/Dexter/Documents/ML_files/171003_Inception_v3/Inception_model'
image = 'C:/Users/Dexter/Documents/ML_files/171003_Inception_v3/Images/husky.jpg'
#将类别ID转换为人类易读的标签
class NodeLookup(object):
def __init__(self, label_lookup_path=None, uid_lookup_path=None):
if not label_lookup_path:
# 加载“label_lookup_path”文件
# 此文件将数据集中所含类别(1-1000)与一个叫做target_class_string的地址对应起来
# 其地址编码为“n********”星号代表数字
label_lookup_path = os.path.join(
model_dir, 'imagenet_2012_challenge_label_map_proto.pbtxt')
if not uid_lookup_path:
# 加载“uid_lookup_path”文件
# 此文件将数据集中所含类别具体名称与编码方式为“n********”的地址/UID一一对应起来
uid_lookup_path = os.path.join(
model_dir, 'imagenet_synset_to_human_label_map.txt')
self.node_lookup = self.load(label_lookup_path, uid_lookup_path)
def load(self, label_lookup_path, uid_lookup_path):
if not tf.gfile.Exists(uid_lookup_path):
# 预先检测地址是否存在
tf.logging.fatal('File does not exist %s', uid_lookup_path)
if not tf.gfile.Exists(label_lookup_path):
# 预先检测地址是否存在
tf.logging.fatal('File does not exist %s', label_lookup_path)
# Loads mapping from string UID to human-readable string
# 加载编号字符串n********,即UID与分类名称之间的映射关系(字典):uid_to_human
# 读取uid_lookup_path中所有的lines
# readlines(): Returns all lines from the file in a list.
# Leaves the '\n' at the end.
proto_as_ascii_lines = tf.gfile.GFile(uid_lookup_path).readlines()
# 创建空字典uid_to_human用以存储映射关系
uid_to_human = {}
# =============================================================================
# # 使用正则化方法处理文件:
# p = re.compile(r'[n\d]*[ \S,]*')
# for line in proto_as_ascii_lines:
# = p.findall(line)
# uid = parsed_items[0]
# human_string = parsed_items[2]
# uid_to_human[uid] = human_string