淘先锋技术网

首页 1 2 3 4 5 6 7

最近在做多标签分类,多标签分类问题中使用的激活函数和loss计算公式如下:
在这里插入图片描述
然而keras中没有多标签分类绝对准确率的metrics,同时自己在做多标签分类的时候存在类别不平衡的问题,想使用focalloss平衡一下,这里是找到的可以用于多标签问题的focal_loss,下面两个都可以试试:

#用于类别不平衡的focalloss
def multi_category_focal_loss1(alpha, gamma=2.0):
    """
    focal loss for multi category of multi label problem
    适用于多分类或多标签问题的focal loss
    alpha用于指定不同类别/标签的权重,数组大小需要与类别个数一致
    当你的数据集不同类别/标签之间存在偏斜,可以尝试适用本函数作为loss
    Usage:
     model.compile(loss=[multi_category_focal_loss1(alpha=[1,2,3,2], gamma=2)], metrics=["accuracy"], optimizer=adam)
    """
    epsilon = 1.e-7
    alpha = tf.constant(alpha, dtype=tf.float32)
    #alpha = tf.constant([[1],[1],[1],[1],[1]], dtype=tf.float32)
    #alpha = tf.constant_initializer(alpha)
    gamma = float(gamma)
    def multi_category_focal_loss1_fixed(y_true, y_pred):
        y_true = tf.compat.v1.cast(y_true, tf.float32)
        y_pred = tf.compat.v1.clip_by_value(y_pred, epsilon, 1. - epsilon)
        y_t = tf.compat.v1.multiply(y_true, y_pred) + tf.compat.v1.multiply(1-y_true, 1-y_pred)
        ce = -tf.compat.v1.log(y_t)
        weight = tf.compat.v1.pow(tf.compat.v1.subtract(1., y_t), gamma)
        fl = tf.compat.v1.matmul(tf.compat.v1.multiply(weight, ce), alpha)
        loss = tf.compat.v1.reduce_mean(fl)
        return loss
    return multi_category_focal_loss1_fixed


def focal_loss(gamma=2., alpha=0.25):
    def focal_loss_fixed(y_true, y_pred):
        pt_1 = tf.where(tf.equal(y_true, 1), y_pred, tf.ones_like(y_pred))
        pt_0 = tf.where(tf.equal(y_true, 0), y_pred, tf.zeros_like(y_pred))
        return -K.sum(alpha * K.pow(1. - pt_1, gamma) * K.log(pt_1))-K.sum((1-alpha) * K.pow( pt_0, gamma) * K.log(1. - pt_0))
    return focal_loss_fixed

然后根据别人定义的方法,以及Tensorflow中tensor的操作,我做了一下绝对准确率的函数构建:

#绝对准确率
def acc(y_true, y_pred):
    epsilon = 1.e-7
    y_true = tf.compat.v1.cast(y_true, tf.float32)
    y_pred = tf.round(tf.compat.v1.clip_by_value(y_pred, epsilon, 1. - epsilon))
    y_judges = tf.reduce_all(tf.equal(y_true, y_pred),1)
    y_onehot = tf.where(y_judges, tf.ones_like(y_judges), tf.zeros_like(y_judges))
    true_num = tf.compat.v1.count_nonzero(y_onehot)
    all_num = tf.compat.v1.count_nonzero(tf.ones_like(y_onehot))
    acc = true_num/all_num
    return acc

可以利用下面代码试一下:

import tensorflow as tf
a = [[1,0,1],[1,1,0]]
b = [[0.1,0.3,0.6],[0.6,0.6,0.2]]
config = tf.compat.v1.ConfigProto()
config.gpu_options.allocator_type = 'BFC' #A "Best-fit with coalescing" algorithm, simplified from a version of dlmalloc.
config.gpu_options.allow_growth = True
with tf.compat.v1.Session(config=config) as session:
    print(session.run(acc_loss(a,b)))

得到的结果和sklearn.metrics.accuracy_socore是一致的。