美文网首页
Tersorflow目标检测入门的5个Demo

Tersorflow目标检测入门的5个Demo

作者: 随行的羊 | 来源:发表于2018-12-21 13:48 被阅读279次

    Demo One

    Tensorflow版本为1.12.0,Python3版本为3.6.3,Protoc版本为3.6.1

    第一步,下载models,网址为:

    git clone https://github.com/tensorflow/models.git
    

    第二步,进入research目录,运行命令:

    protoc object_detection/protos/*.proto --python_out=.
    

    第三步,进入object_detection目录,运行命令:

    jupyter notebook
    

    就会在浏览器上启动一个服务器,在服务器呈现的目录中找到object_detection_tutorial.ipynb,进入编辑页面,点击运行所有:

    object_detection_tutorial 运行所有

    然后服务器就开始运行,它会到服务器上下载一个frozen_inference_graph.pb文件,大小29.1M。下载完之后,再点击一下运行所有:

    检测成功

    如果没有出现问题的话,就会检测成功。如果出现网络错误,可以点击“服务”,选择“重启并运行所有”就可以了。

    第一个demo相对来说比较简单。


    Demo Two

    第一步,下载标注工具,下载地址:

    https://github.com/tzutalin/labelImg/releases
    

    第二步,进入到labelImg-1.8.0目录,运行命令:

    python3 labelImg.py
    

    这个时候就会启动标注工具,界面是这样的:

    labelImg

    在运行这个命令的时候,你可能会碰到很多问题,一般都是命令没有找到,只要安装相应的命令就可以了,我相信聪明的你一定会解决这些问题的。

    第三步,准备两个文件夹,一个是test,一个是train,train里面有100张你要标注的jpg图片,比如你可以拿100张你自己的头像。然后使用labelImg标注,一张张标注会生成一个个XML文件。然后再搞另外10张图出来,标注一下,放到test目录下。标注的类别我们记为yourface,很重要,请记住这个类别。

    第四步,需要把xml转成csv文件,使用的python代码为:

    # xml2csv.py
    
    import os
    import glob
    import pandas as pd
    import xml.etree.ElementTree as ET
    
    os.chdir('/Users/yangyh/Desktop/coreimage/train')   #1
    path = '/Users/yangyh/Desktop/coreimage/train'   #2
    
    def xml_to_csv(path):
        xml_list = []
       for xml_file in glob.glob(path + '/*.xml'):
            tree = ET.parse(xml_file)
            root = tree.getroot()
            for member in root.findall('object'):
                value = (root.find('filename').text,
                         int(root.find('size')[0].text),
                         int(root.find('size')[1].text),
                         member[0].text,
                         int(member[4][0].text),
                         int(member[4][1].text),
                         int(member[4][2].text),
                         int(member[4][3].text)
                         )
               xml_list.append(value)
        column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
        xml_df = pd.DataFrame(xml_list, columns=column_name)
        return xml_df
    
    
    def main():
        image_path = path
        xml_df = xml_to_csv(image_path)
        xml_df.to_csv('yangyh_plate1_train.csv', index=None)   #3
        print('Successfully converted xml to csv.')
    
    
    main()
    

    注意将上述代码的#1、#2、#3更改一下。然后运行命令:

    python3 xml2csv.py
    

    同样的,把目录和名称改为test,再运行一次。可以打开csv文件,看一下这两个文件里面的数据,数据结构还是挺有趣的。如果运行时发现格式错误,就要检查一下是不是在复制黏贴的时候,格式是否出问题了。

    第五步,进入第一个demo小练习的models文件夹中的research目录,运行命令:

    python3 setup.py install
    

    安装object_detection。

    第六步,进入第一个demo小练习的models文件夹中的object_detection目录:

    models/research/object_detection
    

    创建images文件夹,将刚才的train和test目录中的jpg图片全部放进这个文件夹中。

    第七步,还是在这个目录下,创建my_data目录,将刚才的test和train放进这个目录中,确保需要有csv文件。然后需要把csv文件转成record文件,用到的python代码为:

    """
        Usage:
        # From tensorflow/models/
        # Create train data:
        python generate_tfrecord.py --csv_input=data/train_labels.csv  --output_path=train.record
        # Create test data:
        python generate_tfrecord.py --csv_input=data/test_labels.csv  --output_path=test.record
        """
    from __future__ import division
    from __future__ import print_function
    from __future__ import absolute_import
    
    import os
    import io
    import pandas as pd
    import tensorflow as tf
    
    from PIL import Image
    from object_detection.utils import dataset_util
    from collections import namedtuple, OrderedDict
    
    flags = tf.app.flags
    flags.DEFINE_string('csv_input', '', 'Path to the CSV input')
    flags.DEFINE_string('output_path', '', 'Path to output TFRecord')
    FLAGS = flags.FLAGS
    
    
    # TO-DO replace this with label map
    def class_text_to_int(row_label):
        if row_label == 'yourface':    #1
            return 1
        else:
            return 0    #2
    
    
    def split(df, group):
        data = namedtuple('data', ['filename', 'object'])
        gb = df.groupby(group)
        return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]
    
    
    def create_tf_example(group, path):
        with tf.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:
            encoded_jpg = fid.read()
        encoded_jpg_io = io.BytesIO(encoded_jpg)
        image = Image.open(encoded_jpg_io)
        width, height = image.size
    
        filename = group.filename.encode('utf8')
        image_format = b'jpg'
        xmins = []
        xmaxs = []
        ymins = []
        ymaxs = []
        classes_text = []
        classes = []
    
        for index, row in group.object.iterrows():
            xmins.append(row['xmin'] / width)
            xmaxs.append(row['xmax'] / width)
            ymins.append(row['ymin'] / height)
            ymaxs.append(row['ymax'] / height)
            classes_text.append(row['class'].encode('utf8'))
            classes.append(class_text_to_int(row['class']))
    
        tf_example = tf.train.Example(features=tf.train.Features(feature={
                                                         'image/height': dataset_util.int64_feature(height),
                                                         'image/width': dataset_util.int64_feature(width),
                                                         'image/filename': dataset_util.bytes_feature(filename),
                                                         'image/source_id': dataset_util.bytes_feature(filename),
                                                         'image/encoded': dataset_util.bytes_feature(encoded_jpg),
                                                         'image/format': dataset_util.bytes_feature(image_format),
                                                         'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
                                                         'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
                                                         'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
                                                         'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
                                                         'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
                                                         'image/object/class/label': dataset_util.int64_list_feature(classes),
                                                         }))
        return tf_example
    
    def main(_):
        writer = tf.python_io.TFRecordWriter(FLAGS.output_path)
        path = os.path.join(os.getcwd(), 'images')    #3
        examples = pd.read_csv(FLAGS.csv_input)
        grouped = split(examples, 'filename')
        for group in grouped:
            tf_example = create_tf_example(group, path)
            writer.write(tf_example.SerializeToString())
    
        writer.close()
        output_path = os.path.join(os.getcwd(), FLAGS.output_path)
        print('Successfully created the TFRecords: {}'.format(output_path))
    
    if __name__ == '__main__':
        tf.app.run()
    

    如果你是从网上下载这个代码的,需要修改#2位置的代码。如果你想修改训练的jpg图片的目录地址,你可以修改#3。还记得之前类别不,#1要改为yourface。文件名取名为:generate_tfrecord.py。

    然后运行命令:

    python3 generate_tfrecord.py --csv_input=my_data/train/yangyh_plate1_train.csv --output_path=my_data/train/yangyh_plate1_train.record
    #忽略此注释
    

    获得train.record。同样的,继续运行命令:

    python3 generate_tfrecord.py --csv_input=my_data/test/yangyh_plate1_test.csv --output_path=my_data/test/yangyh_plate1_test.record
    #忽略此注释
    

    获得test.record。

    第八步,安装wget,不管你使用任何办法,只要能安装上wget命令就行了。然后下载一些文件,运行命令:

    wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_11_06_2017.tar.gz
    

    下载完成后,解压文件后,可以看到有不少文件。

    第九步,在object_detection目录下创建my_training文件夹,输入命令:

    vim object-detection.pbtxt
    

    打开vim编辑器,输入内容:

    item {
      id: 1
      name: 'yourface'    
    }
    

    注意你的类别名,有几个类别就填写几个item,保存退出。

    第十步,从目录中找到ssd_mobilenet_v1_pets.config文件,目录为:

    models/research/object_detection/samples/configs/ssd_mobilenet_v1_pets.config
    

    取出来,放在object_detection目录下,打开,修改内容:

    num_classes: 37 -> num_classes: 1
    fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED/model.ckpt" -> fine_tune_checkpoint: "ssd_mobilenet_v1_coco_11_06_2017/model.ckpt"
    train_input_reader/input_path: "PATH_TO_BE_CONFIGURED/pet_faces_train.record-?????-of-00010" -> train_input_reader/input_path: "my_data/train/yangyh_plate1_train.record"
    train_input_reader/label_map_path: "PATH_TO_BE_CONFIGURED/pet_label_map.pbtxt" -> train_input_reader/label_map_path: "my_training/object-detection.pbtxt"
    num_examples: 1100 -> num_examples: 10 #test有几张图就填几张,我这里准备了10张。
    eval_input_reader/input_path: "PATH_TO_BE_CONFIGURED/pet_faces_val.record-?????-of-00010" -> eval_input_reader/input_path: "my_data/test/yangyh_plate1_test.record"
    eval_input_reader/label_map_path: "PATH_TO_BE_CONFIGURED/pet_label_map.pbtxt" -> eval_input_reader/label_map_path: "my_training/object-detection.pbtxt"
    #忽略此注释
    

    改完之后,保存退出。(注意,这个文件一旦编辑好了num_classes,下次就无法修改了,训练之前一定要慎重设置这个参数,考虑拓展性。)

    第十一步,在object_detection目录下找到legacy目录,把里面的train.py拷贝一份到object_detection目录下,运行命令:

    python3 train.py --logtostderr --train_dir=my_training/ --pipeline_config_path=ssd_mobilenet_v1_pets.config
    

    执行命令的时候报错,提示:

    ImportError:No module named nets
    

    那我们需要安装一下slim,进入research/slim目录,运行:

    python3 setup.py install
    

    执行命令的时候报错,提示:

    error: could not create 'build': File exists
    

    然后在网址https://github.com/pachyderm/python-pachyderm/issues/20找到了解决问题的答案:

    Yeah, I did actually. This is because of a case-insensitive file system and the BUILD file. You have to rename the BUILD file and adjust the references to it in setup.py
    #忽略此注释
    

    我们进入slim目录,将BUILD文件命名为BUILD1,然后执行命令:

    python3 setup.py install
    

    这样就成功了,其实我之前也成功过,采用不安装命令的方式,直接迁移目录,有兴趣的童鞋也可以试试。
    然后,执行命令:

    python3 train.py --logtostderr --train_dir=my_training/ --pipeline_config_path=ssd_mobilenet_v1_pets.config
    

    就成功了,然后开始训练了,注意要把不相干的进程都关了,不然电脑卡死。
    如果看到以下内容就表示训练进行中,设置的steps是200000步,你也可以设置小一点,只要到时候测试集的数据可以通过就OK。但是要注意,训练期间不要开其他的IDE,可能会影响训练,导致训练中止,比如说训练期间打开多个Android Studio,最好不要。


    恭喜,成功了!

    Demo Three

    接着上一个练习,可以看到my_training文件夹中有很多文件:

    my_training

    我们需要把my_training中的模型文件转成pb文件。

    第一步,进入到object_detection目录下,运行命令:

    python3 export_inference_graph.py --input_type image_tensor --pipeline_config_path ssd_mobilenet_v1_pets.config --trained_checkpoint_prefix my_training/model.ckpt-4495 --output_directory mac_n_cheese_inference_graph/
    #忽略此注释
    

    注意参数my_training/model.ckpt-4495,运行成功后,会出现mac_n_cheese_inference_graph目录:


    mac_n_cheese_inference_graph

    其中,frozen_inference_graph.pb是我们需要的文件。

    第二步,在object_detection目录下的test_images目录中加入几张之前没参与训练的图片,命名为image1~image7。

    第三步,然后和第一个Demo一样,在object_detection目录下运行:

    jupyter notebook
     (千万注意运行这个进行目标检测的时候,不要再进行GPU模型训练,否则GPU模型训练会报错。)
    

    进入这个文件时,修改几个参数,我们不需要再从服务端下载model了,所以需要修改文件。

    MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17' -> MODEL_NAME = 'mac_n_cheese_inference_graph'
    MODEL_FILE删除
    DOWNLOAD_BASE删除
    PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt') -> PATH_TO_LABELS = os.path.join('my_training', 'object-detection.pbtxt')
    把Download Model整块代码删除
    for i in range(1, 3) -> for i in range(1, 8)
    #忽略此注释
    

    第四步,改完之后,点击cell、run all,即可得到结果。


    Demo Four

    经过了前三个小练习,相信你已经跟我一样开始训练了。

    但是我遇到了新的问题,我的电脑是iMac i5 3.4G HZ CPU,训练速度很慢,我算了一下,20万步大概要训练20多天,就是说训练100张图,训练完我头发都白了,肯定不成。那就试试GPU版本的吧!

    这次请原谅我不厚道地换了个设备,使用Windows系统,系统参数如下:

    Windows 10
    CPU:i7-4770 3.40G HZ
    内存:16G
    GPU:NVIDIA GeForce GTX 750 Ti
    

    从参数可以看出这个电脑的CPU虽然是i7,但是HZ数和iMac的HZ数是一样的,结果当我在Windows电脑上跑Tensorflow-CPU时,训练速度居然比在iMac上的慢,不得不感叹苹果硬件的牛逼。

    但我现在决定使用GPU了。

    《Win10 +VS2017+ python3.67 + CUDA10 + cuDNNv7.3.1 + tensorflow-gpu 1.12.0 最新版》这篇教程给了我很大的帮助。

    第一步,安装一下Python3.6.7。

    第二步,安装CUDA,按照教程来没什么问题,其中可以通过这个:查询GPU是否支持CUDA。我把安装路径改在了D盘,但是下载下来还是变成了C盘,不管它了,C盘就C盘。使用命令可以nvcc -V可以验证是否正确安装了CUDA。(有一个深坑一定要注意,就是安装的时候,按照默认的就好,选择精简模式,而不要手贱选自定义模式,否则出问题后果自负。)

    第三步,下载cuDNN,按照教程来基本没什么问题,有一点需要注意,教程的路径是:

    C:\ProgramData\NVIDIA GPU Computing Toolkit\v10
    

    而你自己的路径可能是:

    C:\ProgramData\NVIDIA GPU Computing Toolkit\v10.0
    

    v10后面多了个.0,这个坑很深。我的Path就是因为写错了,导致运行时,一直报错:

    ImportError: DLL load failed: The specified module could not be found.
    

    第四步,安装Tensorflow-GPU,按照教程来应该没什么问题。他说安装tensorboard需要翻墙,我这边不用翻墙。我运行了一下pip list,发现和文中不太一样:

    six                 1.11.0
    slim                0.1
    tensorboard         1.12.0
    tensorflow-gpu      1.12.0
    termcolor           1.1.0
    Werkzeug            0.14.1
    wheel               0.32.3
    

    并没有tensorpack、terminado、testpath、threadpool。

    第五步,运行:

    import tensorflow as tf
    

    应该没什么问题了。

    第六步,将之前的命令跑一遍:

    python train.py --logtostderr --train_dir=my_training/ --pipeline_config_path=ssd_mobilenet_v1_pets.config
    

    注意是python而不是python3,因为在windows上只有python命令,虽然我使用的是Python3。
    发现出问题了,报错信息:

    Allocator (GPU_0_bfc) ran out of memory trying to allocate
    

    查阅相关资料都说是batch_size设置太大了,大了就变小一点咯。
    进入ssd_mobilenet_v1_pets.config这个配置文件,将batch_size:24改成batch_size:8,再重新运行,就没问题了!

    效果呢,20万步只需要3天左右的时间!Amazing!Unbelievable!


    Demo Five

    接下来我们尝试采用多个分类,多个分类和单个分类的差别不是很大,主要的操作步骤还都是在《Tersorflow目标检测的第二个Demo小练习》这个当中。开始吧!

    《Tersorflow目标检测的第二个Demo小练习》的第七步中generate_tfrecord.py文件需要修改一下代码,class_text_to_int已经变成了很多分类了:

    if row_label == 'yourface':
        return 1
    elif row_label == 'yourleg':
        return 2
    else:
        return 0
    

    然后修改object-detection.pbtxt文件,里面的item已经变成很多类别了:

    item {
      id: 1
      name: 'yourface'    
    }
    item {
      id: 2
      name: 'yourleg'    
    }
    

    最后一处就是ssd_mobilenet_v1_pets.config这个文件了,修改代码:

    num_classes: 37 -> num_classes: 2
    

    然后继续训练吧。


    总结:虽然完成了5个Demo,但离要完成的目标还很远,还有很多问题需要解决。

    -------------------------------我是分割线-------------------------------

    2018-12-21

    相关文章

      网友评论

          本文标题:Tersorflow目标检测入门的5个Demo

          本文链接:https://www.haomeiwen.com/subject/irpmkqtx.html