数据分析师养成之路--keras学习中metrics和callbacks笔记

complie中的metrics参数

model.compile(...metrics=['accuracy'])

如上,
metrics中有两个arguments,y_true,和y_pred
它所接收的评估指标为,损失函数,(mse等)和准确率(accuracy等),它们都作用于训练集和验证集(eg: loss:..acc..mae .. val_loss:..val_acc..val_mae..),当然该性能的评估结果不会真正用于训练,只用来显示(作为参考)
(每个batch,输出:loss acc mae (后两个就是设置metrics得到),每个epoch(一轮),输出:loss,acc mae … val_loss…val_acc… val_mae)
metrics中的损失函数和准确率函数可由自己改写:
如下:

def top_3_accuracy(y_true,y_pred):
# 返回的函数即为metrics 中支持的函数
    return metrics.top_k_categorical_accuracy(y_true,y_pred,k=3)

model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              metrics=[metrics.mae,top_3_accuracy])
import keras.backend as K
 # 对metrics中的accuracy函数进行重写
def mean_pred(y_true, y_pred):
    return K.mean(y_pred)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])

fit中的callbacks参数:

from keras.callbacks import ModelCheckpoint

model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

'''
saves the model weights after each epoch if the validation loss decreased
'''
checkpointer = ModelCheckpoint(filepath='/tmp/weights.hdf5', verbose=1, save_best_only=True)
model.fit(x_train, y_train, batch_size=128, epochs=20, verbose=0, validation_data=(X_test, Y_test), callbacks=[checkpointer])
class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = []

    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))

model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

history = LossHistory()
model.fit(x_train, y_train, batch_size=128, epochs=20, verbose=0, callbacks=[history])

print(history.losses)
# outputs
'''
[0.66047596406559383, 0.3547245744908703, ..., 0.25953155204159617, 0.25901699725311789]
'''

就我而言,callbacks很方便作为 验证集数据评估的参考
如下,为fit_generator的callbacks参数写一个RocAuc接口

class RocAuc(keras.callbacks.Callback):
    def __init__(self,validation_generate,interval=1):
        self.interval=interval
        self.validation_generate=validation_generate
    def on_epoch_end(self,epoch, logs={}):
    # 每次epoch,读取一批生成的数据
        x_val,y_val=next(self.validation_generate)
        #print(y_val)
        if epoch % self.interval == 0:
            try:
                y_pred=self.model.predict(x_val,verbose=0)
                score=roc_auc_score(y_val,y_pred)
                print('\n ROC_AUC - epoch:%d - score:%.6f \n' % (epoch + 1, score*100))

            except:

                print('\n  epoch:%d  only one class!!\n' % (epoch + 1))

def validata(iter_test):
    for index in iter_test:
        yield index
vli=validata(iter_test)
rocauc=RocAuc(validation_generate=vli)
model.fit_generator(...callbacks=[rocauc])

当然也可以把earlyStopping加入其中,不过需要传入roc_auc_val 参数,

class RocAuc(keras.callbacks.Callback):
    def __init__(self,validation_generate,interval=1):
        self.interval=interval
        self.validation_generate=validation_generate
    def on_train_begin(self,logs={}):
    #添加roc_auc_val属性
        self.roc_auc_score=[]
        if not ('roc_auc_val' in self.params['metrics']):
            self.params['metrics'].append('roc_auc_val')
    def on_epoch_end(self,epoch, logs={}):
        logs['roc_auc_val']=float('-inf')
        x_val,y_val=next(self.validation_generate)
        #print(y_val)
        if epoch % self.interval == 0:
            try:
                y_pred=self.model.predict(x_val,verbose=0)
                score=roc_auc_score(y_val,y_pred)
                logs['roc_auc_val']=score*100
                print('\n ROC_AUC - epoch:%d - score:%.6f \n' % (epoch + 1, score*100))

            except:
                logs['roc_auc_val']='cant compute!!'
                print('\n  epoch:%d  only one class!!\n' % (epoch + 1))

        self.roc_auc_score.append(logs.get('roc_auc_val'))

def validata(iter_test):
    for index in iter_test:
        yield index
vli=validata(iter_test)
model.fit_generator(...callbacks=[rocauc, EarlyStopping(monitor='roc_auc_val',patience=30, verbose=2,mode='max')])
print(rocauc.roc_auc_score)

当然也可以添加plot,显示batch,epoch的loss,acc输出趋势.
( 比如,我们看我们的模型是否收敛时,(如果源数据太大,可以抽取一部分(.sample(xxx)),看其模型的Loss,val_loss,是否逐渐下降(主要看loss)acc,val_acc是否逐渐增长,若loss已经平衡了/acc已经达到最大,不变了,那么可以考虑改变learningRate)

class  LossHistory(keras.callbacks.Callback):
    def __init__(self):
        self.loss={'count':[],'batch':[],'epoch':[]}
        self.acc={'count':[],'batch':[],'epoch':[]}
        self.val_loss={'count':[],'batch':[],'epoch':[]}
        self.val_acc={'count':[],'batch':[],'epoch':[]}
    def on_batch_end(self,batch,logs=[]):
        self.loss['batch'].append(logs.get('loss'))
        self.acc['batch'].append(logs.get('acc'))
        self.loss['count'].append(batch)
        self.acc['count'].append(batch)
    def on_epoch_end(self,epoch,logs=[]):
        self.val_loss['epoch'].append(logs.get('loss'))
        self.val_acc['epoch'].append(logs.get('acc'))
        self.val_loss['epoch'].append(logs.get('val_loss'))
        self.val_acc['epoch'].append(logs.get('val_acc'))
        self.val_loss['count'].append(epoch)
        self.val_acc['count'].append(epoch)
    def loss_plot(self,loss_type):
        iters=range(len(loss_type)-1)
        plt.figure()
        if loss_type=='batch':
            plt.plot(iters,self.acc[loss_type],'g',label='train_acc')
            plt.plot(iters,self.loss[loss_type],'b',label='train_loss')
        if loss_type=='epoch':
            plt.plot(iters,self.val_acc[loss_type],'r',label='val_acc')
            plt.plot(iters,self.val_loss[loss_type],'r',label='val_loss')
        plt.grid(True)
        plt.xlabel(loss_type)
        plt.ylabel('acc-loss')
        plt.legend(loc='upper right')
        plt.show()

你可能感兴趣的:(机器学习之Python语言基础)