18
2020
04

Tensorflow:keras中自定义metrics函数和Keras自定义Loss函数

1. 比较一般的自定义metrics函数:

需要注意的是,不能像sklearn那样直接定义,因为这里的y_true和y_pred是张量,不是numpy数组。示例如下:

from keras import backend
def rmse(y_true, y_pred):
    return backend.sqrt(backend.mean(backend.square(y_pred - y_true), axis=-1))

用的时候直接:

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=[rmse])

2. 比较复杂的如AUC函数:

AUC的计算需要整体数据,如果直接在batch里算,误差就比较大,不能合理反映整体情况。这里采用回调函数写法,每个epoch计算一次:

from sklearn.metrics import roc_auc_score

class roc_callback(keras.callbacks.Callback):
    def __init__(self,training_data, validation_data):
        self.x = training_data[0]
        self.y = training_data[1]
        self.x_val = validation_data[0]
        self.y_val = validation_data[1]
        
    
    def on_train_begin(self, logs={}):
        return
 
    def on_train_end(self, logs={}):
        return
 
    def on_epoch_begin(self, epoch, logs={}):
        return
 
    def on_epoch_end(self, epoch, logs={}):        
        y_pred = self.model.predict(self.x)
        roc = roc_auc_score(self.y, y_pred)      
        
        y_pred_val = self.model.predict(self.x_val)
        roc_val = roc_auc_score(self.y_val, y_pred_val)      
        
        print('\rroc-auc: %s - roc-auc_val: %s' % (str(round(roc,4)),str(round(roc_val,4))),end=100*' '+'\n')
        return
 
    def on_batch_begin(self, batch, logs={}):
        return
 
    def on_batch_end(self, batch, logs={}):
        return

调用回调函数示例:

model.fit(X_train, y_train, epochs=10, batch_size=4, 
          callbacks = [roc_callback(training_data=[X_train, y_train], validation_data=[X_test, y_test])] )


Keras本身提供了很多常用的loss函数(即目标函数),但这些损失函数都是比较基本的、通用的。有时候我们需要根据自己所做的任务来自定义损失函数,虽然Keras是一个很高级的封装,自定义loss还是比较简单的。这里记录一下自定义loss的方法,一为助记、二为助人。

3. 自定义loss函数:

自定义loss函数之前,我们可以看看Keras官方是如何定义loss的,进入keras/keras/losses.py文件,我们可以看到很多Keras自带loss的实现代码。比如最简单的均方误差损失函数:

def mean_squared_error(y_true, y_pred):
    return K.mean(K.square(y_pred - y_true), axis=-1)

其中y_pred为网络给出的预测值,y_true即是标签,两者均为tensor。在loss中直接操作这两个变量即可实现自己想要的loss。例如,我们将其改为四次方的平均值来作为新的loss:

def mean_squared_error2(y_true, y_pred):
    return K.mean(K.square(K.square(y_pred-y_true)),axis=-1)

在model编译阶段将loss指定为我们自定义的函数:

model.compile(optimizer='rmsprop',loss=mean_squared_error2)

————————————————

版权声明:本文为期权记的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://www.qiquanji.com/post/163.html


微信扫码关注

更新实时通知

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。