Keras中的自定义加权损失函数用于称量每个元素

时间:2018-01-03 17:54:21

标签: python tensorflow keras loss-function

我正在尝试创建一个简单的加权损失函数。

说,我的输入尺寸为100 * 5,输出尺寸也为100 * 5.我也有一个相同尺寸的重量矩阵。

如下所示:

import numpy as np
train_X = np.random.randn(100, 5)
train_Y = np.random.randn(100, 5)*0.01 + train_X

weights = np.random.randn(*train_X.shape)

定义自定义丢失功能

def custom_loss_1(y_true, y_pred):
    return K.mean(K.abs(y_true-y_pred)*weights)

定义模型

from keras.layers import Dense, Input
from keras import Model
import keras.backend as K

input_layer = Input(shape=(5,))
out = Dense(5)(input_layer)
model = Model(input_layer, out)

使用现有指标进行测试可以正常运行

model.compile('adam','mean_absolute_error')
model.fit(train_X, train_Y, epochs=1)

使用我们的自定义丢失功能进行测试不起作用

model.compile('adam',custom_loss_1)
model.fit(train_X, train_Y, epochs=10)

它提供以下堆栈跟踪:

InvalidArgumentError (see above for traceback): Incompatible shapes: [32,5] vs. [100,5]
 [[Node: loss_9/dense_8_loss/mul = Mul[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](loss_9/dense_8_loss/Abs, loss_9/dense_8_loss/mul/y)]]

32号来自哪里?

使用权重作为Keras张量测试损失函数

def custom_loss_2(y_true, y_pred):
    return K.mean(K.abs(y_true-y_pred)*K.ones_like(y_true))

这个功能似乎可以完成这项工作。因此,可能表明作为权重矩阵的Keras张量可以起作用。所以,我创建了另一个版本的损失函数。

损失函数尝试3

from functools import partial

def custom_loss_3(y_true, y_pred, weights):
    return K.mean(K.abs(y_true-y_pred)*K.variable(weights, dtype=y_true.dtype))

cl3 = partial(custom_loss_3, weights=weights)  

使用cl3拟合数据会产生与上述相同的错误。

InvalidArgumentError (see above for traceback): Incompatible shapes: [32,5] vs. [100,5]
     [[Node: loss_11/dense_8_loss/mul = Mul[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](loss_11/dense_8_loss/Abs, loss_11/dense_8_loss/Variable/read)]]

我想知道我错过了什么!我本可以在Keras中使用sample_weight的概念;但后来我不得不重塑我的输入到3d矢量。

我认为这种自定义丢失函数应该是微不足道的。

1 个答案:

答案 0 :(得分:8)

model.fit中,默认情况下批量大小为32,即此数字的来源。以下是发生的事情:

  • custom_loss_1中,张量K.abs(y_true-y_pred)的形状为(batch_size=32, 5),而numpy数组weights的形状为(100, 5)。这是一个无效的乘法,因为维度不同意,广播也无法应用。

  • custom_loss_2这个问题不存在,因为您将2个张量乘以相同的形状(batch_size=32, 5)

  • custom_loss_3中问题与custom_loss_1中的问题相同,因为将weights转换为Keras变量并不会改变其形状。

    < / LI>

更新:您似乎希望为每个训练样本中的每个元素赋予不同的权重,因此weights数组的形状(100, 5)确实应该为import numpy as np from keras.layers import Dense, Input from keras import Model import keras.backend as K from functools import partial def custom_loss_4(y_true, y_pred, weights): return K.mean(K.abs(y_true - y_pred) * weights) train_X = np.random.randn(100, 5) train_Y = np.random.randn(100, 5) * 0.01 + train_X weights = np.random.randn(*train_X.shape) input_layer = Input(shape=(5,)) weights_tensor = Input(shape=(5,)) out = Dense(5)(input_layer) cl4 = partial(custom_loss_4, weights=weights_tensor) model = Model([input_layer, weights_tensor], out) model.compile('adam', cl4) model.fit(x=[train_X, weights], y=train_Y, epochs=10) 。 在这种情况下,我会输入您的权重&#39;将数组放入模型中,然后在损失函数中使用此张量:

CREATE OR REPLACE FUNCTION update_ts()
  RETURNS TRIGGER AS
$update_b$

BEGIN
update "B" set import_ts=now() where a_id=NEW.id;
RETURN NULL;
END; 
$update_b$
  LANGUAGE plpgsql;

CREATE TRIGGER update_b
  AFTER UPDATE ON "A"
  FOR EACH ROW
  EXECUTE PROCEDURE update_ts();