使用TensorFlow训练模型

框架准备:

  1.  下载TensorFlow框架代码,以ssd-TensorFlow为例

    https://github.com/balancap/SSD-Tensorflow

    实现基于VGG的SSD网络(具有300和512输入)

  2. 根据需求下载数据集:Pascal VOC数据集(2007和2012)或者使用自己的数据集(数据集制作)

  3. 下载基础模型

    需fq下载:https://drive.google.com/open?id=0B0qPCUZ-3YwWZlJaRTRRQWRFYXM

  4.  安装jupyter(根据需求,不安装可以在IDE中修改代码并直接执行)

 

数据集制作:

  1.  下载标记工具,这里推荐labelimg标注工具(画方块标记)

    https://pan.baidu.com/s/1ZVRpMIbkN2HryCtwfOvdMw 提取码:6666

  2.  对自己的数据集做标注(得到xml文件,其中有标注框的坐标、名称等等信息)

    创建文件路径:

      VOC2007      --主文件夹

        -Annotations   --放置xml生成文件的文件夹

        -JPEGImages    --放置数据集图像的文件夹

        -ImageSets    

          --Main    --放置自动划分train / val / test 的txt文件

  3.  使用make_main_txt.py 生成划分训练集,验证集,测试集的txt文件,生成后的文件放在Main中

  4.  使用框架中tf_convert_data.py将数据集转为TensorFlow方便使用的tf-tfrecord类型的文件

    创建tfrecord生成后放置的文件夹

      tfrecord

 

训练模型

  一、 修改 train_ssd_network.py 代码

    1. 进入SSD-Tensorflow-master—>datasets—>pascalvoc_common.py 更改代码,根据自己情况更改,有几类就改成几类。

      

    VOC_LABELS = { 
        'none': (0, 'Background'), 
        'aeroplane': (1, 'Vehicle'), 
        'bicycle': (2, 'Vehicle'), 
        'bird': (3, 'Animal'), 
     ...
    }

    2. SSD-Tensorflow-master—>datasets—>pascalvoc_to_tfrecords.py   

      a. 然后更改文件的83行读取方式为’rb’:image_data = tf.gfile.FastGFile(filename, 'rb').read()

      b. SAMPLES_PER_FILES = 200, 根据需求修改,可以不改。意思是200张图片转换为一个tfrecord文件.

    3. train_ssd_network.py

      a. 修改最大训练步数参数max_number_of_steps,将None改为比如50000。

      b. num_classes 参数根据自己的类别数更改,数字为类别数加1。

    4. nets/ssd_vgg_300.py

      num_classes, no_annotation_label, 更改为你的类别数加1

    5. datasets/pascalvoc_2007.py

      NUM_CLASSES = 1

    6. eval_ssd_network.py 把um_classes改成你的类别数加1.

      会出现shape不匹配等问题

 

  二、 使用train_ssd_network.py 来训练模型,注意调整参数

    两种情况训练,第一种情况,不加载模型,直接全部训练。第二种情况,加载预训练模型,训练部分参数。

    第一种: 不加载模型,直接全部训练

    python3 train_ssd_network.py \
        --train_dir=/media/comway/data/dial_SSD/SSD-Tensorflow-master/train_log/ \
        --dataset_dir=/media/comway/data/dial_SSD/SSD-Tensorflow-master/dialvoc-train-tfrecords \
        --dataset_name=pascalvoc_2007 \
        --dataset_split_name=train \
        --model_name=ssd_300_vgg \
        --save_summaries_secs=60 \
        --save_interval_secs=600 \
        --weight_decay=0.0005 \
        --optimizer=adam \
        --learning_rate=0.001 \
        --learning_rate_decay_factor=0.94 \
        --batch_size=16 

    第二种: 加载预训练模型,训练部分参数。从vgg开始训练其中某些层的参数。其实就是加了--checkpoint_exclude_scopes,与--trainable_scopes。

python3 train_ssd_network.py \
    --train_dir=/media/comway/data/dial_SSD/SSD-Tensorflow-master/train_log/ \   #训练生成模型的存放路径
    --dataset_dir=/media/comway/data/dial_SSD/SSD-Tensorflow-master/dialvoc-train-tfrecords \  #数据存放路径
    --dataset_name=pascalvoc_2007 \  #数据名的前缀,我觉得应该通过这个调用是2007还是2012
    --dataset_split_name=train \  #是加载训练集还是测试集
    --model_name=ssd_300_vgg \  #加载的模型的名字
    --checkpoint_path=/media/comway/data/dial_SSD/SSD-Tensorflow-master/checkpoints/ssd_300_vgg.ckpt \  #所加载模型的路径
 --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=16 \   
    --gpu_memory_fraction=0.9  #指定占用gpu内存的百分比

    1.  指定数据集位置 dataset_dir 也就是 tfrecord文件的位置

    2. 指定checkpoint_path    基础模型的位置,框架中的checkpoints文件夹

    3. 指定生成模型的放置位置,自己创建文件夹,此处以model为例

    4. 根据电脑配置调整batch-size、learning_rate等参数

 

问题:

  执行train_ssd_network.py时遇到的错误

  1. 使用CPU执行代码时:

修改代码中的 DATA_FORMAT = 'NCHW'

 

  2.  提示找不到某个‘标注名’ 

在框架中datasets文件夹中pascalvoc_common.py里找到VOC_LABELS={ 。。。}, 将除去‘none’外所有不属于自己的标签都可以删掉,然后填入自己标注时的标签名称

 

  3. 报错:Nan in summary histogram for: ssd_300_vgg/block11/conv1x1/biases_1

    1. 修改batch-size,将数值改小 (每次处理的图像数量)
    2. 修改learning_rate,将数值改小,可改为0.0001(学习速率)
        同时修改end_learning_rate,可改为0.00001

   4. 报错: 报错:Dataset directory: ./voc2007/ Output directory: ./tfrecords >> Converting image 1/9963Traceback (most recent call last): File "./tf_convert_data.py", line 59, in tf.app.run() UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

修改:将datasets/pascalvoc_to_tfrecords.py文件83行中的读取方式由

    image_data = tf.gfile.FastGFile(filename, 'r').read()
  改为image_data = tf.gfile.FastGFile(filename, 'rb').read()

  

  5. 报错: INFO:tensorflow:Error reported to Coordinator: <class 'tensorflow.python.framework.errors_impl.InvalidArgumentError'>, All bounding box coordinates must be in [0.0, 1.0]: 1.002 。。。

一般是在转tfrecord文件时,tf_convert_data.py,产生错误(数据集中的数据标记不规范,出现了bbox四个坐标值落到到图像外的情况。)

解决问题方法1
错误位置:datasets
/pascalvoc_to_tfrecords.py bboxes.append((float(bbox.find('ymin').text) / shape[0], float(bbox.find('xmin').text) / shape[1], float(bbox.find('ymax').text) / shape[0], float(bbox.find('xmax').text) / shape[1] )) 修改为: ymin = max(float(bbox.find('ymin').text) / shape[0], 0.0)
xmin = max(float(bbox.find('xmin').text) / shape[1], 0.0)
ymax = min(float(bbox.find('ymax').text) / shape[0], 1.0)
xmax = min(float(bbox.find('xmax').text) / shape[1], 1.0)
bboxes.append(ymin, xmin, ymax, xmax
)

解决问题方法2:
如果修改后还会有此类报错,也可能是图像扩展时,某个框跑到了旋转后的页面之外。
可以尝试在修改方法1中的bboxes.append(ymin, xmin, ymax, xmax)之前增加一行代码:
...
if max(ymin, xmin, ymax, xmax) > 1.0:
return False

bboxes.append(ymin, xmin, ymax, xmax)
当筛选后的两个顶角坐标仍有超过图像尺寸的,直接跳过
 

 

注意:

  数据集图像不能太小,目前vgg模型中支持的标准图像大小是:224*224,300*300, 512*512图像太小也会报错

 

 

 
 
 
 
 
 
posted @ 2020-11-27 11:13  黑无常  阅读(945)  评论(0)    收藏  举报