【问题标题】:Keras image classification prediction error on image resize图像调整大小时 Keras 图像分类预测误差
【发布时间】:2021-01-29 23:11:14
【问题描述】:

我有一个经过训练的模型,该模型经过训练可以识别不同的文档,我从 http://www.cs.cmu.edu/~aharley/rvl-cdip/ 获取数据集。

以下是我构建模型的方式

import numpy as np
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import pickle

from keras.optimizers import SGD
from keras.models import Sequential, save_model
from keras.layers import Dense, Dropout, Flatten, Activation
from keras.layers.convolutional import Conv2D, MaxPooling2D

# Set image information
channels = 1
height = 1000
width = 754

model = Sequential()
# Add a Conv2D layer with 32 nodes to the model
model.add(Conv2D(32, (3, 3), input_shape=(1000, 754, 3)))
# Add the reLU activation function to the model
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())  # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('relu'))

model.compile(loss='categorical_crossentropy',  # sparse_categorical_crossentropy
              # Adam(lr=.0001) SGD variation with learning rate
              optimizer='adam',
              metrics=['accuracy'])

# Image data generator to import iamges from data folder
datagen = ImageDataGenerator()

# Flowing images from folders sorting by labels, and generates batches of images
train_it = datagen.flow_from_directory(
    "data/train/", batch_size=16, target_size=(height, width), shuffle=True, class_mode='categorical')
test_it = datagen.flow_from_directory(
    "data/test/", batch_size=16, target_size=(height, width), shuffle=True, class_mode='categorical')
val_it = datagen.flow_from_directory(
    "data/validate/", batch_size=16, target_size=(height, width), shuffle=True, class_mode='categorical')

history = model.fit(
    train_it,
    epochs=2,
    batch_size=16,
    validation_data=val_it,
    shuffle=True,
    steps_per_epoch=2000 // 16,
    validation_steps=800 // 16)


save_model(model, "./ComplexDocumentModel")
model.save("my_model", save_format='h5')

与上一行一样,我将模型保存为 h5 格式。

我现在正在尝试使用经过训练的模型对单个图像进行预测,并通过以下脚本查看它属于哪个类别。

from keras.models import load_model
import cv2
import numpy as np
import keras
from keras.preprocessing import image

model = load_model('my_model')

# First try
def prepare(file):
    img_array = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
    new_array = cv2.resize(img_array, (1000, 754))
    return new_array.reshape(3, 1000, 754, 1)


# Second try
img = image.load_img(
    "/home/user1/Desktop/Office/image-process/test/0000113760.tif")
img = image.img_to_array(img)
img = np.expand_dims(img, axis=-1)


prediction = model.predict(
    [prepare("/home/user1/Desktop/Office/image-process/test/0000113760.tif")])

print(prediction)

我尝试用两种方式预测图像,但都给出了错误

    ValueError: Input 0 of layer sequential is incompatible with the layer: expected axis -1 of input shape to have value 3 but received input with shape (None, 762, 3, 1)

我还尝试使用 PIL 打开图像并将其转换为 NumPy 数组,这是在 google 上找到的一种方法。不幸的是,我发现没有其他答案、博客或视频教程对我有帮助。

【问题讨论】:

    标签: python tensorflow machine-learning keras


    【解决方案1】:

    您正在尝试将灰度图像馈送到需要具有 3 个通道的图像的网络。您可以将最后一个通道堆叠 3 次以获得兼容的形状,但预测可能会很差:

    def prepare(file):
        img_array = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
        new_array = cv2.resize(img_array, (1000, 754)) # shape is (1000,754)
        # converting to RGB
        array_color = cv2.cvtColor(new_array, cv2.COLOR_GRAY2RGB) # shape is (1000,754,3)
        array_with_batch_dim = np.expand_dims(array_color, axis=0) # shape is (1,1000,754,3)
        return array_with_batch_dim
    

    另一种解决方案是在阅读时不将图像转换为灰度,方法是省略标志 cv2.IMREAD_GRAYSCALE。 opencv 的默认行为是加载具有 3 个通道的图像。

    def prepare(file):
        img_array = cv2.imread(file)
        new_array = cv2.resize(img_array, (1000, 754)) # shape is (1000,754, 3)
        # converting to RGB
        array_with_batch_dim = np.expand_dims(new_array, axis=0) # shape is (1,1000,754,3)
        return array_with_batch_dim
    

    注意:根据您的预处理,您可能需要通过将图像除以 255 将图像在 0 和 1 之间进行归一化,然后再将其输入网络。

    【讨论】:

    • 或者,首先不要转换为灰度(代码块的第 2 行)
    • 这很好。我确信imread 正在将灰度图像加载到 2D 数组中,但似乎默认是将它们加载到具有 3 个通道的 3D 数组中。
    猜你喜欢
    • 1970-01-01
    • 2020-08-04
    • 2021-02-15
    • 2020-12-21
    • 1970-01-01
    • 2017-03-28
    • 2010-10-22
    • 1970-01-01
    • 2011-03-31
    相关资源
    最近更新 更多