AttributeError: 'Model' 对象没有属性 'predict_classes' [英] AttributeError: 'Model' object has no attribute 'predict_classes'

查看:72
本文介绍了AttributeError: 'Model' 对象没有属性 'predict_classes'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用预训练和微调的 DL 模型预测验证数据.该代码遵循 Keras 博客中关于使用非常少的数据构建图像分类模型"的示例.代码如下:

将 numpy 导入为 np从 keras.preprocessing.image 导入 ImageDataGenerator导入 matplotlib.pyplot 作为 plt从 keras.models 导入顺序从 keras.models 导入模型从 keras.layers 导入扁平化,密集从 sklearn.metrics 导入分类报告,混淆矩阵从 sklearn.metrics 导入 roc_auc_score导入迭代工具从 keras.optimizers 导入 SGD从 sklearn.metrics 导入 roc_curve, auc从 keras 导入应用程序从 keras 导入后端为 KK.set_image_dim_ordering('tf')# 绘制混淆矩阵def plot_confusion_matrix(cm, classes,normalize=False, #if true 混淆矩阵中的所有值都在 0 和 1 之间title='混淆矩阵',cmap=plt.cm.Blues):"""此函数打印并绘制混淆矩阵.可以通过设置normalize=True"来应用规范化."""plt.imshow(cm,interpolation='nearest',cmap=cmap)plt.title(标题)plt.colorbar()tick_marks = np.arange(len(classes))plt.xticks(tick_marks,类,旋转 = 45)plt.yticks(tick_marks,类)如果标准化:cm = cm.astype('float')/cm.sum(axis=1)[:, np.newaxis]print("标准化混淆矩阵")别的:print('混淆矩阵,没有归一化')打印(厘米)阈值 = cm.max()/2.对于 i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):plt.text(j, i, cm[i, j],水平对齐=中心",color="white" 如果 cm[i, j] >脱粒其他黑色")plt.tight_layout()plt.ylabel('真实标签')plt.xlabel('预测标签')#绘图数据def generate_results(validation_labels, y_pred):fpr, tpr, _ = roc_curve(validation_labels, y_pred) ##(这个实现仅限于二分类任务)roc_auc = auc(fpr, tpr)plt.figure()plt.plot(fpr, tpr, label='ROC 曲线 (面积 = %0.2f)' % roc_auc)plt.plot([0, 1], [0, 1], 'k--')plt.xlim([0.0, 1.05])plt.ylim([0.0, 1.05])plt.xlabel('误报率 (FPR)')plt.ylabel('真阳性率 (TPR)')plt.title('接受者操作特征(ROC)曲线')plt.show()打印('曲线下面积(AUC):%f'%roc_auc)img_width, img_height = 100,100top_model_weights_path = 'modela.h5'train_data_dir = 'data4/train'validation_data_dir = 'data4/validation'nb_train_samples = 20nb_validation_samples = 20时代 = 50批量大小 = 10def save_bottleneck_features():datagen = ImageDataGenerator(rescale=1./255)模型 = Applications.VGG16(include_top=False, weights='imagenet', input_shape=(100,100,3))生成器 = datagen.flow_from_directory(train_data_dir,target_size=(img_width, img_height),批量大小=批量大小,class_mode='二进制',洗牌=假)bottleneck_features_train = model.predict_generator(生成器,nb_train_samples//批量大小)np.save(open('bottleneck_features_train', 'wb'),bottleneck_features_train)生成器 = datagen.flow_from_directory(验证数据目录,target_size=(img_width, img_height),批量大小=批量大小,class_mode='二进制',洗牌=假)bottleneck_features_validation = model.predict_generator(生成器,nb_validation_samples//批量大小)np.save(open('bottleneck_features_validation', 'wb'),bottleneck_features_validation)def train_top_model():train_data = np.load(open('bottleneck_features_train', 'rb'))train_labels = np.array([0] * (nb_train_samples//2) + [1] * (nb_train_samples//2))验证数据 = np.load(open('bottleneck_features_validation', 'rb'))validation_labels = np.array([0] * (nb_validation_samples//2) + [1] * (nb_validation_samples//2))模型 = 顺序()model.add(Flatten(input_shape=train_data.shape[1:]))模型.添加(密集(512,激活='relu'))model.add(Dense(1, activation='sigmoid'))sgd = SGD(lr=1e-3, 衰减=0.00, 动量=0.99, nesterov=False)模型编译(优化器=SGD,loss='binary_crossentropy', metrics=['accuracy'])模型.fit(train_data,train_labels,时代=时代,批量大小=批量大小,验证数据=(验证数据,验证标签))model.save_weights(top_model_weights_path)print('预测测试数据')y_pred = model.predict_classes(validation_data)打印(y_pred.shape)print('生成结果')生成结果(validation_labels[:,], y_pred[:,])print('Generating the ROC_AUC_Scores') #根据预测分数计算曲线下面积(AUC)print(roc_auc_score(validation_labels,y_pred)) #这个实现仅限于标签指标格式的二元分类任务或多标签分类任务.target_names = ['class 0(Normal)', 'class 1(异常)']打印(classification_report(validation_labels,y_pred,target_names=target_names))打印(混淆矩阵(验证标签,y_pred))cnf_matrix = (confusion_matrix(validation_labels,y_pred))np.set_printoptions(precision=2)plt.figure()# 绘制非归一化混淆矩阵plot_confusion_matrix(cnf_matrix,类=目标名称,标题='混淆矩阵')plt.show()save_bottleneck_features()train_top_model()# 模型权重文件的路径.weights_path = '../keras/examples/vgg16_weights.h5'top_model_weights_path = 'modela.h5'# 我们图像的尺寸.img_width, img_height = 100, 100train_data_dir = 'data4/train'validation_data_dir = 'data4/validation'nb_train_samples = 20nb_validation_samples = 20时代 = 50批量大小 = 10# 构建 VGG16 网络base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(100,100,3))打印('模型加载.')train_datagen = ImageDataGenerator(重新缩放=1./255,剪切范围=0.2,zoom_range=0.2,水平翻转=真)test_datagen = ImageDataGenerator(rescale=1./255)train_generator = train_datagen.flow_from_directory(train_data_dir,target_size=(img_height, img_width),批量大小=批量大小,class_mode='二进制')验证生成器 = test_datagen.flow_from_directory(验证数据目录,target_size=(img_height, img_width),批量大小=批量大小,class_mode='二进制')top_model = 顺序()top_model.add(Flatten(input_shape=base_model.output_shape[1:]))top_model.add(Dense(512, activation='relu'))top_model.add(Dense(1, activation='softmax'))top_model.load_weights(top_model_weights_path)模型=模型(输入=base_model.input,输出=top_model(base_model.output))# 设置前 15 层(直到最后一个 conv 块)# 不可训练(权重不会更新)for layer in model.layers[:15]: #up 到最后一个卷积块之前的层layer.trainable = 假模型摘要()# 微调模型model.compile(loss='binary_crossentropy',optimizer=SGD(lr=1e-4,momentum=0.99),metrics=['accuracy'])model.fit_generator(train_generator,step_per_epoch=nb_train_samples//批量大小,时代=时代,验证数据=验证生成器,validation_steps=nb_validation_samples//批量大小,详细=1)model.save_weights(top_model_weights_path)bottleneck_features_validation = model.predict_generator(validation_generator, nb_validation_samples//batch_size)np.save(open('bottleneck_features_validation','wb'),bottleneck_features_validation)验证数据 = np.load(open('bottleneck_features_validation', 'rb'))y_pred1 = model.predict_classes(validation_data)

问题在于预训练模型正在接受数据训练并完美地预测类别并给出混淆矩阵.当我继续微调模型时,我发现 model.predict_classes 不起作用.这是错误:

<块引用>

文件C:/Users/rajaramans2/codes/untitled12.py",第220行,在<module>y_pred1 = model.predict_classes(validation_data)AttributeError: 'Model' 对象没有属性 'predict_classes'

我很困惑,因为 model.predict_classes 与预训练模型配合得很好,但在微调阶段不行.验证数据的大小为 (20,1) 和 float32 类型.任何帮助,将不胜感激.

解决方案

predict_classes 方法仅适用于 Sequential 类(这是您的第一个模型的类) 但不适用于 Model 类(您的第二个模型的类).

使用 Model 类,您可以使用 predict 方法,该方法将为您提供概率向量,然后获取该向量的 argmax(使用 np.argmax(y_pred1,axis=1)).

I'm trying to predict on the validation data with pre-trained and fine-tuned DL models. The code follows the example available in the Keras blog on "building image classification models using very little data". Here is the code:

import numpy as np
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.models import Model
from keras.layers import Flatten, Dense
from sklearn.metrics import classification_report,confusion_matrix
from sklearn.metrics import roc_auc_score
import itertools
from keras.optimizers import SGD
from sklearn.metrics import roc_curve, auc
from keras import applications
from keras import backend as K
K.set_image_dim_ordering('tf')

# Plotting the confusion matrix
def plot_confusion_matrix(cm, classes,
                          normalize=False, #if true all values in confusion matrix is between 0 and 1
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')

    print(cm)
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, cm[i, j],
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")
    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

#plot data
def generate_results(validation_labels, y_pred):
    fpr, tpr, _ = roc_curve(validation_labels, y_pred) ##(this implementation is restricted to a binary classification task)
    roc_auc = auc(fpr, tpr)
    plt.figure()
    plt.plot(fpr, tpr, label='ROC curve (area = %0.2f)' % roc_auc)
    plt.plot([0, 1], [0, 1], 'k--')
    plt.xlim([0.0, 1.05])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate (FPR)')
    plt.ylabel('True Positive Rate (TPR)')
    plt.title('Receiver operating characteristic (ROC) curve')
    plt.show()
    print('Area Under the Curve (AUC): %f' % roc_auc)

img_width, img_height = 100,100
top_model_weights_path = 'modela.h5'
train_data_dir = 'data4/train'
validation_data_dir = 'data4/validation'
nb_train_samples = 20
nb_validation_samples = 20
epochs = 50
batch_size = 10
def save_bottleneck_features():
   datagen = ImageDataGenerator(rescale=1. / 255)
   model = applications.VGG16(include_top=False, weights='imagenet', input_shape=(100,100,3))
   generator = datagen.flow_from_directory(
               train_data_dir,
               target_size=(img_width, img_height),
               batch_size=batch_size,
               class_mode='binary',
               shuffle=False)
   bottleneck_features_train = model.predict_generator(
               generator, nb_train_samples // batch_size)
   np.save(open('bottleneck_features_train', 'wb'),bottleneck_features_train)

   generator = datagen.flow_from_directory(
               validation_data_dir,
               target_size=(img_width, img_height),
               batch_size=batch_size,
               class_mode='binary',
               shuffle=False)
   bottleneck_features_validation = model.predict_generator(
               generator, nb_validation_samples // batch_size)
   np.save(open('bottleneck_features_validation', 'wb'),bottleneck_features_validation)

def train_top_model():
   train_data = np.load(open('bottleneck_features_train', 'rb'))
   train_labels = np.array([0] * (nb_train_samples // 2) + [1] * (nb_train_samples // 2))
   validation_data = np.load(open('bottleneck_features_validation', 'rb'))
   validation_labels = np.array([0] * (nb_validation_samples // 2) + [1] * (nb_validation_samples // 2))
   model = Sequential()
   model.add(Flatten(input_shape=train_data.shape[1:]))
   model.add(Dense(512, activation='relu'))
   model.add(Dense(1, activation='sigmoid'))
   sgd = SGD(lr=1e-3, decay=0.00, momentum=0.99, nesterov=False) 
   model.compile(optimizer=sgd,
         loss='binary_crossentropy', metrics=['accuracy'])
   model.fit(train_data, train_labels,
          epochs=epochs,
          batch_size=batch_size,
   validation_data=(validation_data, validation_labels))
   model.save_weights(top_model_weights_path)
   print('Predicting on test data')
   y_pred = model.predict_classes(validation_data)
   print(y_pred.shape)
   print('Generating results')
   generate_results(validation_labels[:,], y_pred[:,])
   print('Generating the ROC_AUC_Scores') #Compute Area Under the Curve (AUC) from prediction scores
   print(roc_auc_score(validation_labels,y_pred)) #this implementation is restricted to the binary classification task or multilabel classification task in label indicator format.
   target_names = ['class 0(Normal)', 'class 1(Abnormal)']
   print(classification_report(validation_labels,y_pred,target_names=target_names))
   print(confusion_matrix(validation_labels,y_pred))
   cnf_matrix = (confusion_matrix(validation_labels,y_pred))
   np.set_printoptions(precision=2)
   plt.figure()
   # Plot non-normalized confusion matrix
   plot_confusion_matrix(cnf_matrix, classes=target_names,
                      title='Confusion matrix')
   plt.show()
save_bottleneck_features()
train_top_model()

# path to the model weights files.
weights_path = '../keras/examples/vgg16_weights.h5'
top_model_weights_path = 'modela.h5'
# dimensions of our images.
img_width, img_height = 100, 100
train_data_dir = 'data4/train'
validation_data_dir = 'data4/validation'
nb_train_samples = 20
nb_validation_samples = 20
epochs = 50
batch_size = 10

# build the VGG16 network
base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(100,100,3))
print('Model loaded.')

train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='binary') 
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(512, activation='relu'))
top_model.add(Dense(1, activation='softmax'))
top_model.load_weights(top_model_weights_path)
model = Model(inputs=base_model.input, outputs=top_model(base_model.output))
   # set the first 15 layers (up to the last conv block)
# to non-trainable (weights will not be updated)
for layer in model.layers[:15]: #up to the layer before the last convolution block
        layer.trainable = False
model.summary()
   # fine-tune the model
model.compile(loss='binary_crossentropy', optimizer=SGD(lr=1e-4, momentum=0.99), metrics=['accuracy'])
model.fit_generator(train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size,
    verbose=1)
model.save_weights(top_model_weights_path)
bottleneck_features_validation = model.predict_generator(validation_generator, nb_validation_samples // batch_size)
np.save(open('bottleneck_features_validation','wb'), bottleneck_features_validation)
validation_data = np.load(open('bottleneck_features_validation', 'rb'))
y_pred1 = model.predict_classes(validation_data)

The problem is that the pre-trained model is getting trained on the data and predicts the classes perfectly and gives the confusion matrix as well. As I proceed to fine-tuning the model, I could find that model.predict_classes is not working. Here is the error:

File "C:/Users/rajaramans2/codes/untitled12.py", line 220, in <module>
    y_pred1 = model.predict_classes(validation_data)

AttributeError: 'Model' object has no attribute 'predict_classes'

I am confused because, model.predict_classes worked well with the pre-trained model, but not in the fine-tuning stage. The size of validation data is (20,1) and float32 type. Any help would be appreciated.

解决方案

The predict_classes method is only available for the Sequential class (which is the class of your first model) but not for the Model class (the class of your second model).

With the Model class, you can use the predict method which will give you a vector of probabilities and then get the argmax of this vector (with np.argmax(y_pred1,axis=1)).

这篇关于AttributeError: 'Model' 对象没有属性 'predict_classes'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆