使用TensorFlow和Keras进行图像分类

5
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K


# dimensions of our images.
img_width, img_height = 150, 150


train_data_dir = 'flowers/train'
validation_data_dir = 'flowers/validation'
nb_train_samples = 2500
nb_validation_samples = 1000
epochs = 20
batch_size = 50


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(5))
model.add(Activation('softmax'))


model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])


# 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')


validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical')


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)


model.save_weights('first_flowers_try.h5')

我们训练了这个模型以分类5个图像类别。我们使用了500张图像来训练模型,并使用每个类别的200张图像来验证模型。我们在tensorflow后端中使用keras进行训练。可以在以下网址下载数据: https://www.kaggle.com/alxmamaev/flowers-recognition 在我们的设置中,我们:
  • 创建了一个data/文件夹
  • 在data/文件夹内创建了train/和validation/子文件夹
  • 在train/和validation/子文件夹中创建了daisy/、dandelion/、rose/、sunflower/和tulip/子文件夹
  • 将500张图像放置于每个data/train/daisy、dandelion、rose、sunflower和tulip子文件夹中
  • 将每个data/validation/daisy、dandelion、rose、sunflower和tulip文件夹中的200张图像放置于其中,以使每个类别有500个训练示例和200个验证示例。
如何使用这个训练好的模型预测/测试和识别另一张图像呢?
3个回答

2

你需要从保存权重的文件中调用 model.load_weights() 方法。然后,获取一个需要预测的样本图像,并调用 model.predict( [sample_image] ) 方法,使用返回的结果作为预测结果。


但是当我们尝试这样做时,代码会产生一些错误! - Lakwin Chandula
追溯(Traceback)最近的一次调用: 文件 "C:\Program Files\JetBrains\PyCharm Community Edition 2018.1.4\helpers\pydev\pydev_run_in_console.py",第52行,在运行文件时: pydev_imports.execfile(file, globals, locals) # 执行脚本 - Lakwin Chandula
文件“C:\ Program Files \ JetBrains \ PyCharm Community Edition 2018.1.4 \ helpers \ pydev \ _pydev_imps \ _pydev_execfile.py”,第18行,在execfile中 执行(编译(内容+“\ n”,文件,“exec”),glob,loc) 文件“C:/ Users / shasi / PycharmProjects / cats_dogs / classifier_from_little_data_script_1.py”,第119行,在<module>中 model.load_weight('data / first_try.h5') - Lakwin Chandula
model.load_weight('data/first_try.h5') AttributeError: 'Sequential' 对象没有属性 'load_weight'。 - Lakwin Chandula

2

按照您在训练时所做的方式构建您的模型

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(5))
model.add(Activation('softmax'))


model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

从磁盘中加载模型的权重

model.load_weights('first_flowers_try.h5')

加载新图片。由于我们只使用一张图片,因此我们必须扩展维度-添加另一个维度。

from keras.preprocessing import image

img_path = 'path_to_your_new_image'
#img = image.load_img(img_path, target_size=(224, 224)) # if a you want a spesific image size
img = image.load_img(img_path)
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = x*1./255 #rescale as training

进行预测

prediction = model.predict(x) #Vector with the prob of each class

0
根据keras文档,您需要使用predict(self, x, batch_size=None, verbose=0, steps=None)。由于您在最后一层中使用Softmax作为激活函数,因此它将返回每个类别的概率。如果您只想要最有可能的类别,您需要选择具有最高概率的那个类别:
class_list = [class1, class2, class3, class4, class5] #A list of your classes
model.load_weights('first_flowers_try.h5') #Loads the saved weights
predicted_vector = model.predict(path_to_your_new_image) #Vector with the prob of each class
print(class_list[np.argmax(predicted_vector)) #Prints ellement with highest prob

现在,关于获取class_list,你可以尝试这样做:

import os
class_list = os.listdir('train')
class_list = sorted(class_list)

请告诉我这是否有效。


但是我们没有声明类,所以当我们尝试这样做时,会生成一些错误!如果我们需要声明类,我们应该如何声明呢? - Lakwin Chandula
编辑了上面的帖子,为您提供了创建列表的示例。请查阅glob文档以获取正确的参数。 - Yannis
顺便提一句,在 @lenik 解决方案中(我在这里评论是因为我没有足够的声望在那里评论),你可能将 model.load_weights() 拼写错误成了 model.load_weight()。 这就是你会遇到错误的原因。 - Yannis
它也不起作用。你能否编辑代码并发送给我吗?这将非常有帮助。 - Lakwin Chandula
文件未找到错误:[WinError 3] 系统无法找到指定路径:'data/train' - Lakwin Chandula
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接