【问题标题】:Tensorflow & Keras: Building Custom Metric for PrecisionTensorflow 和 Keras:为精度构建自定义指标
【发布时间】:2020-12-22 20:16:14
【问题描述】:

我已对 Metric 类进行子分类以创建自定义精度指标。一切看起来都很好;我的意思是没有运行时错误。但是我怀疑当我看到输出中记录的精度分数时出现问题,它总是在每个时期结束时显示相同的分数,例如时期 0.1000 或 0.9000

这是我的代码:


(X_train_10, y_train_10), (X_test_10, y_test_10) = keras.datasets.cifar10.load_data()

X_train_10 = X_train_10 / 255.
X_test_10 = X_test_10 / 255.

class PrecisionMetric(keras.metrics.Metric):
    def __init__(self, name = 'precision', **kwargs):
        super(PrecisionMetric, self).__init__(**kwargs)
        self.tp = self.add_weight('tp', initializer = 'zeros')
        self.fp = self.add_weight('fp', initializer = 'zeros')

    def update_state(self, y_true, y_pred):
        y_true = tf.cast(y_true, tf.bool)
        y_pred = tf.cast(y_pred, tf.bool)        
        true_p = tf.logical_and(tf.equal(y_true, True), tf.equal(y_pred, True))
        false_p = tf.logical_and(tf.equal(y_true, False), tf.equal(y_pred, True))
        self.tp.assign_add(tf.reduce_sum(tf.cast(true_p, self.dtype)))
        self.fp.assign_add(tf.reduce_sum(tf.cast(false_p, self.dtype)))
    def reset_states(self):
        self.tp.assign(0)
        self.fp.assign(0)

    def result(self):
        return self.tp / (self.tp + self.fp)


keras.backend.clear_session()
model = keras.models.Sequential()

model.add(keras.layers.Flatten(input_shape = np.array(X_train_10.shape[1: ])))
for _ in range(2):
    model.add(keras.layers.Dense(50, activation = 'elu', kernel_initializer = 'he_normal'))
model.add(keras.layers.Dense(1, activation = 'sigmoid'))

loss = keras.losses.binary_crossentropy
optimizer = keras.optimizers.SGD()

model.compile(loss = loss, optimizer = optimizer, metrics = [PrecisionMetric()])

# To make it binary classification
y_train_5 = (y_train_10 == 5)
y_test_5 = (y_test_10 == 5)

history = model.fit(X_train_10, y_train_5, epochs = 5)

运行 5 个 epoch 后的输出:

Epoch 1/5
1563/1563 [==============================] - 5s 4ms/step - loss: 0.2921 - precision_metric: 0.1000
Epoch 2/5
1563/1563 [==============================] - 4s 2ms/step - loss: 0.2744 - precision_metric: 0.1000
Epoch 3/5
1563/1563 [==============================] - 3s 2ms/step - loss: 0.2682 - precision_metric: 0.1000
Epoch 4/5
1563/1563 [==============================] - 3s 2ms/step - loss: 0.2651 - precision_metric: 0.1000
Epoch 5/5
1563/1563 [==============================] - 4s 3ms/step - loss: 0.2629 - precision_metric: 0.1000

注意:即使尝试使用更高数量的 epoch,例如 100,仍然输出完全相同的精度,而损失不断缩小/变小。

【问题讨论】:

    标签: tensorflow machine-learning keras deep-learning metrics


    【解决方案1】:

    编辑

    您的实施存在错误。您不应该将y_pred 转换为布尔值。这些是 sigmoid 的输出。你应该这样做

    y_pred = tf.math.greater(y_pred, 0.5)
    

    当您的问题是二进制时(您从 sigmoid 获得输出)。并使其适应多类分类。

    请在result 中检查您是否没有通过以下方式划分 0/0:

        def result(self):
            res =  self.tp / (self.tp + self.fp)
            if tf.math.is_nan(res):
                return 0.0
            else:
                return res
    

    我为第一个错误的答案道歉,尽管我希望它有点教育意义。

    【讨论】:

    • 非常感谢@Proko,不用担心这里的一切都是教育性的,如果不是我,其他人可以从中学习。我修复了代码,确定我完全忘记了那里的 sigmoid 函数;)。此外,我是 StackOverflow 的新手;我删除了我自己的答案。另外,更新 softmax 函数的适配。
    猜你喜欢
    • 1970-01-01
    • 2021-03-26
    • 2018-05-14
    • 2019-07-04
    • 2020-03-07
    • 1970-01-01
    • 2017-11-20
    • 2020-03-04
    • 2017-09-20
    相关资源
    最近更新 更多