【问题标题】:Keras - custom loss function - Computing squared distance of softmax output from truth labelKeras - 自定义损失函数 - 从真值标签计算 softmax 输出的平方距离
【发布时间】:2018-03-12 00:04:33
【问题描述】:

我正在训练一个以 softmax 层结束的分类问题。我想将损失计算为每个示例的 softmax 输出与真值标签的预测概率和平方距离的乘积的平均值。

在伪代码中:average(probability*distance_from_label**2)

现在我正在使用以下代码,该代码运行,但收敛到为每个实例输出“0”。它的实现有问题:

bs = batch_size
l = labels
X = K.constant([[0,1,...,l-1] for y in range(bs)], shape=((bs,l))
X = tf.add(-y_true, X)
X = tf.abs(X)
X = tf.multiply(y_pred, X)
X = tf.multiply(X, X)
return K.mean(X)

有没有办法实现这个平方差损失函数并保留一个 softmax 层?并且仍然要测量预测标签和真实标签之间的实际欧几里得距离,而不仅仅是单热向量中的元素差异?

为清楚起见,我提供了以下示例:

示例 1:

标签1 = [0, 0, 1, 0],预测1 = [1, 0, 0, 0]

损失1 = 4 = (4 + 0 + 0 + 0) = (1*2^2 + 0*1^2 + 0*0^2 + 0*1^2)

示例 2:

label2 = [0, 1, 0, 0],prediction2 = [0.3, 0.1, 0.3, 0.3]

损失2 = 1.8 = (0.3 + 0 + 0.3 + 1.2) = (0.3*1^2 + 0.1*0^2 + 0.3*1^2 + 0.3*2^2)

【问题讨论】:

    标签: python tensorflow machine-learning neural-network keras


    【解决方案1】:

    在设计自定义损失函数时,您可以使用 Tensorflow(或 Theano)以及 Keras 后端。注意 Tensorflow 中的 tf.multiply 和其他函数。

    以下代码在 Keras 中实现了这个自定义损失函数(经过测试并可以工作):

    def custom_loss(y_true, y_pred):
        bs = 1 # batch size
        l = 4 # label number
        c = K.constant([[x for x in range(l)] for y in range(bs)], shape=((bs, l)))
    
        truths = tf.multiply(y_true, c)
        truths = K.sum(truths, axis=1)
        truths = K.concatenate(list(truths for i in range(l)))
        truths = K.reshape(truths, ((bs,l)))
    
        distances = tf.add(truths, -c)
        sqdist = tf.multiply(distances, distances)
    
        out = tf.multiply(y_pred, sqdist)
        out = K.sum(out, axis=1)
    
        return K.mean(out)
    
    y_true = K.constant([0,0,1,0])
    y_pred = K.constant([1,0,0,0])
    print(custom_loss(y_true, y_pred)) # tf.Tensor(4.0, shape=(), dtype=float32)
    

    【讨论】:

    • 您能否更深入地了解您是如何实现这一点的?如何创建以批量大小和标签号为变量的图表?
    • @SebastiaanvanBaars - 也许你已经知道你的编辑,但更深入的是我做了很多试验和错误。咨询了很多the docsarticles like this one。此外,您可能还对 this coursera course 感兴趣,了解高级 TF 技术,包括自定义损失函数
    【解决方案2】:

    这是另一个实现相同目标但权重略有不同的实现。注意:one-hot 标签需要为 dtype=float32。所有学分都归我的主管所有。

    import numpy as np
    import tensorflow as tf
    import tensorflow.keras as keras
     
    model = keras.models.Sequential()
    model.add(keras.layers.Dense(5, activation="relu"))
    model.add(keras.layers.Dense(4, activation="softmax"))
    opt = keras.optimizers.Adam(lr=1e-3, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
     
    def custom_loss(y_true, y_pred):
    
        a = tf.reshape(tf.range(tf.cast(tf.shape(y_pred)[1],dtype=tf.float32)),(1,-1))
        c = tf.tile(a,(tf.shape(y_pred)[0],1))
        x = tf.math.multiply(y_true,c)
        x = tf.reshape(tf.reduce_sum(x, axis=1),(-1,1))
        x = tf.tile(x,(1,tf.shape(y_pred)[1]))
        x = tf.math.pow(tf.math.subtract(x,c),2)
        x = tf.math.multiply(x,y_pred)
        x = tf.reduce_sum(x, axis=1)
        return tf.reduce_mean(x)
         
    
     
    yTrue= np.array([[0,0,1,0],[0,0,1,0],[0, 1, 0, 0]]).astype(np.float32)
    y_true = tf.constant(yTrue)
    y_pred = tf.constant([[1,0,0,0],[0,0,1,0],[0.3, 0.1, 0.3, 0.3]])
    custom_loss(y_true,y_pred)
     
    model.compile(optimizer=opt, loss=custom_loss)
    model.fit(np.random.random((3,10)),yTrue, epochs=100)
    

    【讨论】:

      猜你喜欢
      • 2018-07-14
      • 2020-02-09
      • 2021-01-14
      • 2020-02-25
      • 1970-01-01
      • 2020-06-04
      • 2019-11-28
      • 2020-12-19
      • 2017-12-18
      相关资源
      最近更新 更多