""""
keras.py
functions to run and train autopilots using keras
"""
from tensorflow.python.keras.layers import Input
from tensorflow.python.keras.models import Model, load_model
from tensorflow.python.keras.layers import Convolution2D
from tensorflow.python.keras.layers import Dropout, Flatten, Dense
from tensorflow.python.keras.callbacks import ModelCheckpoint, EarlyStopping
class KerasPilot:
def load(self, model_path):
self.model = load_model(model_path)
def shutdown(self):
pass
def train(self, train_gen, val_gen,
saved_model_path, epochs=100, steps=100, train_split=0.8,
verbose=1, min_delta=.0005, patience=5, use_early_stop=True):
"""
train_gen: generator that yields an array of images an array of
"""
"""
filename:字符串,保存模型的路径
monitor:需要监视的值
verbose:信息展示模式,0或1(checkpoint的保存信息,类似Epoch 00001: saving model to ...)
save_best_only:当设置为True时,监测值有改进时才会保存当前的模型( the latest best model according to the quantity monitored will not be overwritten)
mode:‘auto’,‘min’,‘max’之一,在save_best_only=True时决定性能最佳模型的评判准则,例如,当监测值为val_acc时,模式应为max,当监测值为val_loss时,模式应为min。在auto模式下,评价准则由被监测值的名字自动推断。
save_weights_only:若设置为True,则只保存模型权重,否则将保存整个模型(包括模型结构,配置信息等)
period:CheckPoint之间的间隔的epoch数
"""
# checkpoint to save model after each epoch
save_best = ModelCheckpoint(saved_model_path,
monitor='val_loss',
verbose=verbose,
save_best_only=True,
mode='min')
"""
monitor: 监控的数据接口,有’acc’,’val_acc’,’loss’,’val_loss’等等。正常情况下如果有验证集,就用’val_acc’或者’val_loss’。
min_delta:增大或减小的阈值,只有大于这个部分才算作improvement。这个值的大小取决于monitor,也反映了你的容忍程度。
patience:能够容忍多少个epoch内都没有improvement。这个设置其实是在抖动和真正的准确率下降之间做tradeoff。如果patience设的大,那么最终得到的准确率要略低于模型可以达到的最高准确率。
如果patience设的小,那么模型很可能在前期抖动,还在全图搜索的阶段就停止了,准确率一般很差。patience的大小和learning rate直接相关。在learning rate设定的情况下,
前期先训练几次观察抖动的epoch number,比其稍大些设置patience。在learning rate变化的情况下,建议要略小于最大的抖动epoch number。
mode: 'auto','min','max'之一,在min模式训练,如果检测值停止下降则终止训练。在max模式下,当检测值不再上升的时候则停止训练。
"""
# stop training if the validation error stops improving.
early_stop = EarlyStopping(monitor='val_loss',
min_delta=min_delta,
patience=patience,
verbose=verbose,
mode='auto')
# 回调函数
callbacks_list = [save_best]
if use_early_stop:
callbacks_list.append(early_stop)
"""
generator:生成器函数,生成器的输出应该为:
一个形如(inputs,targets)的tuple
一个形如(inputs, targets,sample_weight)的tuple。所有的返回值都应该包含相同数目的样本。生成器将无限在数据集上循环。每个epoch以经过模型的样本数达到samples_per_epoch时,记一个epoch结束
steps_per_epoch:整数,当生成器返回steps_per_epoch次数据时计一个epoch结束,执行下一个epoch
epochs:整数,数据迭代的轮数
verbose:日志显示,0为不在标准输出流输出日志信息,1为输出进度条记录,2为每个epoch输出一行记录
validation_data:具有以下三种形式之一
生成验证集的生成器
一个形如(inputs,targets)的tuple
一个形如(inputs,targets,sample_weights)的tuple
validation_steps: 当validation_data为生成器时,本参数指定验证集的生成器返回次数
class_weight:规定类别权重的字典,将类别映射为权重,常用于处理样本不均衡问题。
sample_weight:权值的numpy array,用于在训练时调整损失函数(仅用于训练)。可以传递一个1D的与样本等长的向量用于对样本进行1对1的加权,或者在面对时序数据时,传递一个的形式为(samples,sequence_length)的矩阵来为每个时间步上的样本赋不同的权。这种情况下请确定在编译模型时添加了sample_weight_mode='temporal'。
workers:最大进程数在使用基于进程的线程时,最多需要启动的进程数量
use_multiprocessing:布尔值。当为True时,使用基于基于过程的线程。
max_q_size:生成器队列的最大容量
initial_epoch: 从该参数指定的epoch开始训练,在继续之前的训练时有用。
"""
hist = self.model.fit_generator(
train_gen,
steps_per_epoch=steps,
epochs=epochs,
verbose=1,
validation_data=val_gen,
callbacks=callbacks_list,
validation_steps=steps * (1.0 - train_split) / train_split)
return hist
class KerasLinear(KerasPilot):
def __init__(self, model=None, num_outputs=None, *args, **kwargs):
super(KerasLinear, self).__init__(*args, **kwargs)
if model:
self.model = model
elif num_outputs is not None:
self.model = default_linear()
else:
self.model = default_linear()
def run(self, img_arr):
# reshape()是数组array中的方法,作用是将数据重新组织
img_arr = img_arr.reshape((1,) + img_arr.shape)
outputs = self.model.predict(img_arr)
# print(len(outputs), outputs)
steering = outputs[0]
throttle = outputs[1]
return steering[0][0], throttle[0][0]
def default_linear():
img_in = Input(shape=(120, 160, 3), name='img_in')
x = img_in
# Convolution2D class name is an alias for Conv2D
# filters代表卷积核个数,kernel_size卷积核大小,strides步长
x = Convolution2D(filters=24, kernel_size=(5, 5), strides=(2, 2), activation='relu')(x)
x = Convolution2D(filters=32, kernel_size=(5, 5), strides=(2, 2), activation='relu')(x)
x = Convolution2D(filters=64, kernel_size=(5, 5), strides=(2, 2), activation='relu')(x)
x = Convolution2D(filters=64, kernel_size=(3, 3), strides=(2, 2), activation='relu')(x)
x = Convolution2D(filters=64, kernel_size=(3, 3), strides=(1, 1), activation='relu')(x)
# Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。
x = Flatten(name='flattened')(x)
"""Keras定义网络层的基本方法
units:该层有几个神经元
activation:该层使用的激活函数
use_bias:是否添加偏置项
kernel_initializer:权重初始化方法
bias_initializer:偏置值初始化方法
kernel_regularizer:权重规范化函数
bias_regularizer:偏置值规范化方法
activity_regularizer:输出的规范化方法
kernel_constraint:权重变化限制函数
bias_constraint:偏置值变化限制函数
"""
x = Dense(units=100, activation='linear')(x)
# 防止过拟合
x = Dropout(rate=.1)(x)
x = Dense(units=50, activation='linear')(x)
x = Dropout(rate=.1)(x)
# categorical output of the angle
angle_out = Dense(units=1, activation='linear', name='angle_out')(x)
# continous output of throttle
throttle_out = Dense(units=1, activation='linear', name='throttle_out')(x)
model = Model(inputs=[img_in], outputs=[angle_out, throttle_out])
# 目标函数
model.compile(optimizer='adam',
loss={'angle_out': 'mean_squared_error',
'throttle_out': 'mean_squared_error'},
loss_weights={'angle_out': 0.5, 'throttle_out': .5})
return model
donkeycar的keras网络的代码解析
猜你喜欢
转载自blog.csdn.net/qq_36444039/article/details/103124852
今日推荐
周排行