代码之家  ›  专栏  ›  技术社区  ›  RoyalSwish

TensorFlow/Keras-预期的全局平均值pooling2d输入具有形状(1,1,2048),但得到具有形状的数组(7,7,2048)

  •  0
  • RoyalSwish  · 技术社区  · 7 年前

    我对TensorFlow和图像分类还比较陌生,所以我可能缺少关键知识,这可能是我面临这个问题的原因。

    我已经建立了一个 ResNet50 用于犬种图像分类的张量流模型 ImageNet 我和图书馆已经成功地训练了一个神经网络,可以检测各种狗的品种。

    我现在想把一只狗的随机图像传给我的模型,让它输出一个它认为狗是什么品种的输出。但是,当我运行这个函数时, dog_breed_predictor("<file path to image>") ,我得到错误 expected global_average_pooling2d_1_input to have shape (1, 1, 2048) but got array with shape (7, 7, 2048) 当它试图执行行时 Resnet50_model.predict(bottleneck_feature) 我不知道该怎么解决这个问题。

    这是密码。我已经提供了我认为与问题有关的一切。

    import cv2
    import matplotlib.pyplot as plt
    import numpy as np
    import tensorflow as tf
    
    from keras.applications.resnet50 import ResNet50
    from keras.preprocessing import image
    from tqdm import tqdm
    
    from sklearn.datasets import load_files
    np_utils = tf.keras.utils
    
    # define function to load train, test, and validation datasets
    def load_dataset(path):
        data = load_files(path)
        dog_files = np.array(data['filenames'])
        dog_targets = np_utils.to_categorical(np.array(data['target']), 133)
        return dog_files, dog_targets
    
    # load train, test, and validation datasets
    train_files, train_targets = load_dataset('dogImages/dogImages/train')
    valid_files, valid_targets = load_dataset('dogImages/dogImages/valid')
    test_files, test_targets = load_dataset('dogImages/dogImages/test')
    
    #define Resnet50 model
    Resnet50_model = ResNet50(weights="imagenet")
    
    def path_to_tensor(img_path):
        #loads RGB image as PIL.Image.Image type
        img = image.load_img(img_path, target_size=(224, 224))
        #convert PIL.Image.Image type to 3D tensor with shape (224, 224, 3)
        x = image.img_to_array(img)
        #convert 3D tensor into 4D tensor with shape (1, 224, 224, 3)
        return np.expand_dims(x, axis=0)
    
    from keras.applications.resnet50 import preprocess_input, decode_predictions
    
    def ResNet50_predict_labels(img_path):
        #returns prediction vector for image located at img_path
        img = preprocess_input(path_to_tensor(img_path))
        return np.argmax(Resnet50_model.predict(img))
    
    ###returns True if a dog is detected in the image stored at img_path
    def dog_detector(img_path):
        prediction = ResNet50_predict_labels(img_path)
        return ((prediction <= 268) & (prediction >= 151))
    
    ###Obtain bottleneck features from another pre-trained CNN
    bottleneck_features = np.load("bottleneck_features/DogResnet50Data.npz")
    train_DogResnet50 = bottleneck_features["train"]
    valid_DogResnet50 = bottleneck_features["valid"]
    test_DogResnet50 = bottleneck_features["test"]
    
    ###Define your architecture
    Resnet50_model = tf.keras.Sequential()
    Resnet50_model.add(tf.keras.layers.GlobalAveragePooling2D(input_shape=train_DogResnet50.shape[1:]))
    Resnet50_model.add(tf.contrib.keras.layers.Dense(133, activation="softmax"))
    
    Resnet50_model.summary()
    
    ###Compile the model
    Resnet50_model.compile(loss="categorical_crossentropy", optimizer="rmsprop", metrics=["accuracy"])
    ###Train the model
    checkpointer = tf.keras.callbacks.ModelCheckpoint(filepath="saved_models/weights.best.ResNet50.hdf5",
                                                     verbose=1, save_best_only=True)
    
    Resnet50_model.fit(train_DogResnet50, train_targets,
                      validation_data=(valid_DogResnet50, valid_targets),
                      epochs=20, batch_size=20, callbacks=[checkpointer])
    
    ###Load the model weights with the best validation loss.
    Resnet50_model.load_weights("saved_models/weights.best.ResNet50.hdf5")
    
    ###Calculate classification accuracy on the test dataset
    Resnet50_predictions = [np.argmax(Resnet50_model.predict(np.expand_dims(feature, axis=0))) for feature in test_DogResnet50]
    
    #Report test accuracy
    test_accuracy = 100*np.sum(np.array(Resnet50_predictions)==np.argmax(test_targets, axis=1))/len(Resnet50_predictions)
    print("Test accuracy: %.4f%%" % test_accuracy)
    
    def extract_Resnet50(tensor):
        from keras.applications.resnet50 import ResNet50, preprocess_input
        return ResNet50(weights='imagenet', include_top=False).predict(preprocess_input(tensor))
    
    def dog_breed(img_path):
        #extract bottleneck features
        bottleneck_feature = extract_Resnet50(path_to_tensor(img_path))
        #obtain predicted vector
        predicted_vector = Resnet50_model.predict(bottleneck_feature) #shape error occurs here
        #return dog breed that is predicted by the model
        return dog_names[np.argmax(predicted_vector)]
    
    def dog_breed_predictor(img_path):
        #determine the predicted dog breed
        breed = dog_breed(img_path)
        #display the image
        img = cv2.imread(img_path)
        cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        plt.imshow(cv_rgb)
        plt.show()
        #display relevant predictor result
        if dog_detector(img_path):
            print("This is a dog and its breed is: " + str(breed))
        elif face_detector(img_path):
            print("This is a human but it looks like a: " + str(breed))
        else:
            print("I don't know what this is.")
    
    dog_breed_predictor("dogImages/dogImages/train/016.Beagle/Beagle_01126.jpg")
    

    我提供给函数的图像来自用于训练模型的同一个数据集-我想看看模型是否按预期工作-所以这个错误使它变得更加混乱。我可能做错什么了?

    2 回复  |  直到 7 年前
        1
  •  2
  •   RoyalSwish    7 年前

    nessuno pooling ResNet50

    return ResNet50(weights='imagenet',
                    include_top=False).predict(preprocess_input(tensor))
    

    (1, 7, 7, 2048) pooling="avg"

    return ResNet50(weights='imagenet',
                    include_top=False,
                    pooling="avg").predict(preprocess_input(tensor))
    

    (1, 2048)

    dog_breed()

    print(bottleneck_feature.shape) #returns (1, 2048)
    bottleneck_feature = np.expand_dims(bottleneck_feature, axis=0)
    bottleneck_feature = np.expand_dims(bottleneck_feature, axis=0)
    bottleneck_feature = np.expand_dims(bottleneck_feature, axis=0)
    print(bottleneck_feature.shape) #returns (1, 1, 1, 1, 2048) - yes a 5D shape, not 4.
    

    (1, 1, 1, 1, 2048)

    def dog_breed(img_path):
        #extract bottleneck features
        bottleneck_feature = extract_Resnet50(path_to_tensor(img_path))
        #obtain predicted vector
        predicted_vector = Resnet50_model.predict(bottleneck_feature) #shape error occurs here
        #return dog breed that is predicted by the model
        return dog_names[np.argmax(predicted_vector)]
    

    def dog_breed(img_path):
        #extract bottleneck features
        bottleneck_feature = extract_Resnet50(path_to_tensor(img_path))
        print(bottleneck_feature.shape) #returns (1, 2048)
        bottleneck_feature = np.expand_dims(bottleneck_feature, axis=0)
        bottleneck_feature = np.expand_dims(bottleneck_feature, axis=0)
        bottleneck_feature = np.expand_dims(bottleneck_feature, axis=0)
        print(bottleneck_feature.shape) #returns (1, 1, 1, 1, 2048) - yes a 5D shape, not 4.
        #obtain predicted vector
        predicted_vector = Resnet50_model.predict(bottleneck_feature) #shape error occurs here
        #return dog breed that is predicted by the model
        return dog_names[np.argmax(predicted_vector)]
    

        2
  •  1
  •   nessuno    7 年前

    ResNet50 input_shape

    include_top False

    return ResNet50(weights='imagenet',
                    include_top=False,
                    input_shape=(224, 224, 3)).predict(preprocess_input(tensor))
    
    推荐文章