python - Keras weighted_metrics 在计算中不包括样本权重

标签 python tensorflow keras deep-learning loss-function

<分区>

我正在使用形状为 (400,22) 的二维张量作为输入和输出来训练 CNN 模型。我将 categorical_crossentropy 用作损失和指标。然而,损失/指标值非常不同。

我的模型有点像这样:

<强>1。使用样本权重,并在 model.compile 中使用 metrics= 传递指标。

# Imports
import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras.optimizers import *
from tensorflow.keras.regularizers import *
from tensorflow.keras import *
import numpy as np

# Build the model
X_input = Input(shape=(400,22))
X = Conv1D(filters=32, kernel_size=2, activation='elu', 
           kernel_regularizer=L2(1e-4), bias_regularizer=L2(1e-4), 
           padding='same')(X_input)
X = Dropout(0.2)(X)
X = Conv1D(filters=32, kernel_size=2, activation='elu', 
           kernel_regularizer=L2(1e-4), bias_regularizer=L2(1e-4), 
           padding='same')(X)
X = Dropout(0.2)(X)
y = Conv1D(filters=22, kernel_size=1, activation='softmax', 
           kernel_regularizer=L2(1e-4), bias_regularizer=L2(1e-4), 
           padding='same')(X)
model = Model(X_input, y, name='mymodel')


# Compile and train the model (with metrics=[])
model.compile(optimizer=Adam(1e-3),
              loss=tf.keras.losses.categorical_crossentropy,
               metrics=[tf.keras.losses.categorical_crossentropy])
Xtrain = np.random.rand(20,400,22)
ytrain = np.random.rand(20,400,22)
np.random.seed(0)
sample_weight = np.random.choice([0.01, 0.1, 1], size=20)
history = model.fit(x=Xtrain, y=ytrain, sample_weight=sample_weight, epochs=4)
Epoch 1/4
1/1 [==============================] - 0s 824us/step - loss: 10.2952 - categorical_crossentropy: 34.9296
Epoch 2/4
1/1 [==============================] - 0s 785us/step - loss: 10.2538 - categorical_crossentropy: 34.7858
Epoch 3/4
1/1 [==============================] - 0s 772us/step - loss: 10.2181 - categorical_crossentropy: 34.6719
Epoch 4/4
1/1 [==============================] - 0s 766us/step - loss: 10.1903 - categorical_crossentropy: 34.5797

从结果可以看出,Keras 在计算指标时没有使用样本权重,因此它大于损失。如果我们将样本权重更改为 ones,我们将得到以下结果:

<强>2。样本权重 = ones,在 `model.compile.

中使用 metrics= 传递指标
# Compile and train the model
model.compile(optimizer=Adam(1e-3),
              loss=tf.keras.losses.categorical_crossentropy,
               metrics=[tf.keras.losses.categorical_crossentropy])
Xtrain = np.random.rand(20,400,22)
ytrain = np.random.rand(20,400,22)
np.random.seed(0)
sample_weight = np.ones((20,))
history = model.fit(x=Xtrain, y=ytrain, sample_weight=sample_weight, epochs=4)
Epoch 1/4
1/1 [==============================] - 0s 789us/step - loss: 35.2659 - categorical_crossentropy: 35.2573
Epoch 2/4
1/1 [==============================] - 0s 792us/step - loss: 35.0647 - categorical_crossentropy: 35.0562
Epoch 3/4
1/1 [==============================] - 0s 778us/step - loss: 34.9301 - categorical_crossentropy: 34.9216
Epoch 4/4
1/1 [==============================] - 0s 736us/step - loss: 34.8076 - categorical_crossentropy: 34.7991

现在指标和损失与 ones 的样本权重非常接近。据我所知,由于丢失、正则化的影响以及指标是在每个时期结束时计算的事实,损失略大于指标,而损失是训练中各批处理的平均值。

如何获取包含样本权重的指标?

<强>3。更新:使用样本权重,并在 model.compile 中使用 weighted_metrics= 传递指标。

有人建议我在 model.compile 中使用 weighted_metrics=[...] 而不是 metrics=[...] .然而,Keras 仍然没有将样本权重纳入指标的评估。

# Compile and train the model
model.compile(optimizer=Adam(1e-3),
              loss=tf.keras.losses.categorical_crossentropy,
               weighted_metrics=[tf.keras.losses.categorical_crossentropy])
Xtrain = np.random.rand(20,400,22)
ytrain = np.random.rand(20,400,22)
np.random.seed(0)
sample_weight = np.random.choice([0.01, 0.1, 1], size=20)
history = model.fit(x=Xtrain, y=ytrain, sample_weight=sample_weight, epochs=4)
Epoch 1/4
1/1 [==============================] - 0s 764us/step - loss: 10.2581 - categorical_crossentropy: 34.9224
Epoch 2/4
1/1 [==============================] - 0s 739us/step - loss: 10.2251 - categorical_crossentropy: 34.8100
Epoch 3/4
1/1 [==============================] - 0s 755us/step - loss: 10.1854 - categorical_crossentropy: 34.6747
Epoch 4/4
1/1 [==============================] - 0s 746us/step - loss: 10.1631 - categorical_crossentropy: 34.5990

如何确保样本权重在指标中得到评估?

最佳答案

Keras 不会在指标评估中自动包含样本权重。这就是损失和指标之间存在巨大差异的原因。

如果您希望在评估指标时包含样本权重,请将它们作为 weighted_metrics 而不是指标传递。

model.compile(optimizer=Adam(1e-3), 
              loss=tf.keras.losses.categorical_crossentropy,
              weighted_metrics=[tf.keras.losses.categorical_crossentropy]))

关于python - Keras weighted_metrics 在计算中不包括样本权重,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69820462/

相关文章:

python - 如何在迭代时从 json 中删除项目?

python - Tensorflow Inception V3 无法加载计算图

python - 3D 语义分割任务的 Keras 预处理

machine-learning - 带有 Keras 的词级 Seq2Seq

具有负值的 Python timedelta 对象

Microsoft UI 自动化的 Python 绑定(bind)?

python - Python 中接口(interface)和类之间的 UML 聚合

python - Tensorflow:tf.image.resize 仍然没有对齐角吗?

python - RNN 分类器,如何显示权重以了解 neraul 网络如何做出决策

python-3.x - 如何将嵌入式列与 Keras 中的其他输入数据组合