我按照Keras博客上的教程进行操作,我遇到以下问题:一旦模型被训练,我该如何选择图像并对其进行分类?
我知道 train_generator.class_indices 在模型中有类。
目标是引入图像的路径并返回相应的类。
以下是代码:
#libraries used
from keras import backend as K
from keras import applications
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.optimizers import SGD
import cv2
from PIL import Image
import matplotlib.pyplot as plt
from scipy.misc import imread
import numpy as np
%matplotlib inline
# dimensions of our images.
img_width, img_height = 150, 150
train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 3000
nb_validation_samples = 1200
epochs = 10 #50
batch_size = 16
n_classes = 3
# Get data
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(rescale=1. / 255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(train_data_dir, target_size=(img_width, img_height),\
batch_size=batch_size,class_mode = 'categorical') # class_mode='binary'
validation_generator = test_datagen.flow_from_directory(validation_data_dir, target_size=(img_width, img_height),\
batch_size=batch_size, class_mode='categorical') #class_mode = 'categorical
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
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(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(n_classes))
model.add(Activation('softmax')) #sigmoid
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy']) #loss binary_crossentropy
# on the other model
#model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy', 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)
修改1:
我编写了以下函数,它不起作用:
def predict(model, img, target_size):
if img.size != target_size:
img = img.resize(target_size)
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = model.predict(x)
return preds[0]
target_size = (150, 150)
model = load_model(model_name)
img_path = 'image_test/test1.jpg'
img = Image.open(img_path)
fig = plt.figure()
plt.imshow(img)
plt.show()
preds = predict(model, img, target_size)
preds
编辑2 :
出现错误:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-55-516f01bf49e9> in <module>()
17 plt.imshow(img)
18 plt.show()
---> 19 preds = predict(model, img, target_size)
20 preds
<ipython-input-55-516f01bf49e9> in predict(model, img, target_size)
3 img = img.resize(target_size)
4
----> 5 x = image.img_to_array(img)
6 x = np.expand_dims(x, axis=0)
7 x = preprocess_input(x)
AttributeError: 'numpy.ndarray' object has no attribute 'img_to_array'
编辑3 :解决方案如下(我们必须重塑这个数字):
def predict(model, img, target_size):
if img.size != target_size:
img = img.resize(target_size)
x = img.getdata() #.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = (x/255.)
print("shape = ", x.shape)
x = x.reshape(1,150,150,3)
preds = model.predict(x)
return preds[0]
target_size = (150, 150)
img_path = 'image_test/bird.jpg'
img = Image.open(img_path)
fig = plt.figure()
plt.imshow(img)
plt.show()
preds = predict(model, img, target_size)
preds
答案 0 :(得分:1)
从发生器获取模型预期的确切形状:
X, Y = train_generator.next() #or next(train_generator)
现在看看:
print(X.shape)
print(X.max())
获取图像库,例如Pillow(from PIL import Image
),然后将所需的文件加载到数组中(该方法取决于库)。
确保此加载数组中的最大值与X
中的最大值兼容(例如,您可能必须将数组除以255)
您可以创建包含多个图像的数组,或仅创建图像,但请确保在第一维中考虑批量大小:
oneImageBatch = oneImageArray.reshape((1,)+oneImageArray.shape)
然后使用model.predict(oneImageBatch)
。
答案 1 :(得分:1)
这肯定会有用。
from keras.preprocessing import image
targ_size = (150, 150)
def predict(model, img_path):
x = image.load_image(img_path, target_size=targ_size)
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = model.predict(x)
return preds
model = load_model(model_name)
img_path = 'image_test/test1.jpg'
preds = predict(model, img_path)
这将返回每个类的概率数组。如果你想知道它是哪一个类,那就这样做:
pred_class = np.argmax(pred, axis=-1)