基于Inception v3进行迁移学习训练自己的数据集

一、 什么是InceptionV3

Google Inception Net在2014年的 ImageNet Large Scale Visual Recognition Competition (ILSVRC)中取得第一名,该网络以结构上的创新取胜,通过采用全局平均池化层取代全连接层,极大的降低了参数量,是非常实用的模型,一般称该网络模型为Inception V1。随后的Inception V2中,引入了Batch Normalization方法,加快了训练的收敛速度。在Inception V3模型中,通过将二维卷积层拆分成两个一维卷积层,不仅降低了参数数量,同时减轻了过拟合现象。(这个概括是我以前在一篇博客上看到的,我觉得概括的不错,如果像要深入了解该网络还需要取读原始论文)

二、 什么是迁移学习

训练一个神经网络一般有3种方法
1) 从头到尾自己写出一个完整的网络结构,然后用自己的数据集去训练,但实际应用中我们的训练集往往不够,并且我们的电脑配置也可能不够高。而往往一个比较复杂的神经网络需要调节的权重参数又很多。这就导致了我们训练的效果会不好,并且花费的时间会很长。
2) 所以我们可以去网上获取别人已经训练好,就是所有的权重参数都以及训练好并保存在文件中的神经网络。然后我们拿到这个网络,只需要用自己的训练集训练最后一层,其他的层不改变参数。这样我们就能很快的训练好一个分类效果比较好且能适用于自己的数据集的神经网络,这也就是迁移学习。迁移学习的原理也很简单,因为对于图像分类来说,中间的层一般都是用来做图片的特征提取,所以对于每个数据集并没有很大差别,所以我们只需要对最后一层的参数改动。
3) 第三种方法和第二种方法类似,也是迁移学习,就是不完全固定中间层的参数,而是用很小的学习率进行微调。这样的效果一般会更好,但是对时间消耗就更大一些,我这次采用的是第二种方法训练自己的数据集。

三、 实现步骤

(1) 首先,在github上下载自己的tensorflow-master,并解压。
基于Inception v3进行迁移学习训练自己的数据集_第1张图片
(2) 建立一个Tensorflow文件夹,里面要有下面文件夹
基于Inception v3进行迁移学习训练自己的数据集_第2张图片
第一个文件夹是inception-V3的模型,里面有一个压缩包
在这里插入图片描述
链接:http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz
第二个文件夹是也是自己创建的文件夹,里面的东西我在下一步会详细讲
基于Inception v3进行迁移学习训练自己的数据集_第3张图片
第三个文件夹就是第一步下载解压文件夹,这里有个地方特别注意。
基于Inception v3进行迁移学习训练自己的数据集_第4张图片
记住这个路径下,是否有40多KB的一个retrain的py文件。如果没有或者retrain.py的大小不是这么大的,另外去网上下一个放在这个路径下,其他文件不用管。
(3) retrain文件夹下的东西
第一个bottleneck文件夹你只需要创建,一开始里面是空的。这个在训练的时候电脑会往这里面存放文件,如果你了解迁移学习的机制,应该很容易知道这里面存放的东西是干什么的。
第二个data文件夹看下图
基于Inception v3进行迁移学习训练自己的数据集_第5张图片
在data文件夹下创建一个train文件夹,再train文件夹下创建你要分类的数据集,每个类别的图片都单独创建一个文件夹,如上图,10个类别
第三个images文件夹是放你要测试训练好的网络的测试图片
第四第五个output_graph.pb和output_labels_txt是训练好它自动生成的。
第六个retrain.bat是要自己写的一个脚本文件
用txt写好,然后改成bat运行即可,内容如下:
基于Inception v3进行迁移学习训练自己的数据集_第6张图片
自己改对应路径,写好之后双击运行即可开始训练。有GPU的电脑会自动优先用GPU训练,没用GPU的也会用CPU正常运行
基于Inception v3进行迁移学习训练自己的数据集_第7张图片
训练好后,会创建一个tmp文件夹
在这里插入图片描述
如果要再次训练记得把这个文件夹删除掉。
(4) 运行好后就可以开始测试了,测试代码

import tensorflow as tf
import os
import numpy as np
import re
from PIL import Image
import matplotlib.pyplot as plt

lines=tf.gfile.GFile('D:/Tensorflow/retrain/output_labels.txt').readlines()
uid_to_human={}
for uid,line in enumerate(lines):
    line=line.strip("\n")
    uid_to_human[uid]=line
    
def id_to_string(node_id):
    if node_id not in uid_to_human:
        return ''
    return uid_to_human[node_id]

with tf.gfile.FastGFile('D:/Tensorflow/retrain/output_graph.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('final_result:0')
    for root,dirs,files in os.walk('D:/Tensorflow/retrain/images'):
        for file in files:
            image_data=tf.gfile.FastGFile(os.path.join(root,file),'rb').read()
            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()
            top_k=predictions.argsort()[::-1]
            print(top_k)
            for node_id in top_k:
                human_string=id_to_string(node_id)
                score=predictions[node_id]
                print("%s (score = %.5f)" % (human_string,score))
            print()

(5)运行结果
基于Inception v3进行迁移学习训练自己的数据集_第8张图片

四、 总结

用迁移学习的方法,确实能很快实现对自己的数据集进行训练,并且因为你用的是比较好的神经网络,效果往往也比较好。但是在用tensorflow迁移学习时,有很多坑,由于版本的升级和不兼容导致了我踩了不少坑,所以本文中提到需要注意的地方,大家一定要小心谨慎,不然除非你对tensorflow的流程图非常了解,不然很容易出错。

你可能感兴趣的:(深度学习)