在 Tensorflow 中创建加权 MSE 损失函数

b.j*_*b.j 5 keras tensorflow loss-function

我想使用 训练循环神经网络Tensorflow。我的模型为每个训练样本输出一个 1 x 100 向量。假设这y = [y_1, y_2, ..., y_100]是我的训练样本输出x,预期输出为y'= [y'_1, y'_2, ..., y'_100]

我希望编写一个自定义损失函数来计算该特定样本的损失,如下所示:

Loss =  1/sum(weights) * sqrt(w_1*(y_1-y'_1)^2 + ... + w_100*(y_100-y'_100)^2)
Run Code Online (Sandbox Code Playgroud)

weights = [w_1,...,w_100]是给定的权重数组。

有人可以帮助我实现这样的自定义损失函数吗?(我在训练时也使用小批量)

Mar*_*ani 4

我想强调的是,根据您的问题,您有两种可能性:

[1] 如果所有样本的权重相等:

您可以构建一个损失包装器。这是一个虚拟示例:

n_sample = 200
X = np.random.uniform(0,1, (n_sample,10))
y = np.random.uniform(0,1, (n_sample,100))
W = np.random.uniform(0,1, (100,)).astype('float32')

def custom_loss_wrapper(weights):
    def loss(true, pred):
        sum_weights = tf.reduce_sum(weights) * tf.cast(tf.shape(pred)[0], tf.float32)
        resid = tf.sqrt(tf.reduce_sum(weights * tf.square(true - pred)))
        return resid/sum_weights
    return loss

inp = Input((10,))
x = Dense(256)(inp)
pred = Dense(100)(x)

model = Model(inp, pred)
model.compile('adam', loss=custom_loss_wrapper(W))

model.fit(X, y, epochs=3)
Run Code Online (Sandbox Code Playgroud)

[2] 如果样本之间的权重不同:

您应该使用以下命令构建模型add_loss,以便动态考虑每个样本的权重。这是一个虚拟示例:

n_sample = 200
X = np.random.uniform(0,1, (n_sample,10))
y = np.random.uniform(0,1, (n_sample,100))
W = np.random.uniform(0,1, (n_sample,100))

def custom_loss(true, pred, weights):
    sum_weights = tf.reduce_sum(weights)
    resid = tf.sqrt(tf.reduce_sum(weights * tf.square(true - pred)))
    return resid/sum_weights

inp = Input((10,))
true = Input((100,))
weights = Input((100,))
x = Dense(256)(inp)
pred = Dense(100)(x)

model = Model([inp,true,weights], pred)
model.add_loss(custom_loss(true, pred, weights))
model.compile('adam', loss=None)

model.fit([X,y,W], y=None, epochs=3)
Run Code Online (Sandbox Code Playgroud)

使用时,add_loss您应该将损失涉及的所有张量作为输入层传递,并将它们传递到损失内部进行计算。

在推理时,您可以像往常一样计算预测,只需删除真实值和权重作为输入:

final_model = Model(model.input[0], model.output)
final_model.predict(X)
Run Code Online (Sandbox Code Playgroud)