Inception 网络训练识别自己的图片
一. 下载inception网络并查看他的结构
在我们的训练过程中我们需要进行我们初始网络的下载到我们的当前电脑才能使用,所以我们需要实现进行网络的下载过程,才能继续我们网络的训练过程。
1. 导入我们的包库
在我们python的第一步都是导入我们的数据包库,这是我们接下来操作的起点和操作的初始状态。
import tensorflow as tf
import os
import tarfile
import requests
2. 定义模型的下载地址和模型的存放地址
我们下面我已经将我们的模型下载地址给出了,我们还定义了我们的模型的存放地址,在我们当前的文件中新建一个inception_model文件夹来存放我们的模型,然后定义了我们文件的存储名字,和他的路径
#模型下载地址
inception_pretrain_model_url='http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz'
#模型存放地址
inception_pretrain_model_dir="inception_model"
if not os.path.exists(inception_pretrain_model_dir):
os.makedirs(inception_pretrain_model_dir)
#获取文件名以及文件路径
filename=inception_pretrain_model_url.split('/')[-1]
filepath=os.path.join(inception_pretrain_model_dir, filename)
3. 下载模型
我们下面线看看是否路径是存在的,存在就开始下载,使用了request的get方法,定义了一个文件就是我们上面定义的文件名字,然后写进我们的数据在这个文件里面,最后输出文件下载完成操作。
if not os.path.exists(filepath):
print("download:", filename)
r=requests.get(inception_pretrain_model_url, stream=True)
with open(filepath, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print("finish: ",filename)
4. 解压下载文件
这里就是解压我们的文件
#解压文件
tarfile.open(filepath, 'r:gz').extractall(inception_pretrain_model_dir)
5. 模型的存放
在这里我们定义了一个我们模型数据的log文件存放的地址,先定义了文件的存储文件夹,下面我定义了一个sess图来将我们的数据文件下进去,然后存起来,在用FileWriter方法下入了我们的结构。
#模型结构存放文件
log_dir='inception_log'
if not os.path.exists(log_dir):
os.makedirs(log_dir)
#classify_image_graph_def.pb为google训练好的模型,
inception_graph_def_file=os.path.join(inception_pretrain_model_dir, 'classify_image_graph_def.pb')
with tf.Session() as sess:
#创建一个图来保存google训练好的模型
with tf.gfile.FastGFile(inception_graph_def_file, 'rb') as f:
graph_def=tf.GraphDef()
graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def, name='')
#保存图的结构
writer=tf.summary.FileWriter(log_dir, sess.graph)
writer.close()
二、 下载inception文件全代码
import tensorflow as tf
import os
import tarfile
import requests
#模型下载地址
inception_pretrain_model_url='http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz'
#模型存放地址
inception_pretrain_model_dir="inception_model"
if not os.path.exists(inception_pretrain_model_dir):
os.makedirs(inception_pretrain_model_dir)
#获取文件名以及文件路径
filename=inception_pretrain_model_url.split('/')[-1]
filepath=os.path.join(inception_pretrain_model_dir, filename)
#下载模型
if not os.path.exists(filepath):
print("download:", filename)
r=requests.get(inception_pretrain_model_url, stream=True)
with open(filepath, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print("finish: ",filename)
#解压文件
tarfile.open(filepath, 'r:gz').extractall(inception_pretrain_model_dir)
#模型结构存放文件
log_dir='inception_log'
if not os.path.exists(log_dir):
os.makedirs(log_dir)
#classify_image_graph_def.pb为google训练好的模型,
inception_graph_def_file=os.path.join(inception_pretrain_model_dir, 'classify_image_graph_def.pb')
with tf.Session() as sess:
#创建一个图来保存google训练好的模型
with tf.gfile.FastGFile(inception_graph_def_file, 'rb') as f:
graph_def=tf.GraphDef()
graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def, name='')
#保存图的结构
writer=tf.summary.FileWriter(log_dir, sess.graph)
writer.close()
三、 定义包库
这里没什么介绍的,和开始的时候是一样的。
import tensorflow as tf
import os
import numpy as np
import re
from PIL import Image
import matplotlib.pyplot as plt
四. 预处理数据介绍
这里我们要介绍我们的数据,以便更好的能了解我们下面程序是在干什么。了解了怎么干我们才知道干什么。
1.imagenet_synset_to_human_label_map.txt 文件介绍
这里面包含了两列他们中间是用\t来进行分隔的,他的是一个是编号一个是他的介绍的标签
2. imagenet_synset_to_human_label_map.txt 文件介绍
我们这个文件中,我们要的东西是两个,一个是类别的编号,一个是他所对应的标签代码,我们要做的事将他的标签和介绍进行匹配,通过他们的标签代码进行连接,所以我们的预处理是将他们链接起来。
五. 图像预处理函数NodeLookup类函数
1.初始函数 --init–(self)
我们这里定义了我们的这两个通用文件的路径,和使用了我们的文件的下载函数load
def __init__(self):
label_look_path = 'inception_model/imagenet_2012_challenge_label_map_proto.pbtxt'
uid_lookup_path = 'inception_model/imagenet_synset_to_human_label_map.txt'
self.node_lookup = self.load(label_look_path,uid_lookup_path)
- 链接两个文件
我们传入了我们的两个文件,然后一行一行的读取我们的说明文件,我在上面讲过,这个文件的分隔方式是tab分隔,他每行都是用了enter 所以我们首先明确了我们要怎么分隔和消除不需要的标签的方式,我们在这里定义了一个我们的容器uid_to_human,这个是拿来存放我们的代码和我们说明的位置,我们在下面的使用中我们通过他的键来提取出我们的说明,所以他是一个我们过渡文件。下面我们进行处理,我们去除了他的回车和根据他的tab分隔来将两个数值读取出来存放在了我们的文件中
下面我们处理我们的另一个文件,也就是类型和类型编码,我们还是和上面的一样定义了我们的我呢见的存储容器,我们在这里还是一行行读取这是没有发生改变的,我们使用strip函数来去除了他的空格,我们使用:分隔我们的数组,我们取出他的后面那个也就是编号,然后我们下面使用同样的方法来取出他的标签代码,这样我们得到的一个映射关系,然后我们将他存储在我们事先准备好的容器中,这样我们得到了我们的另一个映射关系容器
def load(self,label_lookup_path,uid_lookup_path):
# 加载分类字符串m**********对应的分类名称的文件
proto_as_ascii_line = tf.gfile.GFile(uid_lookup_path).readlines()
uid_to_human = {}
# 一行一行的读取数据
for line in proto_as_ascii_line:
# 去掉换行符
line = line.strip('\n')
# 安装\t分隔
parsed_items = line.split('\t')
# 获取分类编号
uid = parsed_items[0]
# 获取分类名称
human_string = parsed_items[1]
# 保存编号自负床n**********与分类名称的映射关系
uid_to_human[uid] = human_string
# 加载分类字符串n*********对应分类编号1-1000的文件
proot_as_ascii = tf.gfile.GFile(label_lookup_path).readlines()
node_id_to_uid = {}
for line in proot_as_ascii:
if line.strip().startswith('target_class:'):
# 获取分类编号1-1000
target_class = int(line.strip().split(':')[1]) # 取出分类编号(1-1000某个数)
if line.strip().startswith('target_class_string:'):
# 获取分类字符串n*********
target_class_string = line.strip().split(':')[1].strip() # 取出编号字符串
# 保存分类编号1-1000与编号字符串n********映射关系
node_id_to_uid[target_class] = target_class_string[1:-1] # 构造分类编号和编号字符串的映射关系
# 建立分类编号1-1000对应的分类名称的映射关系
node_id_to_name = {}
for key, val in node_id_to_uid.items():
# 获取分类名称
name = uid_to_human[val]
# 建立分类编号1-1000到分类名称的映射
node_id_to_name[key] = name
return node_id_to_name
做到了上面的那两个步骤,我们得到了我们的两个容器文件,现在我们需要的是根据他的的映射关系来进行我们的匹配操作,这里我们将标签的值作为我们说明的键取出我们说明,这就完成了我们的预处理操作。
3. 链接两个文件
这里我们就用我上面使用的方法来构建我们的标签和说明的映射关系
# 建立分类编号1-1000对应的分类名称的映射关系
node_id_to_name = {}
for key, val in node_id_to_uid.items():
# 获取分类名称
name = uid_to_human[val]
# 建立分类编号1-1000到分类名称的映射
node_id_to_name[key] = name
return node_id_to_name
4.定义说明返回函数
这个就是返回他的说明,通过他的键。
# 传入分类编号1-1000返回分类名称
def id_to_string(self,node_id):
if node_id not in self.node_lookup:
return ''
return self.node_lookup[node_id]
5. 说明
上面的所有操作都是在一个类中,他们不是单独的函数,所以请在这里注意哈
六、导入我们的图
导入我们下载的inception图
with tf.gfile.FastGFile('./inception_model/classify_image_graph_def.pb','rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def, name='')
七、调用网络
我们接下来的操作是读取我们的文件,然后丢进网络,然后获取编号,然后调用函数提取说明
我们首先在上面我们读取我们文件里面的一张纸图像,我们调用图像解码层(inception),我们将我们的数据进行转换,我们输出我们的当前识别图像,然后读取他的准确率,输出类别并用他提取说明。
with tf.Session() as sess:
softmax_tensor = sess.graph.get_tensor_by_name('softmax:0')
# 遍历目录
for root,dirs,files in os.walk('images/'):
for file in files:
# 载入图像
image_data = tf.gfile.FastGFile(os.path.join(root,file),'rb').read()
# 图像的格式是jpg格式
predictions = sess.run(softmax_tensor,{'DecodeJpeg/contents:0': image_data})
predictions = np.squeeze(predictions) # 把结果转成一维的数据
# 打印图片路径及名称
image_path = os.path.join(root,file)
print(image_path)
# 显示图像
img = Image.open(image_path)
plt.imshow(img)
plt.axis('off')
plt.show()
# 提取出最大的概率的准确率
node_id = predictions.argsort()[-1] #从小到大排序后取出最大概率
node_lookup = NodeLookup()
human_string = node_lookup.id_to_string(node_id)#得到node_id对应的分类名称
# 获取该分类的置信度
score = predictions[node_id] #得到该分类的可能性
print('%s (score = %.5f)'%(human_string, score))
八、完整实现
import tensorflow as tf
import os
import numpy as np
import re
from PIL import Image
import matplotlib.pyplot as plt
# 定义图像预处理函数
class NodeLookup(object):
def __init__(self):
label_look_path = 'inception_model/imagenet_2012_challenge_label_map_proto.pbtxt'
uid_lookup_path = 'inception_model/imagenet_synset_to_human_label_map.txt'
self.node_lookup = self.load(label_look_path,uid_lookup_path)
def load(self,label_lookup_path,uid_lookup_path):
# 加载分类字符串m**********对应的分类名称的文件
proto_as_ascii_line = tf.gfile.GFile(uid_lookup_path).readlines()
uid_to_human = {}
# 一行一行的读取数据
for line in proto_as_ascii_line:
# 去掉换行符
line = line.strip('\n')
# 安装\t分隔
parsed_items = line.split('\t')
# 获取分类编号
uid = parsed_items[0]
# 获取分类名称
human_string = parsed_items[1]
# 保存编号自负床n**********与分类名称的映射关系
uid_to_human[uid] = human_string
# 加载分类字符串n*********对应分类编号1-1000的文件
proot_as_ascii = tf.gfile.GFile(label_lookup_path).readlines()
node_id_to_uid = {}
for line in proot_as_ascii:
if line.strip().startswith('target_class:'):
# 获取分类编号1-1000
target_class = int(line.strip().split(':')[1]) # 取出分类编号(1-1000某个数)
if line.strip().startswith('target_class_string:'):
# 获取分类字符串n*********
target_class_string = line.strip().split(':')[1].strip() # 取出编号字符串
# 保存分类编号1-1000与编号字符串n********映射关系
node_id_to_uid[target_class] = target_class_string[1:-1] # 构造分类编号和编号字符串的映射关系
# 建立分类编号1-1000对应的分类名称的映射关系
node_id_to_name = {}
for key, val in node_id_to_uid.items():
# 获取分类名称
name = uid_to_human[val]
# 建立分类编号1-1000到分类名称的映射
node_id_to_name[key] = name
return node_id_to_name
# 传入分类编号1-1000返回分类名称
def id_to_string(self,node_id):
if node_id not in self.node_lookup:
return ''
return self.node_lookup[node_id]
# 创建一个图来存放Google训练好的模型
with tf.gfile.FastGFile('./inception_model/classify_image_graph_def.pb','rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def, name='')
with tf.Session() as sess:
softmax_tensor = sess.graph.get_tensor_by_name('softmax:0')
# 遍历目录
for root,dirs,files in os.walk('images/'):
for file in files:
# 载入图像
image_data = tf.gfile.FastGFile(os.path.join(root,file),'rb').read()
# 图像的格式是jpg格式
predictions = sess.run(softmax_tensor,{'DecodeJpeg/contents:0': image_data})
predictions = np.squeeze(predictions) # 把结果转成一维的数据
# 打印图片路径及名称
image_path = os.path.join(root,file)
print(image_path)
# 显示图像
img = Image.open(image_path)
plt.imshow(img)
plt.axis('off')
plt.show()
# 提取出最大的概率的准确率
node_id = predictions.argsort()[-1] #从小到大排序后取出后5位,在倒置
node_lookup = NodeLookup()
# for node_id in top_k:
# # 获取分类名称
human_string = node_lookup.id_to_string(node_id)#得到node_id对应的分类名称
# 获取该分类的置信度
score = predictions[node_id] #得到该分类的可能性
print('%s (score = %.5f)'%(human_string, score))
九、说明
这是博主的一个学习笔记,有错误欢迎提出,或者留言评论,谢谢。