SSD(2)代码分析

目录

代码运行

代码分析

 

代码运行

同样分析tensorflow版的实现,代码地址:SSD-Tensorflow

1.预测

unzip ssd_300_vgg.ckpt.zip
jupyter notebook notebooks/ssd_notebook.ipynb

启动jupyter notebook后,我们运行里面的代码就可以进行预测了。

2.训练

准备数据

首先下载VOC数据,下载方式可以参考https://blog.csdn.net/stesha_chen/article/details/82965283

创建文件夹tfrecords,然后运行tf_convert_data.py,将VOC数据转成tfrecord方式存储,后面会细读这部分的代码。

python tf_convert_data.py \
    --dataset_name=pascalvoc \
    --dataset_dir=./VOCdevkit/VOC2007/ \
    --output_name=voc_2007_train \
    --output_dir=./tfrecords

基于pre-trained VGG

由于SSD网络的base network就是一个分类网络,所以就算是从头开始训练SSD,我们也会先用训练好的分类网络初始化SSD的前面层,这里以VGG为例。

先下载预先训练好的VGG权重文件,VGG下载地址

python train_ssd_network.py \
    --train_dir=./log \
    --dataset_dir=./tfrecords \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \
    --checkpoint_path=./checkpoints/vgg_16.ckpt \
    --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 \
    --save_interval_secs=600 \
    --weight_decay=0.0005 \
    --optimizer=adam \
    --learning_rate=0.001 \
    --learning_rate_decay_factor=0.94 \
    --batch_size=32

--train_dir表示训练权重,tensorboard等信息保存的地址

--dataset_dir表示转出来的tfrecords保存的地址

--dataset_name表示我们现在训练哪个数据集,因为不同的数据集,在解析方式上是有些微差别的

--dataset_split_name表示我们现在是用pascalvoc_2007数据集的train数据还是test数据

--model_name表示我们模型的名字,检测模型是SSD,输入是300x300,base network是VGG

--checkpoint_path就是VGG pre-trained weights存放的地址

--checkpoint_exclude_scopes表示这些参数不需要从checkpoint中恢复

--trainable_scopes表示训练的时候只更新这些参数的值

基于pre-trained SSD

在用jupyter运行的时候我们已经将预先训练好的SSD权重文件下载了,运行下面的命令就可以继续训练了

python train_ssd_network.py \
    --train_dir=./log/ \
    --dataset_dir=./tfrecords \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \
    --checkpoint_path=./checkpoints/ssd_300_vgg.ckpt \
    --save_summaries_secs=60 \
    --save_interval_secs=600 \
    --weight_decay=0.0005 \
    --optimizer=adam \
    --learning_rate=0.001 \
    --batch_size=32

3.评估

python eval_ssd_network.py \
    --eval_dir=./log/eval \
    --dataset_dir=./tfrecords \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=test \
    --model_name=ssd_300_vgg \
    --checkpoint_path=./checkpoints/ssd_300_vgg.ckpt \
    --wait_for_checkpoints=True \
    --batch_size=1 \
    --max_num_batches=500

 

代码分析

数据准备

在tf_convert_data.py中主要是调用了pascalvoc_to_tfrecords.run,第一个参数dataset_dir是./VOCdevkit/VOC2007,第二个参数output_dir是./tfrecords,第三个参数是voc_2007_train

    path = os.path.join(dataset_dir, DIRECTORY_ANNOTATIONS)
    filenames = sorted(os.listdir(path))

path是./VOCdevkit/VOC2007/Annotations,列出里面的所有文件就是filenames,每个文件是对图片进行标记的xml文件。

然后遍历所有文件,将200个文件放入一条tfrecord记录中。

        # 创建TFRecordWriter
        with tf.python_io.TFRecordWriter(tf_filename) as tfrecord_writer:
            j = 0
            # 循环200次放入同一条tfrecord中
            while i < len(filenames) and j < SAMPLES_PER_FILES:
                filename = filenames[i]
                img_name = filename[:-4]
                # 将数据写入tfrecord中
                _add_to_tfrecord(dataset_dir, img_name, tfrecord_writer)

在_add_to_tfrecord函数中先调用_process_image对数据进行解析,返回值如下:

image_data是通过tf.gfile.FastGFile(filename, 'r').read()读出来的图片buffer

    filename = directory + DIRECTORY_IMAGES + name + '.jpg'
    image_data = tf.gfile.FastGFile(filename, 'r').read()

shape是从xml中读出的size信息

    shape = [int(size.find('height').text),
             int(size.find('width').text),
             int(size.find('depth').text)]

bboxes是从xml中读出的每个物体的位置框,如果图片中两个物体那么bboxes的长度为2,里面放着两个bbox信息

        bbox = obj.find('bndbox')
        bboxes.append((float(bbox.find('ymin').text) / shape[0],
                       float(bbox.find('xmin').text) / shape[1],
                       float(bbox.find('ymax').text) / shape[0]
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值