我正在训练一个以softmax层结尾的分类问题。我想将损失计算为预测概率和每个示例的softmax输出与真值标签的平方距离乘积的平均值。
在伪代码中:平均值(概率* 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:
label1 = [0,0,1,0],prediction1 = [1,0,0,0]
loss1 = 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)
答案 0 :(得分:0)
在设计自定义丢失功能时,您可以使用Tensorflow(或Theano)以及Keras后端。请注意Tensorflow中的tf.multiply和其他函数。
以下代码在Keras(测试和工作)中实现此自定义丢失功能:
bs = batch_size
l = labels
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, ((sb,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)
答案 1 :(得分:0)
这里是另一种实现方式,它以略微不同的权重实现相同的目标。注意:一次性标签必须为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)