zoukankan      html  css  js  c++  java
  • tensorflow中阶API (激活函数,损失函数,评估指标,优化器,回调函数)

    一、激活函数

    1、从ReLU到GELU,一文概览神经网络的激活函数:
    https://zhuanlan.zhihu.com/p/98863801
    2、tensorflow使用激活函数:一种是作为某些层的activation参数指定,另一种是显式添加layers.Activation激活层

    import tensorflow as tf
    from tensorflow.keras import layers,models
    model = models.Sequential()
    model.add(layers.Dense(32,input_shape = (None,16),activation = tf.nn.relu)) #通过activation参数指定
    model.add(layers.Dense(10))
    model.add(layers.Activation(tf.nn.softmax))  # 显式添加layers.Activation激活层
    

    二、损失函数

    1、内置损失函数
    监督学习的目标函数由损失函数和正则化项组成。(Objective = Loss + Regularization)
    损失函数在模型编译时指定
    回归模型: 均方误差损失函数 mean_squared_error
    二分类模型:二元交叉熵损失函数 binary_crossentropy
    多分类模型:label 为one-hot编码,则类别交叉熵损失函数 categorical_crossentropy
    label为类别序号编码,使用稀疏类别交叉熵损失函数sparse_categorical_crossentropy

    model.compile(optimizer = "rmsprop",
            loss = "binary_crossentropy",metrics = ["AUC"])
    

    2、自定义损失函数

    2.1 自定义损失函数接收两个张量y_true,y_pred作为输入参数,并输出一个标量作为损失函数值。
    2.2 对tf.keras.losses.Loss进行子类化,重写call方法实现损失的计算逻辑,从而得到损失函数的类的实现
    自定义Focal Loss,一种对binary_crossentropy的改进损失函数形式
    它在样本不均衡和存在较多易分类的样本时相比binary_crossentropy具有明显的优势。
    它有两个可调参数,alpha参数和gamma参数。其中alpha参数主要用于衰减负样本的权重,gamma参数主要用于衰减容易训练样本的权重。
    从而让模型更加聚焦在正样本和困难样本上。
    详见《5分钟理解Focal Loss与GHM——解决样本不平衡利器》

    https://zhuanlan.zhihu.com/p/80594704

    [focal\_loss(y,p) = egin{cases} -alpha (1-p)^{gamma}log(p) & ext{if y = 1}\ -(1-alpha) p^{gamma}log(1-p) & ext{if y = 0} end{cases}]

    def focal_loss(gamma=2., alpha=0.75):
        
        def focal_loss_fixed(y_true, y_pred):
            bce = tf.losses.binary_crossentropy(y_true, y_pred)
            p_t = (y_true * y_pred) + ((1 - y_true) * (1 - y_pred))
            alpha_factor = y_true * alpha + (1 - y_true) * (1 - alpha)
            modulating_factor = tf.pow(1.0 - p_t, gamma)
            loss = tf.reduce_sum(alpha_factor * modulating_factor * bce,axis = -1 )
            return loss
        return focal_loss_fixed
    
    class FocalLoss(tf.keras.losses.Loss):
        
        def __init__(self,gamma=2.0,alpha=0.75,name = "focal_loss"):
            self.gamma = gamma
            self.alpha = alpha
    
        def call(self,y_true,y_pred):
            bce = tf.losses.binary_crossentropy(y_true, y_pred)
            p_t = (y_true * y_pred) + ((1 - y_true) * (1 - y_pred))
            alpha_factor = y_true * self.alpha + (1 - y_true) * (1 - self.alpha)
            modulating_factor = tf.pow(1.0 - p_t, self.gamma)
            loss = tf.reduce_sum(alpha_factor * modulating_factor * bce,axis = -1 )
            return loss
    

    三、评估指标metrics

    KS指标适合二分类问题,其计算方式为 KS=max(TPR-FPR).

    其中TPR=TP/(TP+FN) , FPR = FP/(FP+TN)
    TPR曲线实际上就是正样本的累积分布曲线(CDF),FPR曲线实际上就是负样本的累积分布曲线(CDF)。

    KS指标就是正样本和负样本累积分布曲线差值的最大值。

    #类形式的自定义评估指标
    class KS(metrics.Metric):
        
        def __init__(self, name = "ks", **kwargs):
            super(KS,self).__init__(name=name,**kwargs)
            self.true_positives = self.add_weight(
                name = "tp",shape = (101,), initializer = "zeros")
            self.false_positives = self.add_weight(
                name = "fp",shape = (101,), initializer = "zeros")
       
        @tf.function
        def update_state(self,y_true,y_pred):
            y_true = tf.cast(tf.reshape(y_true,(-1,)),tf.bool)
            y_pred = tf.cast(100*tf.reshape(y_pred,(-1,)),tf.int32)
            
            for i in tf.range(0,tf.shape(y_true)[0]):
                if y_true[i]:
                    self.true_positives[y_pred[i]].assign(
                        self.true_positives[y_pred[i]]+1.0)
                else:
                    self.false_positives[y_pred[i]].assign(
                        self.false_positives[y_pred[i]]+1.0)
            return (self.true_positives,self.false_positives)
        
        @tf.function
        def result(self):
        # cumsum,累加求和,结果为[[1],[2],[3],...[8]] reduce_sum 为求和,结果为8。二者相除。
            cum_positive_ratio = tf.truediv(
                tf.cumsum(self.true_positives),tf.reduce_sum(self.true_positives))
            cum_negative_ratio = tf.truediv(
                tf.cumsum(self.false_positives),tf.reduce_sum(self.false_positives))
            ks_value = tf.reduce_max(tf.abs(cum_positive_ratio - cum_negative_ratio)) 
            return ks_value
    
    
    y_true = tf.constant([[1],[1],[1],[0],[1],[1],[1],[0],[0],[0],[1],[0],[1],[0]])
    y_pred = tf.constant([[0.6],[0.1],[0.4],[0.5],[0.7],[0.7],
                          [0.7],[0.4],[0.4],[0.5],[0.8],[0.3],[0.5],[0.3]])
    
    myks = KS()
    myks.update_state(y_true,y_pred)
    tf.print(myks.result())
    
    

    四、优化器

    https://zhuanlan.zhihu.com/p/32230623
    在model.compile()时候,完成,损失函数,评估指标,优化器的设置。
    深度学习优化算法大概经历了 SGD -> SGDM -> NAG ->Adagrad -> Adadelta(RMSprop) -> Adam -> Nadam 这样的发展历程
    在keras.optimizers子模块中,它们基本上都有对应的类的实现。

    SGD, 默认参数为纯SGD, 设置momentum参数不为0实际上变成SGDM, 考虑了一阶动量, 设置 nesterov为True后变成NAG,即 Nesterov Accelerated Gradient,在计算梯度时计算的是向前走一步所在位置的梯度。

    Adagrad, 考虑了二阶动量,对于不同的参数有不同的学习率,即自适应学习率。缺点是学习率单调下降,可能后期学习速率过慢乃至提前停止学习。

    RMSprop, 考虑了二阶动量,对于不同的参数有不同的学习率,即自适应学习率,对Adagrad进行了优化,通过指数平滑只考虑一定窗口内的二阶动量。

    Adadelta, 考虑了二阶动量,与RMSprop类似,但是更加复杂一些,自适应性更强。

    Adam, 同时考虑了一阶动量和二阶动量,可以看成RMSprop上进一步考虑了一阶动量。

    Nadam, 在Adam基础上进一步考虑了 Nesterov Acceleration。

    五、回调函数 callbacks

    查看训练模型的内在状态和统计

    model.fit(x,y,callbacks=[回调函数列表])
    
  • 相关阅读:
    Teamwork[HDU4494]
    The Parallel Challenge Ballgame[HDU1101]
    「JSOI2016」无界单词
    「SCOI2015」小凸玩密室
    #3636. IIIDX(iiidx)
    #2652. 背单词(word)
    「JXOI2017」加法
    拙者
    19.10.01 acm E:Lowest Common Ancestor
    #3391. big
  • 原文地址:https://www.cnblogs.com/leimu/p/13572929.html
Copyright © 2011-2022 走看看