参考:https://blog.csdn.net/weixin_39881922/article/details/80569803
1 xml目标计算参考:https://blog.csdn.net/zjc910997316/article/details/100776527
2 生成tset.txt等文件:https://blog.csdn.net/zjc910997316/article/details/100776527
3 VGG16模型下载地址:链接:https://pan.baidu.com/s/1diWbdJdjVbB3AWN99406nA 密码:ge3x
1下载源码
1.代码地址:https://github.com/balancap/SSD-Tensorflow,下载该代码到本地
2.解压ssd_300_vgg.ckpt.zip 到checkpoint文件夹下
3. 测试一下看看,在notebooks中创建ssd_notebook.py,
格式这样:notebooks/ssd_notebook.py
其实就是用jupyter notebook打开ssd_notebook.ipynb,保存为ssd_notebook.py
该py文件是完成对于单张图片的测试,对Jupyter不熟,就自己改了,感觉这样要方便一些。
4. 19行是ipython格式(jupyter打开的)内容注释掉即可
5. python ssd_notebook.py运行即可
2设置自己的数据集
1.将自己的数据集做成VOC2007格式放在该工程下面
2. 修改datasets文件夹中pascalvoc_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'),
}
'''
#修改后的第一种思路:所有动物算一类
'''
VOC_LABELS = {
'none': (0, 'Background'),
'animal':(1,'Vehicle'),
}
'''
#修改后的第二种思路:14种动物
VOC_LABELS = {
'none': (0, 'Background'),
'antelope': (1, 'Animal'),
'blood_male': (2, 'Animal'),
'golden_monkey': (3, 'Animal'),
'gr-tailed_pheasant': (4, 'Animal'),
'panda': (5, 'Animal'),
'rock_sheep': (6, 'Animal'),
'sambar(female)': (7, 'Animal'),
'sambar(male)': (8, 'Animal'),
'small_muntjac': (9, 'Animal'),
'takin': (10, 'Animal'),
'tibetan_macaque': (11, 'Animal'),
'tufted_deer': (12, 'Animal'),
'wild_boar': (13, 'Animal'),
'yellow_marten': (14, 'Animal'),
}
存在疑问?这里的Animal Background是什么意思?是否在代码里面起作用了?
'none': (0, 'Background'),
'aeroplane': (1, 'Vehicle'),
'bicycle': (2, 'Vehicle'),
'bird': (3, 'Animal'),
3. 将图像数据转换为tfrecods格式,datasets/pascalvoc_to_tfrecords.py
修改datasets文件夹中的pascalvoc_to_tfrecords.py文件,
然后更改文件的83行读取方式为’rb‘,如果你的文件不是.jpg格式,也可以修改图片的类型。
此外, 修改67行,可以修改几张图片转为一个tfrecords 200张默认
4.运行tf_convert_data.py文件(通过脚本tf_convert_data.sh运行),但是需要传给它一些参数:
linux下:
在SSD-Tensorflow-master文件夹下创建脚本文件nk_tf_conver_data.sh,
自己建立的保存tfrecords数据的文件夹nk_tfrecords
文件写入内容如下:
DATASET_DIR=/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/VOC2007/
OUTPUT_DIR=/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/nk_tfrecords/
python /home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/tf_convert_data.py \
--dataset_name=pascalvoc \
--dataset_dir=${DATASET_DIR} \
--output_name=voc_2007_test \
--output_dir=${OUTPUT_DIR}
注意:这种红色反斜杠时出问题的(怀疑是4567前面的tab造成,需要从新写一遍就可以了,建议从新写一遍,建议使用绝对路径)
正确的这样:
但是还是报错:ValueError: You must supply the dataset directory with --dataset_dir
解决办法:
1我改用绝对路径,
2#!/bin/bash 也是建议添加的
3下面带有讲解#filename = tf_convert_data.sh #!/bin/bash #This is a shell script to convert Pascal VOC datasets(2007 and 2012) into TF-Records only. #Directory where the original dataset is stored # /home/hp/zjc/Tensorflow/Deeplearning/dataset/VOCtest_06-Nov-2007/VOCdevkit/VOC2007/ DATASET_DIR=/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/VOC2007/ #Output directory where to store TFRecords files # /home/hp/zjc/Tensorflow/Deeplearning/dataset/VOCtest_06-Nov-2007/VOCdevkit/VOC2007_tfrecord/ OUTPUT_DIR=/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/nk_tfrecords/ #/home/hp/zjc/Tensorflow/Deeplearning/SSD-Tensorflow-master/tf_convert_data.py python /home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/tf_convert_data.py \ --dataset_name=pascalvoc \ --dataset_dir=${DATASET_DIR} \ --output_name=voc_2007_test \ --output_dir=${OUTPUT_DIR}
5. 通过指令bash tf_convert_data.sh 运行
四川王朗DW制作的数据集14070张图片,14070个xml文件,200个转化为一个tfrecord
bash tf_convert_data.sh
之后得到71个tfrecord
6. 训练模型train_ssd_network.py文件中修改
修改154行最大训练步数,None可以改成50000 max-step为None时训练会无限进行
train_ssd_network.py 文件中网络参数配置,若需要改,在此文件中进行修改,如
3 其他需要修改的地方
a. nets/ssd_vgg_300.py (因为使用此网络结构) ,修改96和97行的类别、
=>nets/ssd_vgg_300.py 96
修改后
b. train_ssd_network.py,修改类别120行,GPU占用量,学习率,batch_size等
GPU占用量
=>train_ssd_network.py 66
学习率0,001-0.0001,衰减率
=>train_ssd_network.py 113 115
batch_size(我这里是21,图中32是默认的),
batch_size=21 为了能被14070整除 14070/21 = 670 一般epoch训练200轮次 200*670 =134000 需要训练134000轮
物种数量(我这里是15 = 14 + 1 因为14种动物加上背景),
=>train_ssd_network.py 151
c eval_ssd_network.py 修改类别,66行
=>eval_ssd_network.py 66
根据自己的数据修改为类别+1
d. datasets/pascalvoc_2007.py 根据自己的训练数据修改整个文件
=>datasets/pascalvoc_2007.py 89->109
'''原有代码
TRAIN_STATISTICS = {
'none': (0, 0),
'aeroplane': (238, 306),
'bicycle': (243, 353),
'bird': (330, 486),
'boat': (181, 290),
'bottle': (244, 505),
'bus': (186, 229),
'car': (713, 1250),
'cat': (337, 376),
'chair': (445, 798),
'cow': (141, 259),
'diningtable': (200, 215),
'dog': (421, 510),
'horse': (287, 362),
'motorbike': (245, 339),
'person': (2008, 4690),
'pottedplant': (245, 514),
'sheep': (96, 257),
'sofa': (229, 248),
'train': (261, 297),
'tvmonitor': (256, 324),
'total': (5011, 12608),
}
TEST_STATISTICS = {
'none': (0, 0),
'aeroplane': (1, 1),
'bicycle': (1, 1),
'bird': (1, 1),
'boat': (1, 1),
'bottle': (1, 1),
'bus': (1, 1),
'car': (1, 1),
'cat': (1, 1),
'chair': (1, 1),
'cow': (1, 1),
'diningtable': (1, 1),
'dog': (1, 1),
'horse': (1, 1),
'motorbike': (1, 1),
'person': (1, 1),
'pottedplant': (1, 1),
'sheep': (1, 1),
'sofa': (1, 1),
'train': (1, 1),
'tvmonitor': (1, 1),
'total': (20, 20),
}
SPLITS_TO_SIZES = {
'train': 5011,
'test': 4952,
}
SPLITS_TO_STATISTICS = {
'train': TRAIN_STATISTICS,
'test': TEST_STATISTICS,
}
NUM_CLASSES = 20
'''
替换为如下: 注意这里NUM_CLASSES=14,有多少类就是多少,无需+1(无需加背景类)
TRAIN_STATISTICS = {
'none': (0, 0),
'antelope': (500, 500), # (有这个动物的图片有多少张, 这个动物bbox一共多少个)
'blood_male': (1858, 5000),
'golden_monkey': (627, 991),
'gr-tailed_pheasant': (607, 607),
'panda': (864, 864),
'rock_sheep': (1599, 5000),
'sambar(female)': (3165, 5000),
'sambar(male)': (845, 845),
'small_muntjac': (536, 536),
'takin': (980, 1282),
'tibetan_macaque': (226, 331),
'tufted_deer': (1047, 1047),
'wild_boar': (908, 1014),
'yellow_marten': (308, 382),
'total': (14070, 23399),
}
TEST_STATISTICS = {
'none': (0, 0),
'antelope': (1, 1),
'blood_male': (1, 1),
'golden_monkey': (1, 1),
'gr-tailed_pheasant':(1, 1),
'panda': (1, 1),
'rock_sheep': (1, 1),
'sambar(female)': (1, 1),
'sambar(male)': (1, 1),
'small_muntjac': (1, 1),
'takin': (1, 1),
'tibetan_macaque': (1, 1),
'tufted_deer': (1, 1),
'wild_boar': (1, 1),
'yellow_marten': (1, 1),
'total': (14, 14),
}
SPLITS_TO_SIZES = {
'train': 14070,
'test': 2814,
}
SPLITS_TO_STATISTICS = {
'train': TRAIN_STATISTICS,
'test': TEST_STATISTICS,
}
NUM_CLASSES = 14
e 迭代次数150000
=>train_ssd_network.py 155
batch_size=21 为了能被14070整除
14070/21 = 670
一般epoch训练200轮次
200*670 =134000 需要训练134000轮 取整150000
4 通过.sh脚本训练网络(通过加载预训练好的vgg16模型,微调网络)
下载预训练好的vgg16模型,解压放入checkpoint文件中,如果找不到vgg_16.ckpt文件,可以在下面的链接中点击下载。
链接:https://pan.baidu.com/s/1diWbdJdjVbB3AWN99406nA 密码:ge3x
(ubuntu解压不方便, 在win下下载解压)
按照之前的方式,同样,如果你是linux用户,你可以新建一个.sh文件,文件里写入
DATASET_DIR=./tfrecords_/
TRAIN_DIR=./train_model/
CHECKPOINT_PATH=./checkpoints/vgg_16.ckpt
python3 ./train_ssd_network.py \
--train_dir=./train_model/ \ #训练生成模型的存放路径
--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 \ #每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内存的百分比
5 通过修改train_ssd network.py文件训练网络(上述方法的替代方案)
1 在train_ssd_network.py文件里面直接修改(等效于用bash xxx.sh修改,)
(这里记录checkpoints和event logs)
(自己创建一个文件夹tfmodel)
=>train_ssd_network.py 43
修改为
2 tfrecord存放地址
=>train_ssd_network.py 139
修改后
3 datasetname, pascalvoc_2007 #数据名的前缀
=>train_ssd_network.py 133
修改后
4 ./checkpoints/vgg_16.ckpt \ #所加载模型的路径
=>train_ssd_network.py 162
修改为 '/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_ssd/SSD-Tensorflow-master/checkpoints/vgg_16.ckpt'
5 vgg_16 #所加载模型里面的作用域名
=>train_ssd_network.py 166
修改后
6 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
=>train_ssd_network.py 170
修改后
7 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
=>train_ssd_network.py 175
修改后
8
save_summaries_secs=60 \ #每60s保存一下日志
=>train_ssd_network.py 60
修改后
9 --save_interval_secs=600 \ #每600s保存一下模型 (不用改,本来就是)
=>train_ssd_network.py 63
10 --weight_decay=0.0005 \ #正则化的权值衰减的系数
=>train_ssd_network.py 72
修改后为
11 --optimizer=adam \ #选取的最优化函数
=>train_ssd_network.py 74
修改后为
12 --learning_rate=0.001 \ #学习率(本来就是)
=>train_ssd_network.py 113 115
如下会比较好:0.001-0.0001
13 --learning_rate_decay_factor=0.94 \ #学习率的衰减因子 (本来就是)
=>train_ssd_network.py 120
14 --batch_size=21 \ (暂时就是32了不做修改)
=>train_ssd_network.py 152
修改为21,为了能被14070(张图片)整除
batch_size=21 为了能被14070整除
14070/21 = 670
一般epoch训练200轮次
200*670 =134000 需要训练134000轮
15 --gpu_memory_fraction=0.9 #指定占用gpu内存的百分比\ (暂时就是32了不做修改)
=>train_ssd_network.py 66