keras 自定义loss损失函数,sample在loss上的加权和metric详解
首先辨析一下概念:
1.loss是整体网络进行优化的目标,是需要参与到优化运算,更新权值W的过程的
2.metric只是作为评价网络表现的一种“指标”,比如accuracy,是为了直观地了解算法的效果,充当view的作用,并不参与到优化过程
在keras中实现自定义loss,可以有两种方式,一种自定义lossfunction,
例如:
#方式一 defvae_loss(x,x_decoded_mean): xent_loss=objectives.binary_crossentropy(x,x_decoded_mean) kl_loss=-0.5*K.mean(1+z_log_sigma-K.square(z_mean)-K.exp(z_log_sigma),axis=-1) returnxent_loss+kl_loss vae.compile(optimizer='rmsprop',loss=vae_loss)
或者通过自定义一个keras的层(layer)来达到目的,作为model的最后一层,最后令model.compile中的loss=None:
#方式二 #Customlosslayer classCustomVariationalLayer(Layer): def__init__(self,**kwargs): self.is_placeholder=True super(CustomVariationalLayer,self).__init__(**kwargs) defvae_loss(self,x,x_decoded_mean_squash): x=K.flatten(x) x_decoded_mean_squash=K.flatten(x_decoded_mean_squash) xent_loss=img_rows*img_cols*metrics.binary_crossentropy(x,x_decoded_mean_squash) kl_loss=-0.5*K.mean(1+z_log_var-K.square(z_mean)-K.exp(z_log_var),axis=-1) returnK.mean(xent_loss+kl_loss) defcall(self,inputs): x=inputs[0] x_decoded_mean_squash=inputs[1] loss=self.vae_loss(x,x_decoded_mean_squash) self.add_loss(loss,inputs=inputs) #Wedon'tusethisoutput. returnx y=CustomVariationalLayer()([x,x_decoded_mean_squash]) vae=Model(x,y) vae.compile(optimizer='rmsprop',loss=None)
在keras中自定义metric非常简单,需要用y_pred和y_true作为自定义metric函数的输入参数点击查看metric的设置
注意事项:
1.keras中定义loss,返回的是batch_size长度的tensor,而不是像tensorflow中那样是一个scalar
2.为了能够将自定义的loss保存到model,以及可以之后能够顺利loadmodel,需要把自定义的loss拷贝到keras.losses.py源代码文件下,否则运行时找不到相关信息,keras会报错
有时需要不同的sample的loss施加不同的权重,这时需要用到sample_weight,例如
#Classweights: #Tobalancethedifferenceinoccurencesofdigitclasslabels. #50%oflabelsthatthediscriminatortrainsonare'fake'. #Weight=1/frequency cw1={0:1,1:1} cw2={i:self.num_classes/half_batchforiinrange(self.num_classes)} cw2[self.num_classes]=1/half_batch class_weights=[cw1,cw2]#使得两种loss能够一样重要
discriminator.train_on_batch(imgs,[valid,labels],class_weight=class_weights)
补充知识:keras模型训练与保存的call_back的设置
1、模型训练
fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)
参数:
x:训练数据的Numpy数组(如果模型只有一个输入),或者是Numpy数组的列表(如果模型有多个输入)。如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到Numpy数组。如果从本地框架张量馈送(例如TensorFlow数据张量)数据,x可以是None(默认)。
y:目标(标签)数据的Numpy数组(如果模型只有一个输出),或者是Numpy数组的列表(如果模型有多个输出)。如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到Numpy数组。如果从本地框架张量馈送(例如TensorFlow数据张量)数据,y可以是None(默认)。
batch_size:整数或None。每次梯度更新的样本数。如果未指定,默认为32。
epochs:整数。训练模型迭代轮次。一个轮次是在整个x和y上的一轮迭代。请注意,与initial_epoch一起,epochs被理解为「最终轮次」。模型并不是训练了epochs轮,而是到第epochs轮停止训练。
verbose:0,1或2。日志显示模式。0=安静模式,1=进度条,2=每轮一行。
callbacks:一系列的keras.callbacks.Callback实例。一系列可以在训练时使用的回调函数。
validation_split:0和1之间的浮点数。用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。验证数据是混洗之前x和y数据的最后一部分样本中。
validation_data:元组(x_val,y_val)或元组(x_val,y_val,val_sample_weights),用来评估损失,以及在每轮结束时的任何模型度量指标。模型将不会在这个数据上进行训练。这个参数会覆盖validation_split。
shuffle:布尔值(是否在每轮迭代之前混洗数据)或者字符串(batch)。batch是处理HDF5数据限制的特殊选项,它对一个batch内部的数据进行混洗。当steps_per_epoch非None时,这个参数无效。
class_weight:可选的字典,用来映射类索引(整数)到权重(浮点)值,用于加权损失函数(仅在训练期间)。这可能有助于告诉模型「更多关注」来自代表性不足的类的样本。
sample_weight:训练样本的可选Numpy权重数组,用于对损失函数进行加权(仅在训练期间)。您可以传递与输入样本长度相同的平坦(1D)Numpy数组(权重和样本之间的1:1映射),或者在时序数据的情况下,可以传递尺寸为(samples,sequence_length)的2D数组,以对每个样本的每个时间步施加不同的权重。在这种情况下,你应该确保在compile()中指定sample_weight_mode="temporal"。
initial_epoch:整数。开始训练的轮次(有助于恢复之前的训练)。
steps_per_epoch:整数或None。在声明一个轮次完成并开始下一个轮次之前的总步数(样品批次)。使用TensorFlow数据张量等输入张量进行训练时,默认值None等于数据集中样本的数量除以batch的大小,如果无法确定,则为1。
validation_steps:只有在指定了steps_per_epoch时才有用。停止前要验证的总步数(批次样本)
fit_generator(generator, steps_per_epoch=None, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_queue_size=10, workers=1, use_multiprocessing=False, shuffle=True, initial_epoch=0)
使用Python生成器(或Sequence实例)逐批生成的数据,按批次训练模型
参数
generator:一个生成器,或者一个Sequence(keras.utils.Sequence)对象的实例,以在使用多进程时避免数据的重复。生成器的输出应该为以下之一:
一个(inputs,targets)元组
一个(inputs,targets,sample_weights)元组。
这个元组(生成器的单个输出)组成了单个的batch。因此,这个元组中的所有数组长度必须相同(与这一个batch的大小相等)。不同的batch可能大小不同。例如,一个epoch的最后一个batch往往比其他batch要小,如果数据集的尺寸不能被batchsize整除。生成器将无限地在数据集上循环。当运行到第steps_per_epoch时,记一个epoch结束。
steps_per_epoch:在声明一个epoch完成并开始下一个epoch之前从generator产生的总步数(批次样本)。它通常应该等于你的数据集的样本数量除以批量大小。对于Sequence,它是可选的:如果未指定,将使用len(generator)作为步数。
epochs:整数。训练模型的迭代总轮数。一个epoch是对所提供的整个数据的一轮迭代,如steps_per_epoch所定义。注意,与initial_epoch一起使用,epoch应被理解为「最后一轮」。模型没有经历由epochs给出的多次迭代的训练,而仅仅是直到达到索引epoch的轮次。
verbose:0,1或2。日志显示模式。0=安静模式,1=进度条,2=每轮一行。
callbacks:keras.callbacks.Callback实例的列表。在训练时调用的一系列回调函数。
validation_data:它可以是以下之一:
验证数据的生成器或Sequence实例
一个(inputs,targets)元组
一个(inputs,targets,sample_weights)元组。
在每个epoch结束时评估损失和任何模型指标。该模型不会对此数据进行训练。
validation_steps:仅当validation_data是一个生成器时才可用。在停止前generator生成的总步数(样本批数)。对于Sequence,它是可选的:如果未指定,将使用len(generator)作为步数。
class_weight:可选的将类索引(整数)映射到权重(浮点)值的字典,用于加权损失函数(仅在训练期间)。这可以用来告诉模型「更多地关注」来自代表性不足的类的样本。
max_queue_size:整数。生成器队列的最大尺寸。如未指定,max_queue_size将默认为10。
workers:整数。使用的最大进程数量,如果使用基于进程的多线程。如未指定,workers将默认为1。如果为0,将在主线程上执行生成器。
use_multiprocessing:布尔值。如果True,则使用基于进程的多线程。如未指定,use_multiprocessing将默认为False。请注意,由于此实现依赖于多进程,所以不应将不可传递的参数传递给生成器,因为它们不能被轻易地传递给子进程。
shuffle:是否在每轮迭代之前打乱batch的顺序。只能与Sequence(keras.utils.Sequence)实例同用。
initial_epoch:开始训练的轮次(有助于恢复之前的训练)
fit与fit_generator函数都返回一个History的对象,其History.history属性记录了损失函数和其他指标的数值随epoch变化的情况,如果有验证集的话,也包含了验证集的这些指标变化情况,可以写入文本后续查看
2、保存模型结构、训练出来的权重、及优化器状态
keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1)
在每个训练期之后保存模型
参数:
filepath:字符串,保存模型的路径。如epoch1.h5或者epoch1.weight(save_weights_only=True)
monitor:被监测的数据。
verbose:详细信息模式,0或者1。
save_best_only:如果save_best_only=True,被监测数据的最佳模型就不会被覆盖。
mode:{auto,min,max}的其中之一。如果save_best_only=True,那么是否覆盖保存文件的决定就取决于被监测数据的最大或者最小值。对于val_acc,模式就会是max,而对于val_loss,模式就需要是min,等等。在auto模式中,方向会自动从被监测的数据的名字中判断出来。
save_weights_only:如果True,那么只有模型的权重会被保存(model.save_weights(filepath)),否则的话,整个模型会被保存(model.save(filepath))。
period:每个检查点之间的间隔(训练轮数)
例子:
checkpoint=ModelCheckpoint(filepath=model_weight_filepath,monitor='val_acc', verbose=0,save_best_only=True,save_weights_only=True,mode='max',period=1) model.fit(X_train,Y_train,callbacks=[checkpoint])
3、当验证损失不再继续降低时,如何中断训练?当监测值不再改善时中止训练
EarlyStopping回调函数:
keras.callbacks.EarlyStopping( monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto', baseline=None, restore_best_weights=False)
当被监测的数量不再提升,则停止训练
参数:
monitor:被监测的数据。
min_delta:在被监测的数据中被认为是提升的最小变化,例如,小于min_delta的绝对变化会被认为没有提升。
patience:没有进步的训练轮数,在这之后训练就会被停止。
verbose:详细信息模式,0或1。
mode:{auto,min,max}其中之一。在min模式中,当被监测的数据停止下降,训练就会停止;在max模式中,当被监测的数据停止上升,训练就会停止;在auto模式中,方向会自动从被监测的数据的名字中判断出来。
baseline:要监控的数量的基准值。如果模型没有显示基准的改善,训练将停止。
restore_best_weights:是否从具有监测数量的最佳值的时期恢复模型权重。如果为False,则使用在训练的最后一步获得的模型权重。
例子:
earlystopping=EarlyStopping(monitor='val_acc',verbose=1,patience=3)
model.fit(X_train,Y_train,callbacks=[earlystopping])
4、学习率动态调整
keras.callbacks.ReduceLROnPlateau( monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, cooldown=0, min_lr=0)
当标准评估停止提升时,降低学习速率。
当学习停止时,模型总是会受益于降低2-10倍的学习速率。这个回调函数监测一个数据并且当这个数据在一定「有耐心」的训练轮之后还没有进步,那么学习速率就会被降低。
参数
monitor:被监测的数据。
factor:学习速率被降低的因数。新的学习速率=学习速率*因数
patience:没有进步的训练轮数,在这之后训练速率会被降低。
verbose:整数。0:安静,1:更新信息。
mode:{auto,min,max}其中之一。如果是min模式,学习速率会被降低如果被监测的数据已经停止下降;在max模式,学习塑料会被降低如果被监测的数据已经停止上升;在auto模式,方向会被从被监测的数据中自动推断出来。
min_delta:对于测量新的最优化的阀值,只关注巨大的改变。
cooldown:在学习速率被降低之后,重新恢复正常操作之前等待的训练轮数量。
min_lr:学习速率的下边界。
例子:
reduce_lr=ReduceLROnPlateau(monitor='val_loss',factor=0.2, patience=5,min_lr=0.001) model.fit(X_train,Y_train,callbacks=[reduce_lr])
4、Tensorboard可视化
keras.callbacks.TensorBoard( log_dir='./logs', histogram_freq=0, batch_size=32, write_graph=True, write_grads=False, write_images=False, embeddings_freq=0, embeddings_layer_names=None, embeddings_metadata=None, embeddings_data=None, update_freq='epoch')
回调函数为Tensorboard编写一个日志,这样你可以可视化测试和训练的标准评估的动态图像,也可以可视化模型中不同层的激活值直方图。
如果你已经使用pip安装了Tensorflow,你应该可以从命令行启动Tensorflow:
tensorboard--logdir=/full_path_to_your_logs
参数:
log_dir:用来保存被TensorBoard分析的日志文件的文件名。
histogram_freq:对于模型中各个层计算激活值和模型权重直方图的频率(训练轮数中)。如果设置成0,直方图不会被计算。对于直方图可视化的验证数据(或分离数据)一定要明确的指出。
write_graph:是否在TensorBoard中可视化图像。如果write_graph被设置为True,日志文件会变得非常大。
write_grads:是否在TensorBoard中可视化梯度值直方图。histogram_freq必须要大于0。
batch_size:用以直方图计算的传入神经元网络输入批的大小。
write_images:是否在TensorBoard中将模型权重以图片可视化。
embeddings_freq:被选中的嵌入层会被保存的频率(在训练轮中)。
embeddings_layer_names:一个列表,会被监测层的名字。如果是None或空列表,那么所有的嵌入层都会被监测。
embeddings_metadata:一个字典,对应层的名字到保存有这个嵌入层元数据文件的名字。查看详情关于元数据的数据格式。以防同样的元数据被用于所用的嵌入层,字符串可以被传入。
embeddings_data:要嵌入在embeddings_layer_names指定的层的数据。Numpy数组(如果模型有单个输入)或Numpy数组列表(如果模型有多个输入)。Learnoreaboutembeddings。
update_freq:'batch'或'epoch'或整数。当使用'batch'时,在每个batch之后将损失和评估值写入到TensorBoard中。同样的情况应用到'epoch'中。如果使用整数,例如10000,这个回调会在每10000个样本之后将损失和评估值写入到TensorBoard中。注意,频繁地写入到TensorBoard会减缓你的训练。
5、如何记录每一次epoch的训练/验证损失/准确度?
Model.fit函数会返回一个History回调,该回调有一个属性history包含一个封装有连续损失/准确的lists。
代码如下:
hist=model.fit(X,y,validation_split=0.2)
print(hist.history)
Keras输出的loss,val这些值如何保存到文本中去
Keras中的fit函数会返回一个History对象,它的History.history属性会把之前的那些值全保存在里面,如果有验证集的话,也包含了验证集的这些指标变化情况,具体写法:
hist=model.fit(train_set_x,train_set_y,batch_size=256,shuffle=True,nb_epoch=nb_epoch,validation_split=0.1) withopen('log_sgd_big_32.txt','w')asf: f.write(str(hist.history))
6、多个回调函数用逗号隔开
例如:
model_weight_filepath="./bert_classfition-test_model"+str(i)+".weight" earlystopping=EarlyStopping(monitor='val_acc',verbose=1,patience=3) reducelronplateau=ReduceLROnPlateau(monitor="val_acc",verbose=1,mode='max',factor=0.5,patience=2) checkpoint=ModelCheckpoint(filepath=model_weight_filepath,monitor='val_acc', verbose=0,save_best_only=True,save_weights_only=True,mode='max',period=1) model.fit_generator( train_D.__iter__(), steps_per_epoch=len(train_D), epochs=epochs, validation_data=valid_D.__iter__(), validation_steps=len(valid_D), callbacks=[earlystopping,reducelronplateau,checkpoint])
以上这篇keras自定义loss损失函数,sample在loss上的加权和metric详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。