Edd*_*ddy 5 python machine-learning deep-learning keras tensorflow
我正在尝试使用如下所示的自定义损失函数来训练自动编码器。输入 Missing_matrix 是一个由 1 和 0 组成的 nxm 数组,对应于 nxm 特征数组。我需要将 Missing_array 与 y_pred 进行逐个元素相乘,这应该是输入特征的重建,以便我可以屏蔽那些乘以 0 的特征,以忽略它们在成本函数中的贡献。我以前从未编写过自定义损失函数,下面的函数根本不起作用。我曾尝试搜索类似的自定义成本函数,但无法找到一个引入像这样的输入数组的函数。我将不胜感激您的帮助或正确方向的指出。
def custom_loss(missing_array):
def missing_mse(y_true, y_pred):
mse = MeanSquaredError()
y_pred_masked = tf.math.multiply(y_pred, missing_array)
return mse(y_true = y_true, y_pred = y_pred_masked)
return missing_mse
Run Code Online (Sandbox Code Playgroud)
编辑:更进一步
from keras.losses import MeanSquaredError
import tensorflow as tf
def custom_loss(missing_matrix):
def missing_mse(y_true, y_pred):
mse = MeanSquaredError()
y_pred_masked = tf.math.multiply(y_pred, tf.convert_to_tensor(missing_matrix, dtype=tf.float32))
return mse(y_true = y_true, y_pred = y_pred_masked)
return missing_mse
Run Code Online (Sandbox Code Playgroud)
有错误
InvalidArgumentError: Incompatible shapes: [64,1455] vs. [13580,1455]
[[node gradient_tape/missing_mse/BroadcastGradientArgs (defined at <ipython-input-454-b60d74568bf2>:64) ]] [Op:__inference_train_function_25950]
Function call stack:
train_function
Run Code Online (Sandbox Code Playgroud)
64让我觉得这就是批次。我可能需要批量获取 64 个缺失的矩阵?
编辑2:这很有趣!所以我验证了如果我做类似的事情,自定义损失函数将会训练
def train(self, model, X_train):
"""
Model training
"""
#model.fit(X_train, X_train, epochs = 10, batch_size = 64, validation_split = 0.10)
for batch_idx in range(0, len(X_train), 70):
self.batch_start = batch_idx
self.batch_end = batch_idx + 70
model.train_on_batch(X_train[self.batch_start:self.batch_end,:], X_train[self.batch_start:self.batch_end,:])
return model
Run Code Online (Sandbox Code Playgroud)
并修改我的自定义损失
def custom_loss2(self, missing_matrix):
def missing_mse(y_true, y_pred):
mse = MeanSquaredError()
y_pred_masked = tf.math.multiply(y_pred, tf.convert_to_tensor(missing_matrix[self.batch_start:self.batch_end,:], dtype=tf.float32))
return mse(y_true = y_true[self.batch_start:self.batch_end,:], y_pred = y_pred_masked[self.batch_start:self.batch_end,:])
return missing_mse
Run Code Online (Sandbox Code Playgroud)
那么现在我怎样才能获得纪元并打印出验证损失等......?或者更确切地说,更好的方法是什么?今晚我就是这样。晚安!
问题是,y_true和y_pred是批量的,而掩模是一次性通过的。自动将数据分成相等批次的一种简单解决方案是使用model.add_loss().
下面我重现了一个带有自动编码器和自定义掩蔽损失的虚拟示例。掩码作为模型输入传递,这是使其工作所需的简单技巧。
使用也mean_squared_error代替MeanSquaredError.
def missing_mse(y_true, y_pred, missing_array):
y_pred_masked = tf.math.multiply(y_pred, missing_array)
mse = tf.keras.losses.mean_squared_error(y_true = y_true, y_pred = y_pred_masked)
return mse
inp = Input((100,))
x = Dense(20)(inp)
out = Dense(100)(x)
inp_mask = Input((100,))
model = Model([inp, inp_mask], out)
model.add_loss(missing_mse(inp, out, inp_mask))
model.compile('adam', loss=None)
X = np.random.uniform(0,1, (300,100))
mask = np.random.randint(0,2, (300,100))
model.fit(x=[X,mask], y=None, epochs=10, batch_size=64)
# at inference time you can remove the mask input in this way
new_model = Model(model.input[0], model.output)
new_model.predict(X).shape
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2432 次 |
| 最近记录: |