损失函数在 Tensorflow 中如何工作?它们是如何从批次中计算出来的?
How do loss functions work in Tensorflow? How are they computed from the batches?
我在 tensorflow 方面有很多实践经验,最近我一直在尝试实现自定义损失函数。由于我一直在努力解决这个问题,所以我尝试实现一个简单的平均绝对误差 (MAE) 损失。这是我的功能:
@tf.function
def my_mae(y_true, y_pred):
return tf.reduce_mean(tf.abs(tf.subtract(y_true, y_pred)), axis=-1)
编译适配
现在,这对我来说看起来很准确,但后来我使用以下参数编译我的模型:
model.compile(loss=my_mae,
optimizer='adam',
metrics=['mae', 'mse'])
然后我从 model.fit
开始训练。问题是在 fit 函数的日志中我可以看到我的 MAE 和 MAE 指标有不同的值:
Epoch 1/100
483/483 [==============================] - 1s 3ms/step - loss: 3.7004 - mae: 0.7226 - mse: 0.8044 - val_loss: 3.2607 - val_mae: 0.5098 - val_mse: 0.4458
Epoch 2/100
483/483 [==============================] - 1s 3ms/step - loss: 3.4139 - mae: 0.6550 - mse: 0.6687 - val_loss: 3.0994 - val_mae: 0.4907 - val_mse: 0.4207
我是不是做错了什么? tensorflow 是不是在做一些我不知道的事情?
更多实验
我还尝试将损失除以一些大数,看看发生了什么,就像这个片段:
@tf.function
def my_mae(y_true, y_pred):
return tf.reduce_mean(tf.abs(tf.subtract(y_true, y_pred)), axis=-1) / 1000
但我得到了完全相同的起始损失值:
Epoch 1/100
483/483 [==============================] - 1s 3ms/step - loss: 3.8101 - mae: 0.7587 - mse: 0.8851 - val_loss: 3.3032 - val_mae: 0.5203 - val_mse: 0.4549
Epoch 2/100
483/483 [==============================] - 1s 3ms/step - loss: 3.4606 - mae: 0.6594 - mse: 0.6793 - val_loss: 3.1446 - val_mae: 0.4985 - val_mse: 0.4274
编辑:模型创建代码
def build_model(nhidden=5, nneurons=60, pdropout=.5,
hidden_act='tanh', last_act='linear',
loss='mae', regularizer=None, optimizer='adam',
input_shape=None, weights=True):
# Input: spectra (areas)
x_input = Input(shape=input_shape)
# Hidden layers
hidden = x_input
for i in range(nhidden):
hidden = Dense(nneurons,
activation=hidden_act,
kernel_regularizer=regularizer,
name='dense{}'.format(i))(hidden)
hidden = Dropout(pdropout)(hidden)
# Last layer
outputs = Dense(3, activation=last_act, name='denseout')(hidden)
# Model
model = Model(x_input, outputs)
loss = my_mae
model.compile(loss=my_mae,
optimizer=optimizer,
metrics=['mae', 'mse'])
model.summary()
return model
正如您最终发现的,这里的罪魁祸首是在您的模型中使用了 regularizer:
hidden = Dense(nneurons,
activation=hidden_act,
kernel_regularizer=regularizer, # <<<<<<<<<<
name='dense{}'.format(i))(hidden)
正则化器添加额外的隐式损失,正则化损失到你的最终损失值,它(通常)独立于传递的特定数据并且完全基于选择的正则化标准.
当您在 Keras 中看到输出时,loss
值指的是 总 损失,它是作为损失函数返回的值计算得出的 加上模型中定义的任何正则化损失。
我在 tensorflow 方面有很多实践经验,最近我一直在尝试实现自定义损失函数。由于我一直在努力解决这个问题,所以我尝试实现一个简单的平均绝对误差 (MAE) 损失。这是我的功能:
@tf.function
def my_mae(y_true, y_pred):
return tf.reduce_mean(tf.abs(tf.subtract(y_true, y_pred)), axis=-1)
编译适配
现在,这对我来说看起来很准确,但后来我使用以下参数编译我的模型:
model.compile(loss=my_mae,
optimizer='adam',
metrics=['mae', 'mse'])
然后我从 model.fit
开始训练。问题是在 fit 函数的日志中我可以看到我的 MAE 和 MAE 指标有不同的值:
Epoch 1/100
483/483 [==============================] - 1s 3ms/step - loss: 3.7004 - mae: 0.7226 - mse: 0.8044 - val_loss: 3.2607 - val_mae: 0.5098 - val_mse: 0.4458
Epoch 2/100
483/483 [==============================] - 1s 3ms/step - loss: 3.4139 - mae: 0.6550 - mse: 0.6687 - val_loss: 3.0994 - val_mae: 0.4907 - val_mse: 0.4207
我是不是做错了什么? tensorflow 是不是在做一些我不知道的事情?
更多实验
我还尝试将损失除以一些大数,看看发生了什么,就像这个片段:
@tf.function
def my_mae(y_true, y_pred):
return tf.reduce_mean(tf.abs(tf.subtract(y_true, y_pred)), axis=-1) / 1000
但我得到了完全相同的起始损失值:
Epoch 1/100
483/483 [==============================] - 1s 3ms/step - loss: 3.8101 - mae: 0.7587 - mse: 0.8851 - val_loss: 3.3032 - val_mae: 0.5203 - val_mse: 0.4549
Epoch 2/100
483/483 [==============================] - 1s 3ms/step - loss: 3.4606 - mae: 0.6594 - mse: 0.6793 - val_loss: 3.1446 - val_mae: 0.4985 - val_mse: 0.4274
编辑:模型创建代码
def build_model(nhidden=5, nneurons=60, pdropout=.5,
hidden_act='tanh', last_act='linear',
loss='mae', regularizer=None, optimizer='adam',
input_shape=None, weights=True):
# Input: spectra (areas)
x_input = Input(shape=input_shape)
# Hidden layers
hidden = x_input
for i in range(nhidden):
hidden = Dense(nneurons,
activation=hidden_act,
kernel_regularizer=regularizer,
name='dense{}'.format(i))(hidden)
hidden = Dropout(pdropout)(hidden)
# Last layer
outputs = Dense(3, activation=last_act, name='denseout')(hidden)
# Model
model = Model(x_input, outputs)
loss = my_mae
model.compile(loss=my_mae,
optimizer=optimizer,
metrics=['mae', 'mse'])
model.summary()
return model
正如您最终发现的,这里的罪魁祸首是在您的模型中使用了 regularizer:
hidden = Dense(nneurons,
activation=hidden_act,
kernel_regularizer=regularizer, # <<<<<<<<<<
name='dense{}'.format(i))(hidden)
正则化器添加额外的隐式损失,正则化损失到你的最终损失值,它(通常)独立于传递的特定数据并且完全基于选择的正则化标准.
当您在 Keras 中看到输出时,loss
值指的是 总 损失,它是作为损失函数返回的值计算得出的 加上模型中定义的任何正则化损失。