SSD-tensorflow 训练自己的数据

参考: http://blog.csdn.net/u014696921/article/details/53353896

             http://blog.csdn.net/ei1990/article/details/75282855

             http://studyai.com/article/3e454b9e

             http://blog.csdn.net/yexiaogu1104/article/details/77415990

             http://www.cnblogs.com/objectDetect/p/5780006.html

              http://blog.csdn.net/yexiaogu1104/article/details/77416020

              http://www.cnblogs.com/whlook/p/7220105.html

             http://blog.csdn.net/w5688414/article/details/78395177

1.  搭建SSD框架,下载解压即可


2. 下载pascalvoc数据,自己的数据根据voc格式改写

3. 图片数据重命名为6位数字

   python代码

import os  
      
class BatchRename():  
      #  ''''' 
     #   批量重命名文件夹中的图片文件 
     
       # '''  
        def __init__(self):  
            #我的图片文件夹路径horse  
            self.path = '/home/xxx/imagedata/image_xml'  
      
        def rename(self):  
            filelist = os.listdir(self.path)  
            total_num = len(filelist)  
            i = 1  
            n = 6  
            for item in filelist:  
                if item.endswith('.jpg'):  
                    n = 6 - len(str(i))  
                    src = os.path.join(os.path.abspath(self.path), item)  
                    dst = os.path.join(os.path.abspath(self.path), str(0)*n + str(i) + '.jpg')  
                    try:  
                        os.rename(src, dst)  
                        print 'converting %s to %s ...' % (src, dst)  
                        i = i + 1  
                  
                    except:  
                        continue  
            print 'total %d to rename & converted %d jpgs' % (total_num, i)  
      
if __name__ == '__main__':  
        demo = BatchRename()  
        demo.rename()  


3.标记数据

4.生成txt文件,train.txt, trainval.txt, test.txt, val.txt


python代码

import os  
import random   
  
xmlfilepath=r'/home/xxx/subimage_xml_xiao'  
saveBasePath=r"/home/xxx/txt"  
  
trainval_percent=0.7 
train_percent=0.7  
total_xml = os.listdir(xmlfilepath)  
num=len(total_xml)    
list=range(num)    
tv=int(num*trainval_percent)    
tr=int(tv*train_percent)    
trainval= random.sample(list,tv)    
train=random.sample(trainval,tr)    
  
print("train and val size",tv)  
print("traub suze",tr)  
ftrainval = open(os.path.join(saveBasePath,'Main/trainval.txt'), 'w')    
ftest = open(os.path.join(saveBasePath,'Main/test.txt'), 'w')    
ftrain = open(os.path.join(saveBasePath,'Main/train.txt'), 'w')    
fval = open(os.path.join(saveBasePath,'Main/val.txt'), 'w')    
  
for i  in list:    
    name=total_xml[i][:-4]+'\n'    
    if i in trainval:    
        ftrainval.write(name)    
        if i in train:    
            ftrain.write(name)    
        else:    
            fval.write(name)    
    else:    
        ftest.write(name)    
    
ftrainval.close()    
ftrain.close()    
fval.close()    
ftest .close() 

5.  将训练类别修改为和自己一样的

   SSD-Tensorflow-master—>datasets—>ascalvoc_common.py

  根据实际情况进行修改

VOC_LABELS = { 
    'none': (0, 'Background'), 
    'aeroplane': (1, 'Vehicle'), 
    'bicycle': (2, 'Vehicle'), 
    'bird': (3, 'Animal'), 
    'boat': (4, 'Vehicle'), 
    'bottle': (5, 'Indoor'), 
    'bus': (6, 'Vehicle'), 
    'car': (7, 'Vehicle'), 
    'cat': (8, 'Animal'), 
    'chair': (9, 'Indoor'), 
    'cow': (10, 'Animal'), 
    'diningtable': (11, 'Indoor'), 
    'dog': (12, 'Animal'), 
    'horse': (13, 'Animal'), 
    'motorbike': (14, 'Vehicle'), 
    'Person': (15, 'Person'), 
    'pottedplant': (16, 'Indoor'), 
    'sheep': (17, 'Animal'), 
    'sofa': (18, 'Indoor'), 
    'train': (19, 'Vehicle'), 
    'tvmonitor': (20, 'Indoor'), 
} 




6.  将图像数据转换为tfrecods格式

   SSD-Tensorflow-master—>datasets—>pascalvoc_to_tfrecords.py 。。。然后更改文件的83行读取方式为’rb’)


    在SSD-Tensorflow-master文件夹下创建tf_conver_data.sh

   

  1 #!/bin/bash
  2 #this is a shell script to convert pascal VOC datasets into tf-records only
  3 #directory where the original dataset is stored 
  4 
  5 DATASET_DIR=/home/xxx/imagedata/VOCdevkit/VOC2007/     #VOC数据保存的文件夹(VOC的目录格式未改变)
  6 
  7 #output directory where to store TFRecords files
  8 OUTPUT_DIR=/home/xxx/imagedata/xingshizheng_tf  #自己建立的保存tfrecords数据的文件夹
  9   
 10 python3 ./tf_convert_data.py \
 11        --dataset_name=pascalvoc \
 12        --dataset_dir=${DATASET_DIR} \
 13        --output_name=voc_2007_train \
 14        --output_dir=${OUTPUT_DIR}
~

7. 训练模型

train_ssd_network.py修改第154行的最大训练步数,将None改为比如50000。(tf.contrib.slim.learning.training函数中max-step为None时训练会无限进行。)

  

方案1: 从vgg开始训练其中某些层的参数

# 通过加载预训练好的vgg16模型,对“voc07trainval+voc2012”进行训练
# 通过checkpoint_exclude_scopes指定哪些层的参数不需要从vgg16模型里面加载进来
# 通过trainable_scopes指定哪些层的参数是需要训练的,未指定的参数保持不变
DATASET_DIR=/home/doctorimage/kindlehe/common/dataset/VOC0712/
TRAIN_DIR=.././log_files/log_finetune/train_voc0712_20170816_1654_VGG16/
CHECKPOINT_PATH=../checkpoints/vgg_16.ckpt

python3 ../train_ssd_network.py \
    --train_dir=${TRAIN_DIR} \      #训练生成模型的存放路径
    --dataset_dir=${DATASET_DIR} \  #数据存放路径
    --dataset_name=pascalvoc_2007 \ #数据名的前缀
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \      #加载的模型的名字
    --checkpoint_path=${CHECKPOINT_PATH} \  #所加载模型的路径
    --checkpoint_model_scope=vgg_16 \   #所加载模型里面的作用域名
    --checkpoint_exclude_scopes=ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box \
    --trainable_scopes=ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box \
    --save_summaries_secs=60 \  #每60s保存一下日志
    --save_interval_secs=600 \  #每600s保存一下模型
    --weight_decay=0.0005 \     #正则化的权值衰减的系数
    --optimizer=adam \          #选取的最优化函数
    --learning_rate=0.001 \     #学习率
    --learning_rate_decay_factor=0.94 \ #学习率的衰减因子
    --batch_size=24 \   
    --gpu_memory_fraction=0.9   #指定占用gpu内存的百分比

方案2: 从自己预训练好的模型开始训练(依然可以指定要训练哪些层)(当你的模型通过vgg训练的模型收敛到大概o.5mAP的时候,可以进行这一步的fine-tune)

# 通过加载预训练好的vgg16模型,对“voc07trainval+voc2012”进行训练
# 通过checkpoint_exclude_scopes指定哪些层的参数不需要从vgg16模型里面加载进来
# 通过trainable_scopes指定哪些层的参数是需要训练的,未指定的参数保持不变
DATASET_DIR=/home/doctorimage/kindlehe/common/dataset/VOC0712/
TRAIN_DIR=.././log_files/log_finetune/train_voc0712_20170816_1654_VGG16/
CHECKPOINT_PATH=./log_files/log_finetune/train_voc0712_20170712_1741_VGG16/model.ckpt-253287

python3 ../train_ssd_network.py \
    --train_dir=${TRAIN_DIR} \      #训练生成模型的存放路径
    --dataset_dir=${DATASET_DIR} \  #数据存放路径
    --dataset_name=pascalvoc_2007 \ #数据名的前缀
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \      #加载的模型的名字
    --checkpoint_path=${CHECKPOINT_PATH} \  #所加载模型的路径
    --checkpoint_model_scope=vgg_16 \   #所加载模型里面的作用域名
    --checkpoint_exclude_scopes=ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box \
    --trainable_scopes=ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box \
    --save_summaries_secs=60 \  #每60s保存一下日志
    --save_interval_secs=600 \  #每600s保存一下模型
    --weight_decay=0.0005 \     #正则化的权值衰减的系数
    --optimizer=adam \          #选取的最优化函数
    --learning_rate=0.001 \     #学习率
    --learning_rate_decay_factor=0.94 \ #学习率的衰减因子
    --batch_size=24 \   
    --gpu_memory_fraction=0.9   #指定占用gpu内存的百分比

# 方案3:从头开始训练自己的模型
# 注释掉CHECKPOINT_PATH,不提供初始化模型,让模型自己随机初始化权重,从头训练
# 删除checkpoint_exclude_scopes和trainable_scopes,因为是从头开始训练
# CHECKPOINT_PATH=./log_files/log_finetune/train_voc0712_20170712_1741_VGG16/model.ckpt-253287

python3 ../train_ssd_network.py \
    --train_dir=${TRAIN_DIR} \   #训练生成模型的存放路径
    --dataset_dir=${DATASET_DIR} \  #数据存放路径
    --dataset_name=pascalvoc_2007 \ #数据名的前缀
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \  #加载的模型的名字
    #--checkpoint_path=${CHECKPOINT_PATH} \ #所加载模型的路径,这里注释掉
    --checkpoint_model_scope=vgg_16 \   #所加载模型里面的作用域名
    --save_summaries_secs=60 \  #每60s保存一下日志
    --save_interval_secs=600 \  #每600s保存一下模型
    --weight_decay=0.0005 \     #正则化的权值衰减的系数
    --optimizer=adam \          #选取的最优化函数
    --learning_rate=0.00001 \   #学习率
    --learning_rate_decay_factor=0.94 \ #学习率的衰减因子
    --batch_size=32


     8. 测试或验证

    
      
在SSD-Tensorfloe-master 文件夹下建立一个sh文件

    #!/bin/bash
    # This is the eval script.
    DATASET_DIR=/home/xxx/voc2007_test_tfrecords/    #保存的转换为tfrcodes格式的数据
    EVAL_DIR=/home/xxx/ssd_eval_log/   # Directory where the results are saved to    
    CHECKPOINT_PATH=/home/xxx/Downloads/SSD-Tensorflow-master/checkpoints/VGG_VOC0712_SSD_300x300_iter_120000.ckpt   #换为自己训练的模型
 python3 ./eval_ssd_network.py \
        --eval_dir=${EVAL_DIR} \
        --dataset_dir=${DATASET_DIR} \
        --dataset_name=pascalvoc_2007 \
        --dataset_split_name=test \
        --model_name=ssd_300_vgg \
        --checkpoint_path=${CHECKPOINT_PATH} \
        --batch_size=1

9. 注意

  1. –dataset_name=pascalvoc_2007 、–dataset_split_name=train、–model_name=ssd_300_vgg这三个参数不要自己随便取,在代码里,这三个参数是if…else…语句,有固定的判断值,所以要根据实际情况取选择
  2. TypeError: expected bytes, NoneType found
    SystemError: returned a result with an error set
    这是由于CHECKPOINT_PATH定义的时候不小心多了个#号键,将输入给注释掉了,如果不想使用预训练的模型,需要将--checkpoint_path=${CHECKPOINT_PATH} \注释掉即可
  3. SSD有在VOC07+12的训练集上一起训练的,用一个笨一点的办法:
    pascalvoc_to_tfrecords.py文件中,改变SAMPLES_PER_FILES,减少输出tfrecord文件的个数,再修改tf_convert_data.py的dataset参数,记得将前后两次的输出名改变一下,前后两次转换的tfrecords放在同一个文件夹下,然后手工重命名。(这里由于只是验证论文的训练方法是否有效,所以没必要写这些自动化代码实现合并,以后要用自己的数据集训练的时候就可以写一些自动化脚本)
  4. 有时候运行脚本会报错,可能是之前依次运行导致显存占满。
  5. 从pyCharm运行时,如果模型保存路径里之前的模型未删除,将会报错,必须保证该文件夹为空。
  6. 在TRAIN_DIR路径下会产生四中文件: 1. checkpoint :文本文件,包含所有model.ckpt-xxxx,相当于是不同时间节点生成的所有ckpt文件的一个索引。 2. model.ckpt-2124.data-000000-of-000001:模型文件,保存模型的权重 3. model.ckpt-2124.meta: 图文件,保存模型的网络图 4. model.ckpt-2124.index : 这个没搞太清楚 5. graph.pbtxt: 用protobuf格式保存的模型的图
相关文章
相关标签/搜索