【问题标题】:Custom loss w weight arrays of batch size in tensorflow/kerastensorflow / keras中批量大小的自定义损失w权重数组
【发布时间】:2021-03-05 13:25:10
【问题描述】:

我正在创建一个自定义损失函数,它是一个 MAE(y_true, y_pred),由两个数组加权 a 和 b,其中所有四个数组的大小相同(10000 个样本/时间步长)。

def custom_loss(y_true, y_pred, a, b):
        mae = K.abs(y_true - y_pred)
        loss = mae * a * b
        return loss

问题:如何将 ab 输入到函数中? 两者都应该像 y_true 和 y_pred 一样被拆分和洗牌。

到目前为止,我使用的 LSTM 是在 X 形状的数据(样本 x 时间步长 x 变量)上训练的。在这里,我尝试了 tf 的 add_loss 函数来完成这项工作,当进一步传递 ab 时,由于数据形状不同而导致错误输入层。

#LSTM
input_layer = Input(shape=input_shape)
in = LSTM(20, activation='relu', return_sequences=True)(input_layer)
out = LSTM(1, activation='linear', return_sequences=False)(in)

layer_a = Input(shape=(10000))
layer_b = Input(shape=(10000))

model = Model(inputs = [input_layer, layer_a, layer_b], outputs = out)  
model.add_loss(custom_loss(input_layer, out, layer_a, layer_b))
model.compile(loss=None, optimizer=Adam(0.01))

# X=data of shape 20 variables x 10000 timesteps, y, a, b = data of shape 10000 timesteps
model.fit(x=[X, a, b], y=y, batch_size=1, shuffle=True)

我该如何正确地做到这一点?

【问题讨论】:

  • X 是 2D 还是 3D? (我错过了)
  • 3d(样本 x 时间步长 x 变量)

标签: python tensorflow keras loss


【解决方案1】:

正如您所介绍的,您必须使用add_loss。请记住将所有变量(正确格式的真值、预测值和额外张量)传递给您的损失。

n_sample = 100
timesteps = 30
features = 5

X = np.random.uniform(0,1, (n_sample,timesteps,features))
y = np.random.uniform(0,1, n_sample)
a = np.random.uniform(0,1, n_sample)
b = np.random.uniform(0,1, n_sample)

def custom_loss(y_true, y_pred, a, b):
    mae = K.abs(y_true - y_pred)
    loss = mae * a * b
    return loss


input_layer = Input(shape=(timesteps, features))
x = LSTM(20, activation='relu', return_sequences=True)(input_layer)
out = LSTM(1, activation='linear')(x)

layer_a = Input(shape=(1,))
layer_b = Input(shape=(1,))
target = Input(shape=(1,))

model = Model(inputs = [target, input_layer, layer_a, layer_b], outputs = out)  
model.add_loss(custom_loss(target, out, layer_a, layer_b))
model.compile(loss=None, optimizer=Adam(0.01))

model.fit(x=[y, X, a, b], y=None, shuffle=True, epochs=3)

在推理模式下使用模型(删除 y 作为输入,如果不需要,删除 a 和 b):

final_model = Model(model.inputs[1], model.output)
final_model.predict(X)

【讨论】:

  • 这个解决方案有效,非常感谢@Marco!
【解决方案2】:

如果您只需要 ab 来计算损失函数,那么我会为您的自定义损失函数编写一个包装器,并传递一个元组 (y,a,b) 作为您的标签。

类似的东西:

n_sample = 100
timesteps = 30
features = 5

X = np.random.uniform(0,1, (n_sample,timesteps,features))
y = np.random.uniform(0,1, n_sample)
a = np.random.uniform(0,1, n_sample)
b = np.random.uniform(0,1, n_sample)

def custom_loss_wrapper(y_true, y_pred):
    def custom_loss(y_true, y_pred, a, b):
        mae = K.abs(y_true - y_pred)
        loss = mae * a * b
        return loss
    return custom_loss(y_true[0], y_pred, y_true[1], y_true[2])


input_layer = Input(shape=(timesteps, features))
x = LSTM(20, activation='relu', return_sequences=True)(input_layer)
out = LSTM(1, activation='linear')(x)

model = Model(inputs =input_layer, outputs = out)  
model.compile(loss=custom_loss_wrapper, optimizer=Adam(0.01))

model.fit(x=X, y=(y,a,b), shuffle=True, epochs=3)

它简化了网络架构,并在推理时删除了不必要的layer_alayer_b

【讨论】:

  • 认为 wrapper 对我来说是一个又好又快的解决方案。但是,由于某种原因,无法读取 y 数据 (y,a,b)。尝试索引 y_true[1] 会产生 ValueError: slice index 1 of dimension 0 out of bounds。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-28
  • 2017-12-29
  • 2021-07-23
  • 2019-06-25
  • 1970-01-01
  • 2020-10-05
  • 2019-06-24
相关资源
最近更新 更多