python - 多标签分类: keras custom metrics

标签 python tensorflow machine-learning keras

情境化
我正在研究图像的多标签分类问题。我正在尝试预测 39 个标签。换句话说,我试图识别给定图像中存在 39 个特征中的哪一个(可以在一张图像中找到许多特征,这就是我处于多标签分类情况的原因。 数据
我的输入数据是 (X,Y):X 的形状为 (1814,204,204,3),Y 的形状为 (1814,39)。所以基本上 X 是图像集,Y 是与每个图像相关的标签,将用于监督学习过程。

型号
我正在构建一个卷积神经网络来进行预测。对于此任务,我使用 Keras 来创建我的模型。

我做了什么
为了验证我的模型,我需要选择一个指标。然而,Keras 中可用的指标在我的情况下是不敬的,并且不会帮助我验证我的模型,因为我处于多标签分类情况。这就是我决定创建自定义指标的原因。我创建了应用于 Y 和 Y_predict 列的召回率和精度指标。换句话说,我将计算 39 个类别中每个类别的召回率和精确率。这是我的指标代码:

def recall(y_true, y_pred):
    #Recall metric.

    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)),axis=0)
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)),axis=0)
    recall = true_positives / (possible_positives + K.epsilon())
    return recall

def precision(y_true, y_pred):
    #Precision metric.

    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)),axis=0)
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)),axis=1)
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision

我的向量 Y 的形状为 (n,39),这就是我在 axis=0 上进行操作的原因。换句话说,对于每个标签,我正在计算精确度和召回率。

下一步,我通过将这两个指标精确到 keras fit 函数来调用它。换句话说,我使用了这行代码:

model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=[precision,recall])

构建、编译和拟合模型的代码:
这是我用于构建模型并对其进行训练及其结果的代码。 (我没有将数据拆分为训练和验证的代码部分:在 1269 个样本上进行训练,在 545 个样本上进行验证)

# Model: CNN
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(204, 204, 3), padding='same', activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Conv2D(32, (3, 3), activation='relu', padding='same', kernel_constraint=maxnorm(3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.5))
model.add(Dense(39))
model.add(Activation('sigmoid'))
# Compile model
epochs = 5
lrate = 0.001
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=[precision,recall])

# fitting the model 
model.fit(X_train, Y_train, epochs=epochs, batch_size=32,validation_data=(X_valid,Y_valid))

结果

Train on 1269 samples, validate on 545 samples
Epoch 1/5
  96/1269 [=>............................] - ETA: 6:40 - loss: 0.6668 - precision: 0.1031 - recall: 0.2493

问题/问题
问题1:在结果部分的日志中,有精确率和召回率值。我不知道为什么我得到的是真实值而不是值向量。我构建两个指标的方式应该为我提供一个形状为 (1,39) 的精度数组和 (1,39) 的召回率数组,其中应包含每个类别的精度和召回率,但输出仍然只是一个数字?
问题2:这些由日志给出的精度和召回值,它们代表了对size=batch的数据的度量计算?如何计算一个时期的指标(这作为一种信息比仅仅计算一个批处理更有用?有人可能会说,只计算所有批处理的平均值?当然,这就是我正在考虑的,但我没有知道如何做到这一点,因为 KERAS 对我来说有点像一个黑匣子,我不知道“幕后”发生了什么,以便遵循/修改代码的适当部分?

最佳答案

补充一下,Keras 在每个验证批处理结束时计算指标,因此您的召回率和精确度将会产生误导。这就是它们从 Keras 2 中删除的原因。您需要创建一个 Keras 回调,它将传递整个验证数据并计算每个周期结束时的指标(在代码中,这是回调的 on_epoch_end 部分) )。 A simple example of this can be found hereeven simpler here ,尽管代码可能稍微过时了。 Here is a final example (at the bottom edit)他们使用 on_epoch_end 方法附加许多指标。

对于关于向量以浮点形式返回的问题,Keras documentation states that metrics automatically averages vector output

RETURNS: Single tensor value representing the mean of the output array across all datapoints.

我假设这样做是为了方便和简单,因为绝大多数指标需要对结果向量进行平均,但这也许可以由 Keras 团队进行修改。

关于python - 多标签分类: keras custom metrics,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49987631/

相关文章:

python - 从tensorflow 1.x升级到2.0

python - Tkinter 从函数中获取按键事件

Tensorflow - ValueError : Parent directory of trained_variables. ckpt 不存在,无法保存

python - Tensorflow 运行之间的准确性保持相同

python - 带有 LSTM 的 GridSearchCV/RandomizedSearchCV

machine-learning - 梯度下降与随机梯度下降算法

algorithm - 皮质学习实现(Numenta 的 HTM 理论)

python - Firebase .validate 无法按预期使用 $location

python - 如何在 tkinter 中向所有 4 个方向加速和减速物体?

python - 从 Colaboratory 删除文件而不移动到废纸篓