语境化
我正在处理图像的多标签分类问题。我正在尝试预测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),这就是为什么我在轴= 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:这些由日志给出的精度和召回率值代表了大小=批处理数据的度量计算?我该如何计算一个时期的指标(作为信息比仅仅计算一个批次更有用?有人可能会说,只是计算所有批次的平均值?当然,这就是我的想法,但我没有我知道该怎么做,因为KERAS对我来说有点像黑匣子,而我不完全是为了跟踪/修改代码的适当部分而在“幕后”发生了什么?
最佳答案
我认为您正在使用tensorflow
后端。实际上,您可以将sklearn.metrics
用于keras
,只需通过sklearn
调用tf.py_func
度量即可,该度量会将python
函数扭曲为tf
函数。
对于Q1,您看到的实际值实际上是度量矢量的平均值。
对于第二季度。它应该是整个时期的平均分数以进行验证。
关于python - 多标签分类:keras自定义指标,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49987631/