margaretmm / myblog

my tech blog
0 stars 1 forks source link

使用InceptionV3 做迁移学习 #19

Open margaretmm opened 6 years ago

margaretmm commented 6 years ago

最近由于一个测试需求, 需要从图像中获取信息,判断结果正确性, 考虑的方案有很多,比如用OpenCV做切图+扣图(太痛苦,而且受分辨率, 位置,缩放影响大), 通过OCR识别(开源工具对中文识别很差)等多种尝试,感觉都有各种局限性, 后来想到 机器学习-图像识别方法,于是找到InceptionV3网络...

由于图像识别是基于特征提取的, 和像素, 开发实现原理等因素关联不大,而且没有平台兼容性问题,非常适合端到端的测试方案! InceptionV3是一种基于监督学习的神经网络 ,基于它做迁移学习,可以做新的物体的分类和识别(神经网络相关基础概念此处不表)

基于InceptionV3 迁移学习的原理: 用原来网络模型A(保留了Inception V3的全部卷积层)进行特征提取, 生成训练数据集的特征文件 在原模型A最后的瓶颈层(全连接层) 中添加一个分类层(softmax) 以适应新的分类任务,经过训练后保存新的 模型A'; 使用新的模型对数据集做分类识别 整个训练流程如下:

1.下载InceptionV3 神经网络模型和标签文件(监督学习)

http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz (网上有多种模型,这个模型对我的环境有效),里面包括:

模型文件:classify_image_graph_def.pb

标签文件:imagenet_2012_challenge_label_map_proto.pbtxt(机器读的标签)

imagenet_synset_to_human_label_map.txt(人可读的标签)

2.定义好整个工程的目录结构

分别存储 数据集(训练集,测试集),原有模型+标签文件,新模型,以及中间生成的特征文件 transfer-learning/

      data/ train/ XX_imgs/ ...... 

      test/ YY_imgs/......

      tmp/ bottleneck/ ......

      model/ imagenet_comp_graph_label_strings.txt

                  tensorflow_inception_graph.pb

newModel/

      train.py

      classify.py

3. 使用原有模型classify_image_graph_def.pb 识别包含新物体的数据集,并生成相关的特征文件集合

通过读取原有模型Graph中(通过节点名)的 全连接层节点,在节点上执行 sess.run(bottleneck_tensor, {image_data_tensor: image_data})  得到每张带训练图片的tensor值/特征值,然后暂时cache到文件中(自己指定文件夹保存比如tmp/ bottleneck/,后续需要读取)

4. 定义新的softmax层

输入为图片特征值+预期标签, 带入激活函数tf.nn.softmax中,  定义损失函数(交叉熵),使计算结果和预期标签做一个交叉熵计算,Loss越小越好 with tf.name_scope('final_training_ops'):        weights = tf.Variable(tf.truncated_normal([BOTTLENECK_TENSOR_SIZE, n_classes], stddev=0.001))       biases = tf.Variable(tf.zeros([n_classes]))       logits = tf.matmul(bottleneck_input, weights) + biases       final_tensor = tf.nn.softmax(logits) 定义损失函数 cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=ground_truth_input) cross_entropy_mean = tf.reduce_mean(cross_entropy)

定义梯度下降 train_step = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(cross_entropy_mean)

5. 执行训练过程,保存模型为A'

6. 使用新模型A’,识别测试集的标签

softmax分类结果和预期标签 做比较,得到概率

7. 详细代码

网上很多代码没有保存模型的操作, 预测脚本也没有使用新模型...我的脚本都已经实现:):

训练新模型脚本:https://github.com/margaretmm/myblog/issues/17

预测脚本: https://github.com/margaretmm/myblog/issues/18