ubuntu16.04 使用tensorflow object detection训练自己的模型

Posted SomnusMistletoe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ubuntu16.04 使用tensorflow object detection训练自己的模型相关的知识,希望对你有一定的参考价值。

一、构建自己的数据集

1、格式必须为jpg、jpeg或png。

2、在models/research/object_detection文件夹下创建images文件夹,在images文件夹下创建train和val两个文件夹,分别存放训练集图片和测试集图片。

3、下载labelImg目标检测标注工具

(1)下载地址:https://github.com/tzutalin/labelImg

(2)由于LabelImg是用Python编写的,并使用Qt作为其图形界面。

因此,python2安装qt4:

sudo apt-get install pyqt4-dev-tools

python3安装qt5:

sudo apt-get install pyqt5-dev-tools

(3)安装lxml

sudo apt-get install python-lxml

(4)解压,进入LabelImg-master文件夹,使用make编译

cd labelImg-master
make all

(5)打开LabelImg

python labelImg.py

(6)使用LabelImg

  • 使用Ctrl + u分别加载models/research/object_detection/images中train和val两个文件夹里的图像。
  • 使用Ctrl + r选择xml文件保存的地址,对应地选择保存在train和val文件夹即可。
  • 使用w创建一个矩形框,标注完一张图片中的所有物体后,Ctrl + s保存即可生成该图片对应的xml文件。

4、创建xml_to_csv.py并运行

分别将train和val文件夹下的xml文件生成对应的csv文件,并将csv文件拷贝到models/research/object_detection/data中。

xml_to_csv.py如下,以train为例。

import os
import glob
import pandas as pd
import xml.etree.ElementTree as ET
pathStr = r\'/home/somnus/boat/train\'
os.chdir(pathStr)
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\').find(\'width\').text),
                     int(root.find(\'size\').find(\'height\').text),
                     member.find(\'name\').text,
                     int(member.find(\'bndbox\').find(\'xmin\').text),
                     int(member.find(\'bndbox\').find(\'ymin\').text),
                     int(member.find(\'bndbox\').find(\'xmax\').text),
                     int(member.find(\'bndbox\').find(\'ymax\').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 = os.path.join(os.getcwd(), \'annotations\')
    image_path = pathStr
    xml_df = xml_to_csv(image_path)
    xml_df.to_csv(\'boat_train.csv\', index=None)
    print(\'Successfully converted xml to csv.\')
main()

5、创建generate_tfrecord.py并运行,以train为例,从而生成对应的TFrecord数据文件。

"""
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

#########根据需要修改路径
os.chdir(\'/home/somnus/models/research/object_detection\')

flags = tf.app.flags
flags.DEFINE_string(\'csv_input\', \'\', \'Path to the CSV input\')
flags.DEFINE_string(\'output_path\', \'\', \'Path to output TFRecord\')
flags.DEFINE_string(\'image_dir\', \'\', \'Path to images\')
FLAGS = flags.FLAGS


####根据需要修改标签
def class_text_to_int(row_label):
    if row_label == \'car\':
        return 1
    else:
        None


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(\'images/train\')

    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()

运行generate_tfrecord.py

python generate_tfrecord.py --csv_input=data/car_train.csv  --output_path=data/car_train.record
python generate_tfrecord.py --csv_input=data/car_val.csv  --output_path=data/car_val.record

二、准备配置文件

1、在models/research/object_detection/data文件夹下创建mymodel_label_map.pbtxt文件,可以模仿pet_label_map.pbtxt,内容修改为自己模型识别的标签,从1开始编号。

item {
  id: 1
  name: \'car\'
}

2、在object_detection下创建training文件夹,在models/research/object_detection/samples/configs中找到需要的模型文件,并拷贝到training文件夹下,以ssd_mobilenet_v1_coco.config为例。

model {
  ssd {

  #根据需要修改训练的数据类数
    num_classes: 1

    box_coder {
      faster_rcnn_box_coder {
        y_scale: 10.0
        x_scale: 10.0
        height_scale: 5.0
        width_scale: 5.0
      }
    }
    matcher {
      argmax_matcher {
        matched_threshold: 0.5
        unmatched_threshold: 0.5
        ignore_thresholds: false
        negatives_lower_than_unmatched: true
        force_match_for_each_row: true
      }
    }
    similarity_calculator {
      iou_similarity {
      }
    }
    anchor_generator {
      ssd_anchor_generator {
        num_layers: 6
        min_scale: 0.2
        max_scale: 0.95
        aspect_ratios: 1.0
        aspect_ratios: 2.0
        aspect_ratios: 0.5
        aspect_ratios: 3.0
        aspect_ratios: 0.3333
      }
    }
    image_resizer {
      fixed_shape_resizer {
        height: 300
        width: 300
      }
    }
    box_predictor {
      convolutional_box_predictor {
        min_depth: 0
        max_depth: 0
        num_layers_before_predictor: 0
        use_dropout: false
        dropout_keep_probability: 0.8
        kernel_size: 1
        box_code_size: 4
        apply_sigmoid_to_scores: false
        conv_hyperparams {
          activation: RELU_6,
          regularizer {
            l2_regularizer {
              weight: 0.00004
            }
          }
          initializer {
            truncated_normal_initializer {
              stddev: 0.03
              mean: 0.0
            }
          }
          batch_norm {
            train: true,
            scale: true,
            center: true,
            decay: 0.9997,
            epsilon: 0.001,
          }
        }
      }
    }
    feature_extractor {
      type: \'ssd_mobilenet_v1\'
      min_depth: 16
      depth_multiplier: 1.0
      conv_hyperparams {
        activation: RELU_6,
        regularizer {
          l2_regularizer {
            weight: 0.00004
          }
        }
        initializer {
          truncated_normal_initializer {
            stddev: 0.03
            mean: 0.0
          }
        }
        batch_norm {
          train: true,
          scale: true,
          center: true,
          decay: 0.9997,
          epsilon: 0.001,
        }
      }
    }
    loss {
      classification_loss {
        weighted_sigmoid {
        }
      }
      localization_loss {
        weighted_smooth_l1 {
        }
      }
      hard_example_miner {
        num_hard_examples: 3000
        iou_threshold: 0.99
        loss_type: CLASSIFICATION
        max_negatives_per_positive: 3
        min_negatives_per_image: 0
      }
      classification_weight: 1.0
      localization_weight: 1.0
    }
    normalize_loss_by_num_matches: true
    post_processing {
      batch_non_max_suppression {
        score_threshold: 1e-8
        iou_threshold: 0.6
        max_detections_per_class: 100
        max_total_detections: 100
      }
      score_converter: SIGMOID
    }
  }
}

train_config: {

 #根据需要修改训练批次
  batch_size: 24


  optimizer {
    rms_prop_optimizer: {
      learning_rate: {
        exponential_decay_learning_rate {
          initial_learning_rate: 0.004
          decay_steps: 800720
          decay_factor: 0.95
        }
      }
      momentum_optimizer_value: 0.9
      decay: 0.9
      epsilon: 1.0
    }
  }
  #这两行注释
  #fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED/model.ckpt"
  #from_detection_checkpoint: true

  # Note: The below line limits the training process to 200K steps, which we
  # empirically found to be sufficient enough to train the pets dataset. This
  # effectively bypasses the learning rate schedule (the learning rate will
  # never decay). Remove the below line to train indefinitely.
  num_steps: 200000
  data_augmentation_options {
    random_horizontal_flip {
    }
  }
  data_augmentation_options {
    ssd_random_crop {
    }
  }
}


train_input_reader: {
  tf_record_input_reader {

  #修改路径
  input_path: "data/car_train.record"

  }

 #修改路径
  label_map_path: "data/mymodel_label_map.pbtxt"

}

eval_config: {
  num_examples: 200
  # Note: The below line limits the evaluation process to 10 evaluations.
  # Remove the below line to evaluate indefinitely.
  max_evals: 10
}


eval_input_reader: {
   tf_record_input_reader {
   
   #修改路径
   input_path: "data/car_val.record"
  
}
  
  #修改路径
  label_map_path: "data/mymodel_label_map.pbtxt"
 
  shuffle: false
  num_readers: 1
}

3、在models/research/object_detection下运行

python ./legacy/train.py --logtostderr --train_dir=training/ --pipeline_config_path=training/ssd_mobilenet_v1_coco.config

三、生成可被调用的模型

python export_inference_graph.py --input_type image_tensor --pipeline_config_path training/ssd_mobilenet_v1_coco.config --trained_checkpoint_prefix training/model.ckpt-8004 --output_directory car_inference_graph 

  其中,model.ckpt-后面的数字可以看training文件夹下的文件,选个最大的数字;--output_directory=指定的是模型生成的文件夹名字,可根据需要修改。

参考

https://www.cnblogs.com/raorao1994/p/8854941.html

https://www.smwenku.com/a/5b898fc42b71775d1ce27004/zh-cn/

 

以上是关于ubuntu16.04 使用tensorflow object detection训练自己的模型的主要内容,如果未能解决你的问题,请参考以下文章

Ubuntu16.04 安装Tensorflow-CPU

Ubuntu 16.04 上 TensorFlow 的 NVIDIA cuDNN 版本类型 [关闭]

ubuntu tensorflow install(Ubuntu16.04+CUDA9.0+cuDNN7.5+Python3.6+TensorFlow1.5)

markdown Ubuntu16.04 + 1080下配置Tensorflow

Ubuntu 16.04安装配置TensorFlow GPU版本

ubuntu16.04下安装TensorFlow(GPU加速)----详细图文教程