yolov3之train.py

"""
Retrain the YOLO model for your own dataset.
"""

import numpy as np
import keras.backend as K
from keras.layers import Input, Lambda
from keras.models import Model
from keras.optimizers import Adam
from keras.callbacks import TensorBoard, ModelCheckpoint, ReduceLROnPlateau, EarlyStopping

from yolo3.model import preprocess_true_boxes, yolo_body, tiny_yolo_body, yolo_loss
from yolo3.utils import get_random_data


def _main():
    #图片的路径+label
    annotation_path = 'train.txt'
    log_dir = 'logs/000/'
    classes_path = 'model_data/voc_classes.txt'
    anchors_path = 'model_data/yolo_anchors.txt'
    class_names = get_classes(classes_path)
    num_classes = len(class_names)
    anchors = get_anchors(anchors_path)

    input_shape = (416,416) # multiple of 32, hw  这个shape是网络要求的输入,416*416.

    is_tiny_version = len(anchors)==6 # default setting   判断是否是简单的yolo
    if is_tiny_version:
        model = create_tiny_model(input_shape, anchors, num_classes,
            freeze_body=2, weights_path='model_data/tiny_yolo_weights.h5')
    else:
        model = create_model(input_shape, anchors, num_classes,
            freeze_body=2, weights_path='model_data/yolo_weights.h5') # make sure you know what you freeze

    logging = TensorBoard(log_dir=log_dir)
    #保存模型训练参数
    checkpoint = (log_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',
        monitor='val_loss', save_weights_only=True, save_best_only=True, period=3)
    #当准确率不怎么变化时,调整学习率  plateau:平台期 
    reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1)
    #早停法,防止过拟合,在测试集上的表现不好时
    early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=1)
    # 将训练数据分成训练和验证数据
    val_split = 0.1
    with open(annotation_path) as f:
        lines = f.readlines()
    np.random.seed(10101)
    np.random.shuffle(lines)
    np.random.seed(None)
    num_val = int(len(lines)*val_split)
    num_train = len(lines) - num_val

    # Train with frozen layers first, to get a stable loss.
    # Adjust num epochs to your dataset. This step is enough to obtain a not bad model.
    if True:
        model.compile(optimizer=Adam(lr=1e-3), loss={
            # use custom yolo_loss Lambda layer.
            'yolo_loss': lambda y_true, y_pred: y_pred})

        batch_size = 32
        print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))
        model.fit_generator(data_generator_wrapper(lines[:num_train], batch_size, input_shape, anchors, num_classes),
                steps_per_epoch=max(1, num_train//batch_size),
                validation_data=data_generator_wrapper(lines[num_train:], batch_size, input_shape, anchors, num_classes),
                validation_steps=max(1, num_val//batch_size),
                epochs=50,
                initial_epoch=0,
                callbacks=[logging, checkpoint])
        model.save_weights(log_dir + 'trained_weights_stage_1.h5')

    # Unfreeze and continue training, to fine-tune.
    # Train longer if the result is not good.
    if True:
        for i in range(len(model.layers)):
            model.layers[i].trainable = True
        model.compile(optimizer=Adam(lr=1e-4), loss={'yolo_loss': lambda y_true, y_pred: y_pred}) # recompile to apply the change
        print('Unfreeze all of the layers.')

        batch_size = 32 # note that more GPU memory is required after unfreezing the body
        print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))
        model.fit_generator(data_generator_wrapper(lines[:num_train], batch_size, input_shape, anchors, num_classes),
            steps_per_epoch=max(1, num_train//batch_size),
            validation_data=data_generator_wrapper(lines[num_train:], batch_size, input_shape, anchors, num_classes),
            validation_steps=max(1, num_val//batch_size),
            epochs=100,
            initial_epoch=50,
            callbacks=[logging, checkpoint, reduce_lr, early_stopping])
        model.save_weights(log_dir + 'trained_weights_final.h5')

    # Further training if needed.


def get_classes(classes_path):
    '''loads the classes'''
    with open(classes_path) as f:
        class_names = f.readlines()
        #['aeroplane\n', 'bicycle\n', 'bird\n', 'boat\n', 'bottle\n', 'bus\n', 'car\n', 'cat\n', 'chair\n', 'cow\n', 'diningtable\n', 'dog\n', 'horse\n', 'motorbike\n', 'person\n', 'pottedplant\n', 'sheep\n', 'sofa\n', 'train\n', 'tvmonitor\n']
    class_names = [c.strip() for c in class_names]   #记住这个用法,去除首尾字符,默认的有\n,\t 和空格。
        #['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor']
    return class_names

def get_anchors(anchors_path):
    '''loads the anchors from a file'''
    with open(anchors_path) as f:
        anchors = f.readline()
    anchors = [float(x) for x in anchors.split(',')]
    return np.array(anchors).reshape(-1, 2)


def create_model(input_shape, anchors, num_classes, load_pretrained=True, freeze_body=2,
            weights_path='model_data/yolo_weights.h5'):
    '''create the training model'''
    K.clear_session() # get a new session
    image_input = Input(shape=(None, None, 3))
    h, w = input_shape
    num_anchors = len(anchors)

    y_true = [Input(shape=(h//{0:32, 1:16, 2:8}[l], w//{0:32, 1:16, 2:8}[l], \
        num_anchors//3, num_classes+5)) for l in range(3)]

    model_body = yolo_body(image_input, num_anchors//3, num_classes)
    print('Create YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))

    if load_pretrained:
        model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)
        print('Load weights {}.'.format(weights_path))
        if freeze_body in [1, 2]:
            # Freeze darknet53 body or freeze all but 3 output layers.
            num = (185, len(model_body.layers)-3)[freeze_body-1]
            for i in range(num): model_body.layers[i].trainable = False
            print('Freeze the first {} layers of total {} layers.'.format(num, len(model_body.layers)))

    model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
        arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5})(
        [*model_body.output, *y_true])
    model = Model([model_body.input, *y_true], model_loss)

    return model

def create_tiny_model(input_shape, anchors, num_classes, load_pretrained=True, freeze_body=2,
            weights_path='model_data/tiny_yolo_weights.h5'):
    '''create the training model, for Tiny YOLOv3'''
    K.clear_session() # get a new session
    image_input = Input(shape=(None, None, 3))
    h, w = input_shape
    num_anchors = len(anchors)

    y_true = [Input(shape=(h//{0:32, 1:16}[l], w//{0:32, 1:16}[l], \
        num_anchors//2, num_classes+5)) for l in range(2)]

    model_body = tiny_yolo_body(image_input, num_anchors//2, num_classes)
    print('Create Tiny YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))

    if load_pretrained:
        model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)
        print('Load weights {}.'.format(weights_path))
        if freeze_body in [1, 2]:
            # Freeze the darknet body or freeze all but 2 output layers.
            num = (20, len(model_body.layers)-2)[freeze_body-1]
            for i in range(num): model_body.layers[i].trainable = False
            print('Freeze the first {} layers of total {} layers.'.format(num, len(model_body.layers)))

    model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
        arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.7})(
        [*model_body.output, *y_true])
    model = Model([model_body.input, *y_true], model_loss)

    return model

def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes):
    '''data generator for fit_generator'''
    n = len(annotation_lines)
    i = 0
    while True:
        image_data = []
        box_data = []
        for b in range(batch_size):
            if i==0:
                np.random.shuffle(annotation_lines)
            image, box = get_random_data(annotation_lines[i], input_shape, random=True)
            image_data.append(image)
            box_data.append(box)
            i = (i+1) % n
        image_data = np.array(image_data)
        box_data = np.array(box_data)
        y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)
        yield [image_data, *y_true], np.zeros(batch_size)

def data_generator_wrapper(annotation_lines, batch_size, input_shape, anchors, num_classes):
    n = len(annotation_lines)
    if n==0 or batch_size<=0: return None
    return data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes)

if __name__ == '__main__':
    _main()
训练代码思路:
1.加载训练数据及其他文件
1)加载文件路径
训练图片加标签路径(train.txt)
class类别路径
anchor路径
log文件保存路径
2)读取类别,anchor
3)将训练数据分成训练和交叉数据

2.构建模型
1)根据len(anchor)==6判断是否为tiny_yolo版本
2)构建模型,这里以create_model版本为例。这里与其他不同的是,加载预训练模型,并保持某些层的模型参数不变。这里面的model最后一层是loss层,输出的结果就是每一个batch_size的结果。
model = create_model(input_shape, anchors, num_classes,
            freeze_body=2, weights_path='model_data/yolo_weights.h5')
模型构建具体过程详见create_model函数解析

3.model.compile
设置loss和optimizer
1)optimizer用于设置学习率和优化方法,就是比如梯度下降算法 or something else。
2)自定义损失函数,由于模型最后一层的输出为loss,这里的loss自定义loss函数,就直接是模型预测结果
loss={'yolo_loss': lambda y_true, y_pred: y_pred})

4.model.fit_generator
1)callbacks设置  ModelCheckpoint、ReduceLROnPlateau、EarlyStopping
这个函数的作用在于在产生batch_size的同时,对模型进行训练。


这里面的训练分两次。
第一次是冻住除了三个输出层意外的其他层,训练,获得平稳的损失。
第二次是解冻,使每个层的模型参数都得到训练更新。
1.model要求的shape是(416,416)
2.实际训练的数据可以不是(416,416),此时由get_random函数进行变换成(416,416)大小,并且包含box尺寸的变化
3.preprocess_true_box将(416,416)的图片变成gt格式的label
[l][batch_size,grid,grid,3,5+classes]    (xywhscore)  取值范围均为0-1
这个是true_box,用于计算iou
true_box还要通过公式计算成tx、ty、tw、th 与模型预测出的output的tx、ty、tw、th进行损失函数的计算。



函数解析:

def get_classes(classes_path):
    '''loads the classes'''
    with open(classes_path) as f:
        class_names = f.readlines()
        #['aeroplane\n', 'bicycle\n', 'bird\n', 'boat\n', 'bottle\n', 'bus\n', 'car\n', 'cat\n', 'chair\n', 'cow\n', 'diningtable\n', 'dog\n', 'horse\n', 'motorbike\n', 'person\n', 'pottedplant\n', 'sheep\n', 'sofa\n', 'train\n', 'tvmonitor\n']
    class_names = [c.strip() for c in class_names]   #记住这个用法,去除首尾字符,默认的有\n,\t 和空格。
        #['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor']
    return class_names

def get_anchors(anchors_path):
    '''loads the anchors from a file'''
    with open(anchors_path) as f:
        anchors = f.readline()
    anchors = [float(x) for x in anchors.split(',')]
    return np.array(anchors).reshape(-1, 2)


'''
with open('xxx.txt') as f:
    lines=f.readlines()/line=f.readline()
dida=[c.strip('') for c in lines]   strip()  用于去除首尾字符,默认为空格、\t、\n
didida=[c.split('') for c in lines]          遇到''引号内的字符自动将字符串分开。比如
1,2,3,4,5   此时应用 split(',')就可以变成   [1,2,3,4,5]将string加float变成单独的元素。
'''

 

def create_model(input_shape, anchors, num_classes, load_pretrained=True, freeze_body=2,
            weights_path='model_data/yolo_weights.h5'):
    '''create the training model'''
    K.clear_session() # get a new session
    image_input = Input(shape=(None, None, 3))
    h, w = input_shape
    num_anchors = len(anchors)

    y_true = [Input(shape=(h//{0:32, 1:16, 2:8}[l], w//{0:32, 1:16, 2:8}[l], \
        num_anchors//3, num_classes+5)) for l in range(3)]

    model_body = yolo_body(image_input, num_anchors//3, num_classes)
    print('Create YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))

    if load_pretrained:
        model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)
        print('Load weights {}.'.format(weights_path))
        if freeze_body in [1, 2]:
            # Freeze darknet53 body or freeze all but 3 output layers.
            num = (185, len(model_body.layers)-3)[freeze_body-1]
            for i in range(num): model_body.layers[i].trainable = False
            print('Freeze the first {} layers of total {} layers.'.format(num, len(model_body.layers)))

    model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
        arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5})(
        [*model_body.output, *y_true])
    model = Model([model_body.input, *y_true], model_loss)

    return model

1.ModelCheckpoint() 

keras.callbacks.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1)

函数作用:保存训练过程中的重要的权值,防止电脑坏掉,训练白费。
函数参数:
filepath: string, path to save the model file.
保存.h5的路径
monitor: quantity to monitor.
被监控量,通常为 val_loss,val_acc,默认为val_loss
verbose: verbosity mode, 0 or 1.
是否在训练过程中显示变动信息,0为不显示,1为显示,默认为0
save_best_only: if save_best_only=True, the latest best model according to the quantity monitored will not be overwritten.
是否保存全部过程中最好的模型,就是该模型会被保存起来,不会被覆盖。默认为False
save_weights_only: if True, then only the model's weights will be saved 
(model.save_weights(filepath)), else the full model is saved (model.save(filepath)).
是否只保存权重,True为是,False为否,就是还会保存模型结构等配置信息,默认为False
mode: one of {auto, min, max}. If save_best_only=True, the decision to overwrite the current save file is made based on either the maximization or the minimization of the monitored quantity. For val_acc, this should be max, for val_loss this should be min, etc. In auto mode, the direction is automatically inferred from the name of the monitored quantity.
模式同下面的模式
period: Interval (number of epochs) between checkpoints.
每隔几个period大小的epoch保存一次。默认为1.

2.ReduceLROnPlateau()   8

keras.callbacks.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, cooldown=0, min_lr=0)
函数作用:当被监控量monitor不怎么变化时,调整learning rate。也就是函数名称的意思,在平台期减小学习率(OnPlateauReduceLR)
参数含义

monitor: quantity to be monitored.
被监控量
factor: factor by which the learning rate will be reduced. new_lr = lr * factor
新的lr=lr*factor,默认为0.1
patience: number of epochs that produced the monitored quantity with no improvement after which training will be stopped. Validation quantities may not be produced for every epoch, if the validation frequency (model.fit(validation_freq=5)) is greater than one.
连续patience次两个monitor之间的值没有增加/减少min_delta,默认为10
verbose: int. 0: quiet, 1: update messages.
是否输出这个训练过程中的变动信息,0不输出,1输出;默认为0
mode: one of {auto, min, max}. In min mode, lr will be reduced when the quantity monitored has stopped decreasing; in max mode it will be reduced when the quantity monitored has stopped increasing; in auto mode, the direction is automatically inferred from the name of the monitored quantity.
模式:min是减少   max是增加   auto自动根据monitor来决定是减少还是增加 默认为'auto'
min_delta: threshold for measuring the new optimum, to only focus on significant changes.
连续变化的值没有超过的阈值min_delta,结合上面食用更加。 默认为0.0001
cooldown: number of epochs to wait before resuming normal operation after lr has been reduced.
调整过lr的冷却期,默认为0
min_lr: lower bound on the learning rate.
lr不能低于的值,默认为0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!这里的间隔标准都是每个epoch之间!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

3.EarlyStopping()   7

keras.callbacks.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto', baseline=None, restore_best_weights=False)

函数作用
Stop training when a monitored quantity has stopped improving.当被监控量停止优化时。
函数参数
monitor: quantity to be monitored.
被监控值,默认val_loss
min_delta: minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute change of less than min_delta, will count as no improvement.
patience: number of epochs that produced the monitored quantity with no improvement after which training will be stopped. Validation quantities may not be produced for every epoch, if the validation frequency (model.fit(validation_freq=5)) is greater than one.
同上,默认0
verbose: verbosity mode.
同上,默认0
mode: one of {auto, min, max}. In min mode, training will stop when the quantity monitored has stopped decreasing; in max mode it will stop when the quantity monitored has stopped increasing; in auto mode, the direction is automatically inferred from the name of the monitored quantity.
同上
baseline: Baseline value for the monitored quantity to reach. Training will stop if the model doesn't show improvement over the baseline.
monitor需要到达的值,如果到这个值没有继续改善,可以停止。默认None
restore_best_weights: whether to restore model weights from the epoch with the best value of the monitored quantity. If False, the model weights obtained at the last step of training are used.
是否启用存储的最好的值,如果是,则最终获得训练期间最后的权重参数,如果否,则获得最后一个epoch的权重参数。默认Flase

4.model.compile()

model.compile(optimizer, loss=None, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None)
#函数作用
Configures the model for training.
#函数参数
optimizer: String (name of optimizer) or optimizer instance. See optimizers.
设置优化器,比如'SGD'
loss: String (name of objective function) or objective function or Loss instance. See losses. If the model has multiple outputs, you can use a different loss on each output by passing a dictionary or a list of losses. The loss value that will be minimized by the model will then be the sum of all individual losses.
设置loss函数,比如 'crossentropy' 写法可能不对。
metrics: List of metrics to be evaluated by the model during training and testing. Typically you will use metrics=['accuracy']. To specify different metrics for different outputs of a multi-output model, you could also pass a dictionary, such as metrics={'output_a': 'accuracy', 'output_b': ['accuracy', 'mse']}. You can also pass a list (len = len(outputs)) of lists of metrics such as metrics=[['accuracy'], ['accuracy', 'mse']] or metrics=['accuracy', ['accuracy', 'mse']].
设置是否计算 accuracy或者mse ,mse是均方误差 mean square error
loss_weights: Optional list or dictionary specifying scalar coefficients (Python floats) to weight the loss contributions of different model outputs. The loss value that will be minimized by the model will then be the weighted sum of all individual losses, weighted by the loss_weights coefficients. If a list, it is expected to have a 1:1 mapping to the model's outputs. If a dict, it is expected to map output names (strings) to scalar coefficients.

sample_weight_mode: If you need to do timestep-wise sample weighting (2D weights), set this to "temporal". None defaults to sample-wise weights (1D). If the model has multiple outputs, you can use a different sample_weight_mode on each output by passing a dictionary or a list of modes.

weighted_metrics: List of metrics to be evaluated and weighted by sample_weight or class_weight during training and testing.

target_tensors: By default, Keras will create placeholders for the model's target, which will be fed with the target data during training. If instead you would like to use your own target tensors (in turn, Keras will not expect external Numpy data for these targets at training time), you can specify them via the target_tensors argument. It can be a single tensor (for a single-output model), a list of tensors, or a dict mapping output names to target tensors.

**kwargs: When using the Theano/CNTK backends, these arguments are passed into K.function. When using the TensorFlow backend, these arguments are passed into tf.Session.run.
'''
后面几个没做注释的,都是没见过的,见过再来补充。
一般就是用前三个,optimizer,loss,metrics=['accuracy']
'''

5.model.fit_generator()

函数作用:以batch_size的形式训练,比fit多了个generator,generator的作用是产生batch_size大小的训练集。
model.fit_generator(generator,
                    steps_per_epoch,
                    epochs=,
                    verbose=1,
                    callbacks=None,
                    validation_data=,
                    validation_steps=,
                    class_weight=None,
                    max_queue_size=10,   
                    workers=1, 
                    use_multiprocessing=False, 
                    shuffle=True, 
                    initial_epoch=0
steps_per_epoch=一个epoch的数据/batch_size
epochs=把数据集训练几遍
validation_data  
#usually,训练集被分成训练和验证集,上面的一个epoch的数据就是这里的训练数据,这里的validation_data就是一整个训练集减去训练的数据。
validation_steps=
z.b.
val_percent=0.1
train_num=len(data)*val_percent 
train_data=data[:train_num]
val_data=data[train_num:]
batch_size=32
steps_per_epoch=len(train_data)//batch_size
validation_steps=len(val_data)//batch_size??? 不太懂的亚子。
fit_generator

fit_generator(generator, steps_per_epoch=None, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, validation_freq=1, class_weight=None, max_queue_size=10, workers=1, use_multiprocessing=False, shuffle=True, initial_epoch=0)
#函数作用
使用Python生成器(或Sequence的实例)逐批生成的数据训练模型。
生成器与模型并行运行以提高效率。例如,这允许您并行地对CPU上的图像进行实时数据增强,以在GPU上训练模型。
keras.utils.Sequence的使用保证了排序,并在使用use_multiprocessing = True时保证每个epoch每个输入的单一使用。
#函数参数
generator: 
生成器:生成器或Sequence(keras.utils.Sequence)对象的实例,以便在使用多重处理时避免重复数据。发电机的输出必须是
        元组(输入,目标)
        元组(输入,目标,sample_weights)。
    该元组(生成器的单个输出)进行单个批处理。因此,该元组中的所有数组都必须具有相同的长度(等于此批处理的大小)。不同批次可能具有不同大小。例如,如果数据集的大小不能被该批次的大小整除,则该时期的最后一个批次通常小于其他批次。预期生成器将无限期地循环其数据。当模型已看到steps_per_epoch批处理时,纪元结束。
steps_per_epoch: 
整数。在声明一个epoch完成并开始下一个epoch之前,要从生成器产生的步骤总数(样本批次)。它通常应等于ceil(num_samples / batch_size)对Sequence而言是可选的:如果未指定,将使len(generator)作为steps。
epochs: 训练多少轮次
verbose: Integer. 0, 1, or 2. Verbosity mode. 0 = silent, 1 = progress bar, 2 = one line per epoch.

callbacks: List of keras.callbacks.Callback instances. List of callbacks to apply during training. See callbacks.

validation_data: This can be either a generator or a Sequence object for the validation data
        tuple (x_val, y_val)
        tuple (x_val, y_val, val_sample_weights)
on which to evaluate the loss and any model metrics at the end of each epoch. The model will not be trained on this data.

validation_steps: validation_steps:仅当validation_data是生成器时才相关。在每个纪元结束时停止之前,validation_data生成器要产生的总步数(样本批次)。它通常应等于验证数据集的样本数量除以批次大小。 Sequence的可选:如果未指定,将使用len(validation_data)作为steps

validation_freq: 仅在提供验证数据时才相关。整数或集合。容器实例(例如列表,元组等)。如果是整数,请指定在执行新的验证运行之前要运行多少个训练时期,例如validation_freq = 2每2个周期运行一次验证。如果是容器,请指定要在其上运行验证的时期,例如validation_freq = [1、2、10]在第1、2和10个epoch的末尾运行验证。    

class_weight: Optional dictionary mapping class indices (integers) to a weight (float) value, used for weighting the loss function (during training only). This can be useful to tell the model to "pay more attention" to samples from an under-represented class.

max_queue_size: Integer. Maximum size for the generator queue. If unspecified, max_queue_size will default to 10.

workers: Integer. Maximum number of processes to spin up when using process-based threading. If unspecified, workers will default to 1. If 0, will execute the generator on the main thread.

use_multiprocessing: Boolean. If True, use process-based threading. If unspecified, use_multiprocessing will default to False. Note that because this implementation relies on multiprocessing, you should not pass non-picklable arguments to the generator as they can't be passed easily to children processes.

shuffle: Boolean. Whether to shuffle the order of the batches at the beginning of each epoch. Only used with instances of Sequence (keras.utils.Sequence). Has no effect when steps_per_epoch is not None.

initial_epoch: Integer. Epoch at which to start training (useful for resuming a previous training run).
整数。开始训练的时期(用于恢复以前的训练运行)。

返回
历史记录对象。它的History.history属性记录了连续时期的训练损失值和metrics值,以及验证损失值和验证metrics值(如果适用)。   

6.data_generator_wrapper

#generator
用于产生batch_size个数的数据,注意yield的使用,随用随生成,避免大量内存占用。

def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes):
    '''data generator for fit_generator'''
    n = len(annotation_lines)
    i = 0
    while True:
        image_data = []
        box_data = []
        for b in range(batch_size):
            if i==0:
                np.random.shuffle(annotation_lines)
            image, box = get_random_data(annotation_lines[i], input_shape, random=True)
            image_data.append(image)
            box_data.append(box)
            i = (i+1) % n
        image_data = np.array(image_data)
        box_data = np.array(box_data)
        y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)
        yield [image_data, *y_true], np.zeros(batch_size)

def data_generator_wrapper(annotation_lines, batch_size, input_shape, anchors, num_classes):
    n = len(annotation_lines)
    if n==0 or batch_size<=0: return None
    return data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes)

现在存疑的就是loss那块,值是怎么传递的???

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值