这里讲了如何在VOC数据集上训练SSD300。预设参数复制了SSD 300 “07+12”模型。训练SSD512雷同,所以不再介绍,在其他数据集上也是一样的。
你可以找到一个完整的培训摘要
from keras.optimizers import Adam, SGD
from keras.callbacks import ModelCheckpoint, LearningRateScheduler, TerminateOnNaN, CSVLogger
from keras import backend as K
from keras.models import load_model
from math import ceil
import numpy as np
from matplotlib import pyplot as plt
from models.keras_ssd300 import ssd_300
from keras_loss_function.keras_ssd_loss import SSDLoss
from keras_layers.keras_layer_AnchorBoxes import AnchorBoxes
from keras_layers.keras_layer_DecodeDetections import DecodeDetections
from keras_layers.keras_layer_DecodeDetectionsFast import DecodeDetectionsFast
from keras_layers.keras_layer_L2Normalization import L2Normalization
from ssd_encoder_decoder.ssd_input_encoder import SSDInputEncoder
from ssd_encoder_decoder.ssd_output_decoder import decode_detections, decode_detections_fast
from data_generator.object_detection_2d_data_generator import DataGenerator
from data_generator.object_detection_2d_geometric_ops import Resize
from data_generator.object_detection_2d_photometric_ops import ConvertTo3Channels
from data_generator.data_augmentation_chain_original_ssd import SSDDataAugmentation
from data_generator.object_detection_2d_misc_utils import apply_inverse_transforms
%matplotlib inline
代码中需要进行任何更改的地方都标记为TOD0,所有没有标记的都只需要执行
这个小结设定了模型定义的配置参数,此处设置的参数构建由SSD300模型的ssd_300()函数所需要的SSDInputEncoder对象的构造函数进一步使用,大多数这些参数需要定义anchor boxes
下面参数都是caffe模型prototxt上面定义的,默认的anchor box的比例取决于特定的数据集。用于COCO数据集的scaling factors小于用于Pascal Voc数据集的。
img_height = 300 # Height of the model input images
img_width = 300 # Width of the model input images
img_channels = 3 # Number of color channels of the model input images
mean_color = [123, 117, 104] # The per-channel mean of the images in the dataset. Do not change this value if you're using any of the pre-trained weights.
swap_channels = [2, 1, 0] # The color channel order in the original SSD is BGR, so we'll have the model reverse the color channel order of the input images.
n_classes = 20 # Number of positive classes, e.g. 20 for Pascal VOC, 80 for MS COCO
scales_pascal = [0.1, 0.2, 0.37, 0.54, 0.71, 0.88, 1.05] # The anchor box scaling factors used in the original SSD300 for the Pascal VOC datasets
scales_coco = [0.07, 0.15, 0.33, 0.51, 0.69, 0.87, 1.05] # The anchor box scaling factors used in the original SSD300 for the MS COCO datasets
scales = scales_pascal
aspect_ratios = [[1.0, 2.0, 0.5],
[1.0, 2.0, 0.5, 3.0, 1.0/3.0],
[1.0, 2.0, 0.5, 3.0, 1.0/3.0],
[1.0, 2.0, 0.5, 3.0, 1.0/3.0],
[1.0, 2.0, 0.5],
[1.0, 2.0, 0.5]] # The anchor box aspect ratios used in the original SSD300; the order matters
two_boxes_for_ar1 = True
steps = [8, 16, 32, 64, 100, 300] # The space between two adjacent anchor box center points for each predictor layer.
offsets = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5] # The offsets of the first anchor box center points from the top and left borders of the image as a fraction of the step size for each predictor layer.
clip_boxes = False # Whether or not to clip the anchor boxes to lie entirely within the image boundaries
variances = [0.1, 0.1, 0.2, 0.2] # The variances by which the encoded target coordinates are divided as in the original implementation
normalize_coords = True
下面的使用一种就行
如果你想要创建一个新的SSD模型,这是最需要读取的部分。如果你想要导入之前保存的SSD300模型,直接去2.2节
下面的代码坐了这些事:
1.调用ssd_300()建立模型
2.导入在weights_path中定义好的权重。你可以导入VGG16或者说预训练的完整模型,如果你想要重现原始SSD的训练过程,加载VGG16的权重。无论什么情况,你需要设置权重路径,所有权重提供在readme中
3.最后编译模型并且运行。我们需要定义 optimizer(adam)loss function(SSDLoss)通过使用compile()方法
通常来说,opyimer会被选择为Adam,但是由于最初的版本使用SGD动量,我们将使用同样的为了保持最初SSD训练过程。Adam是一个更由于的优化器,所以如果你的目标是获得更好的效果,使用Adam。你需要稍微调整学习率如果使用Adam。
注意这里设定的learning rate是不重要的,由于下面我们会将学习率调整给学习函数,该函数将覆盖此处设定的任何学习率。
SSDLoss是常用的Keras loss functiom,它实现了多任务,包括分类和smooth l1.neg_pos_ratio和palpha如文中所述设置
# 1: Build the Keras model.# 1: Bu
K.clear_session() # Clear previous models from memory.
model = ssd_300(image_size=(img_height, img_width, img_channels),
n_classes=n_classes,
mode='training',
l2_regularization=0.0005,
scales=scales,
aspect_ratios_per_layer=aspect_ratios,
two_boxes_for_ar1=two_boxes_for_ar1,
steps=steps,
offsets=offsets,
clip_boxes=clip_boxes,
variances=variances,
normalize_coords=normalize_coords,
subtract_mean=mean_color,
swap_channels=swap_channels)
# 2: Load some weights into the model.
# TODO: Set the path to the weights you want to load.
weights_path = 'path/to/VGG_ILSVRC_16_layers_fc_reduced.h5'
model.load_weights(weights_path, by_name=True)
# 3: Instantiate an optimizer and the SSD loss function and compile the model.
# If you want to follow the original Caffe implementation, use the preset SGD
# optimizer, otherwise I'd recommend the commented-out Adam optimizer.
#adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
sgd = SGD(lr=0.001, momentum=0.9, decay=0.0, nesterov=False)
ssd_loss = SSDLoss(neg_pos_ratio=3, alpha=1.0)
model.compile(optimizer=sgd, loss=ssd_loss.compute_loss)
如果你之前创建并且保存了一个模型,现在想要加载它,请执行下一个代码单元,只需要修改HDF5 文件路径
SSD模型包含自定义对象:Keras核心库中不包含损失函数,anchor box和l2-正则化损失函数,因此我们需要将他提供给模型加载器
下一个单元假定你要加载已训练的模型,如果你想要创建 推理或者快速推理模型,你要将 DecodeDetections or DecodeDetectionsFast layer type假如custom_objects dictionary below.
# TODO: Set the path to the `.h5` file of the model to be loaded.
model_path = 'path/to/trained/model.h5'
# We need to create an SSDLoss object in order to pass that to the model loader.
ssd_loss = SSDLoss(neg_pos_ratio=3, alpha=1.0)
K.clear_session() # Clear previous models from memory.
model = load_model(model_path, custom_objects={'AnchorBoxes': AnchorBoxes,
'L2Normalization': L2Normalization,
'compute_loss': ssd_loss.compute_loss})
下面的代码为训练和验证数据集设定数据生成器用来训练模型。
这个设定重现了pas voc 2007 2012和验证集2007test
你需要改变数据集的地址,注意解析XML注释文件中的标签可能需要一定的时间
注意到生成器提供了两种选项来加速训练。默认来说,它从磁盘加载一个批次的图像,但是只要做有两个缺点。
首先,对于像JPG这样的压缩图像格式,这是一个巨大的计算浪费,因为每次加载图像需要一次一次的解压,
其次,
未完待续。。。