ValueError: bad input shape (2, 256, 3) when trying to compute ROC curve

ValueError: bad input shape (2, 256, 3) when trying to compute ROC curve

首先,我是 python 的新手。尝试构建 ROC 曲线时,此代码行出现错误:

fpr_keras, tpr_keras, thresholds_keras = roc_curve(Y_test.argmax(axis=1), decoded_imgs.argmax(axis=1))

错误:

ValueError: bad input shape (2, 256, 3)

当我在重塑后尝试塑形时,出现第二个错误:

TypeError: 'tuple' object is not callable

我关注了这个link, but I don't understand what should i do, I'm stacking on this problem. Can somebody edit my code? This is what I'm trying to do: link2

import keras
import numpy as np
from keras.datasets import mnist
from get_dataset import get_dataset
from stack import keras_model

X_train, X_test, Y_train, Y_test = get_dataset()

from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, Dense
from keras.models import Model

input_img = Input(shape=(256, 256, 3))

x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)

x = Conv2D(64, (3, 3), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='rmsprop', loss='mae',metrics=['mse', 'accuracy'])

from keras.callbacks import ModelCheckpoint, TensorBoard
checkpoints = []

from keras.preprocessing.image import ImageDataGenerator

generated_data = ImageDataGenerator(featurewise_center=False, samplewise_center=False, featurewise_std_normalization=False, samplewise_std_normalization=False, zca_whitening=False, rotation_range=0,  width_shift_range=0.1, height_shift_range=0.1, horizontal_flip = True, vertical_flip = False)
generated_data.fit(X_train)
epochs = 1
batch_size = 5

autoencoder.fit_generator(generated_data.flow(X_train, X_train, batch_size=batch_size), steps_per_epoch=X_train.shape[0]/batch_size, epochs=epochs, validation_data=(X_test, X_test), callbacks=[TensorBoard(log_dir='/tmp/autoencoder')])

autoencoder.fit(X_train, X_train, batch_size=batch_size, epochs=epochs, validation_data=(X_test, X_test), shuffle=True, callbacks=[TensorBoard(log_dir='/tmp/auti')])

decoded_imgs = autoencoder.predict(X_test)

from sklearn.metrics import roc_curve
#2 256  3
print(decoded_imgs.argmax(axis=1))
print(decoded_imgs.argmax(axis=1).reshape(1,3))

fpr_keras, tpr_keras, thresholds_keras = roc_curve(Y_test.argmax(axis=1), decoded_imgs.argmax(axis=1))

ValueError: bad input shape (2, 256, 3)    

将行编辑为:

fpr_keras, tpr_keras, thresholds_keras = roc_curve(Y_test.argmax(axis=1), decoded_imgs.reshape(6,256,1)) 

我收到这个错误:

ValueError: Found input variables with inconsistent numbers of samples: [2, 4]

您对 ROC 曲线和自动编码器的基础知识听起来有点困惑...

引用自 roc_curve 的 scikit-learn documentation

roc_curve (y_true, y_score, pos_label=None, sample_weight=None, drop_intermediate=True)

Parameters:

y_true : array, shape = [n_samples]

True binary labels. If labels are not either {-1, 1} or {0, 1}, then pos_label should be explicitly given.

y_score : array, shape = [n_samples]

Target scores, can either be probability estimates of the positive class, confidence values, or non-thresholded measure of decisions (as returned by “decision_function” on some classifiers).

换句话说,roc_curve 的两个输入都应该是简单的一维标量数组,第一个包含真实 classes,第二个包含预测分数。

现在,尽管您没有展示您自己的数据样本,而且我不怀疑您的 Y_test.argmax(axis=1) 可能符合此规范,但您的 decoded_imgs.argmax(axis=1)(无论你如何重塑它)不会。为什么?由于自动编码器的本质。

与随机森林 classifier 等模型形成鲜明对比的是,您还尝试在代码的一部分(现已删除)中使用,自动编码器不是 classifier :它们的功能是重建输入的(去噪、压缩等)版本,不是来产生class预测(见漂亮的小tutorial 在 Keras 博客中快速定位)。在你的情况下,这意味着你的 decoded_imgs 实际上是转换后的图像(或图像数据,在任何情况下),而不是 roc_curve 所需的 class 分数,因此错误(从技术上讲,这实际上是由于 decoded_imgs 不是一维数组,但希望你明白了)。

即使您在这里使用了 classifier 而不是自动编码器,您也会遇到另一个问题:ROC 曲线用于 binary classification 任务,而不是 multi-class 任务,比如 MNIST(实际上也有一些方法将它们应用于 multi-class 数据,但它们并未广泛使用 AFAIK)。的确,从表面上看,scikit-learn 的 roc_curve 即使在多 class 设置中也能正常工作:

import numpy as np
from sklearn import metrics

y = np.array([0, 1, 1, 2, 2]) # 3-class problem
scores = np.array([0.05, 0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = metrics.roc_curve(y, scores, pos_label=2)  # works OK, no error

但实际上发生这种情况只是因为我们明确定义了 pos_label=2,因此,在幕后,scikit-learn 将 2 以外的所有标签视为负标签,随后将其余计算就好像我们的问题是二进制问题一样(即 class 2 与所有其他 classes)。

对于您的情况 (MNIST),您应该问自己以下问题:10-class MNIST 数据集中的 "positive" 到底是什么? 这个问题有意义吗?希望您能够说服自己答案并不简单,就像二进制 (0/1) 的情况一样。


总结:此处没有 coding 错误需要补救;你的问题的根本原因只是你尝试了一些毫无意义和无效的事情,因为自动编码器不会产生 class 预测,因此它们的输出不能用于计算 ROC 曲线。我建议先对相关概念和概念有充分的了解,然后再进行应用...