Keras 上的自定义损失函数
Custom loss function on Keras
我有一个包含特征矩阵 X
和标签矩阵 y
的数据集,大小为 N,其中每个元素 y_i
属于 [0,1]。我有以下损失函数
&space;=&space;%5Csum_%7Bn=1%7D%5E%7BN%7D%7B%5Clog%5Cleft(&space;1&space;+&space;y_n%5E2&space;%5Ctimes&space;g(X)))%5Cright)%7D)
其中 g(.)
是一个依赖于输入矩阵 X 的函数。
我知道 Keras 自定义损失函数必须采用 customLoss(y_true,y_predicted)
形式,但是,我很难将术语 g(X)
合并到损失函数中,因为这取决于输入矩阵。
对于我数据集中的每个数据点,我的输入都是 X_i = (H, P)
形式,其中这两个参数是矩阵,函数 g 为每个数据点定义为 g(X_i) = H x P
。我可以在损失函数中传递 a = (H, P)
吗,因为这取决于每个示例,或者我是否需要通过连接它们来一次传递所有矩阵?
编辑(根据大牛的回答):
original_model_inputs = keras.layers.Input(shape=X_train.shape[1])
y_true_inputs = keras.layers.Input(shape=y_train.shape[1])
hidden1 = keras.layers.Dense(256, activation="relu")(original_model_inputs)
hidden2 = keras.layers.Dense(128, activation="relu")(hidden1)
output = keras.layers.Dense(K)(hidden2)
def lambdaLoss(x):
yTrue, yPred, alpha = x
return (K.log(yTrue) - K.log(yPred))**2+alpha*yPred
loss = Lambda(lambdaLoss)(y_true_inputs, output, a)
model = Keras.Model(inputs=[original_model_inputs, y_true_inputs], outputs=[output], loss)
def dummyLoss(true, pred):
return pred
model.compile(loss = dummyLoss, optimizer=Adam())
train_model = model.fit([X_train, y_train], None, batch_size = 32,
epochs = 50,
validation_data = ([X_valid, y_valid], None),
callbacks=callbacks)
修复对我的回答的理解:
original_model_inputs = keras.layers.Input(shape=X_train.shape[1:]) #must be a tuple, not an int
y_true_inputs = keras.layers.Input(shape=y_train.shape[1:]) #must be a tuple, not an int
hidden1 = keras.layers.Dense(256, activation="relu")(original_model_inputs)
hidden2 = keras.layers.Dense(128, activation="relu")(hidden1)
output = keras.layers.Dense(K)(hidden2)
你需要做点什么g(X)
,我不知道是什么,但你需要在某个地方做。
是的,你需要一次传递整个张量,你不能做 x_i
和其他一切。
def g(x):
return something
gResults = Lambda(g)(original_model_inputs)
继续我的回答:
def lambdaLoss(x):
yTrue, yPred, G = x
.... #wait.... where is Y_true in your loss formula?
loss = Lambda(lambdaLoss)([y_true_inputs, output, gResults]) #must be a list of inputs including G
您需要一个模型用于训练,另一个用于获得输出,因为我们正在做一个弗兰肯斯坦模型,因为损失不同。
training_model = keras.Model(inputs=[original_model_inputs, y_true_inputs], outputs=loss)
prediction_model = keras.Model(original_model_inputs, output)
只需要编译训练模型:
def dummyLoss(true, pred):
return pred
training_model.compile(loss = dummyLoss, optimizer=Adam())
training_model = model.fit([X_train, y_train], None, batch_size = 32,
epochs = 50,
validation_data = ([X_valid, y_valid], None),
callbacks=callbacks)
使用其他模型获取结果数据:
results = prediction_model.predict(some_x)
看起来像是某种 GAN。我将 (x) 称为“x_input”,两种方法:
方法1)继承自tf.keras.modelclass,自己写(不推荐,不展示)
方法2)继承自tf.keras.losses.Loss class。和 return(自定义)tf.keras.losses.Loss 实例和 tf.keras.layers.Layer 的元组,无非就是充当 shell 来获取和保存 x_input 的副本(x ).然后可以将该层实例添加为模型中的顶层。 (自定义)tf.keraslosses。然后损失实例可以按需访问输入。这种方法在 Tensorflow 的整个生命周期中也有最好的未来支持。
首先,创建自定义层和自定义损失class:
class Acrylic_Layer(tf.keras.layers.Layer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.x_input = None
def build(self, *args, **kwargs):
pass
def call(self, input):
self.x_input = input
return input # Pass input directly through to next layer
class Custom_Loss(tf.keras.losses.Loss):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.input_thief = Acrylic_Layer() # <<< Magic, python is pass by reference!
def __call__(self, y_true, y_pred, sample_weight=None):
x_input = self.input_thief.x_input # <<< x_input pulled from model
二、给模型加层和损失函数
loss_fn = Custom_Loss(*args, **kwargs)
input_thief = loss_fn.input_thief
model = tf.keras.models.Sequential([
input_thief, # <<< transparent layer
Other_layers,
])
model.fit(loss=loss_fn) # <<< loss function
最后,我是正在寻找 ML/python 角色的市场,大声疾呼。
我有一个包含特征矩阵 X
和标签矩阵 y
的数据集,大小为 N,其中每个元素 y_i
属于 [0,1]。我有以下损失函数
其中 g(.)
是一个依赖于输入矩阵 X 的函数。
我知道 Keras 自定义损失函数必须采用 customLoss(y_true,y_predicted)
形式,但是,我很难将术语 g(X)
合并到损失函数中,因为这取决于输入矩阵。
对于我数据集中的每个数据点,我的输入都是 X_i = (H, P)
形式,其中这两个参数是矩阵,函数 g 为每个数据点定义为 g(X_i) = H x P
。我可以在损失函数中传递 a = (H, P)
吗,因为这取决于每个示例,或者我是否需要通过连接它们来一次传递所有矩阵?
编辑(根据大牛的回答):
original_model_inputs = keras.layers.Input(shape=X_train.shape[1])
y_true_inputs = keras.layers.Input(shape=y_train.shape[1])
hidden1 = keras.layers.Dense(256, activation="relu")(original_model_inputs)
hidden2 = keras.layers.Dense(128, activation="relu")(hidden1)
output = keras.layers.Dense(K)(hidden2)
def lambdaLoss(x):
yTrue, yPred, alpha = x
return (K.log(yTrue) - K.log(yPred))**2+alpha*yPred
loss = Lambda(lambdaLoss)(y_true_inputs, output, a)
model = Keras.Model(inputs=[original_model_inputs, y_true_inputs], outputs=[output], loss)
def dummyLoss(true, pred):
return pred
model.compile(loss = dummyLoss, optimizer=Adam())
train_model = model.fit([X_train, y_train], None, batch_size = 32,
epochs = 50,
validation_data = ([X_valid, y_valid], None),
callbacks=callbacks)
修复对我的回答的理解:
original_model_inputs = keras.layers.Input(shape=X_train.shape[1:]) #must be a tuple, not an int
y_true_inputs = keras.layers.Input(shape=y_train.shape[1:]) #must be a tuple, not an int
hidden1 = keras.layers.Dense(256, activation="relu")(original_model_inputs)
hidden2 = keras.layers.Dense(128, activation="relu")(hidden1)
output = keras.layers.Dense(K)(hidden2)
你需要做点什么g(X)
,我不知道是什么,但你需要在某个地方做。
是的,你需要一次传递整个张量,你不能做 x_i
和其他一切。
def g(x):
return something
gResults = Lambda(g)(original_model_inputs)
继续我的回答:
def lambdaLoss(x):
yTrue, yPred, G = x
.... #wait.... where is Y_true in your loss formula?
loss = Lambda(lambdaLoss)([y_true_inputs, output, gResults]) #must be a list of inputs including G
您需要一个模型用于训练,另一个用于获得输出,因为我们正在做一个弗兰肯斯坦模型,因为损失不同。
training_model = keras.Model(inputs=[original_model_inputs, y_true_inputs], outputs=loss)
prediction_model = keras.Model(original_model_inputs, output)
只需要编译训练模型:
def dummyLoss(true, pred):
return pred
training_model.compile(loss = dummyLoss, optimizer=Adam())
training_model = model.fit([X_train, y_train], None, batch_size = 32,
epochs = 50,
validation_data = ([X_valid, y_valid], None),
callbacks=callbacks)
使用其他模型获取结果数据:
results = prediction_model.predict(some_x)
看起来像是某种 GAN。我将 (x) 称为“x_input”,两种方法:
方法1)继承自tf.keras.modelclass,自己写(不推荐,不展示)
方法2)继承自tf.keras.losses.Loss class。和 return(自定义)tf.keras.losses.Loss 实例和 tf.keras.layers.Layer 的元组,无非就是充当 shell 来获取和保存 x_input 的副本(x ).然后可以将该层实例添加为模型中的顶层。 (自定义)tf.keraslosses。然后损失实例可以按需访问输入。这种方法在 Tensorflow 的整个生命周期中也有最好的未来支持。
首先,创建自定义层和自定义损失class:
class Acrylic_Layer(tf.keras.layers.Layer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.x_input = None
def build(self, *args, **kwargs):
pass
def call(self, input):
self.x_input = input
return input # Pass input directly through to next layer
class Custom_Loss(tf.keras.losses.Loss):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.input_thief = Acrylic_Layer() # <<< Magic, python is pass by reference!
def __call__(self, y_true, y_pred, sample_weight=None):
x_input = self.input_thief.x_input # <<< x_input pulled from model
二、给模型加层和损失函数
loss_fn = Custom_Loss(*args, **kwargs)
input_thief = loss_fn.input_thief
model = tf.keras.models.Sequential([
input_thief, # <<< transparent layer
Other_layers,
])
model.fit(loss=loss_fn) # <<< loss function
最后,我是正在寻找 ML/python 角色的市场,大声疾呼。