我正在按照这个指南学习使用CNN进行图像分类,并且我已经将这段代码应用到了我的数据集中:
https://www.tensorflow.org/tutorials/images/classification
train_image_generator = ImageDataGenerator(rescale=1. / 255) # Generator for our training datavalidation_image_generator = ImageDataGenerator(rescale=1. / 255) # Generator for our validation datatrain_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size, directory=train_img_folder, shuffle=True, target_size=(IMG_HEIGHT, IMG_WIDTH), class_mode='categorical', color_mode='grayscale')val_data_gen = validation_image_generator.flow_from_directory(batch_size=batch_size, directory=valid_img_folder, target_size=(IMG_HEIGHT, IMG_WIDTH), class_mode='categorical', color_mode='grayscale' )model = Sequential([ Conv2D(16, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH, 1)), MaxPooling2D(), Conv2D(32, 3, padding='same', activation='relu'), MaxPooling2D(), Conv2D(64, 3, padding='same', activation='relu'), MaxPooling2D(), Flatten(), Dense(512, activation='relu'), Dense(3, activation='softmax')])model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])history = model.fit_generator( train_data_gen, steps_per_epoch=total_train_value // batch_size, epochs=epochs, validation_data=val_data_gen, validation_steps=total_valid_value // batch_size)# Single predictionimg = []temp = np.array(Image.open('path/to/pic.jpg').resize((256, 256), Image.ANTIALIAS))temp.shape = temp.shape + (1,) # now its (256, 256, 1)img.append(temp)test = np.array(img) # (1, 1024, 1024, 1)prediction = model.predict(test)
当我尝试使用predict_generator函数时:
test_datagen = ImageDataGenerator(rescale=1 / 255.)test_generator = test_datagen.flow_from_directory('test_images/', classes=['0', '1', '2'], color_mode='grayscale', shuffle=True, # use same size as in training target_size=(256, 256))preds = model.predict_generator(test_generator, steps=4) # 我不知道steps的作用,我放这里是因为报错。
我的第一个问题是:我可以获得训练和验证的准确率,但我想得到单张图片的预测结果。如何做到这一点?例如:
foo = model.predict(path/to/pic.jpg)# foo返回 0-> 0.70 | 1-> 0.30
补充:当我尝试像这样使用model.predict时,我得到了以下错误:
ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (1024, 1024)
或者转换为2D(和3D)的np.array仍然得到相同的错误。
我的第二个问题是: 是否有办法在不完全达到100%的情况下进行预测?我是说,如果我们有两个类别(猫和狗)并且测试月亮图片,我想得到这样的结果:
%15 猫 | %10 狗
而不是
%50 猫 | %50 狗
我尝试添加垃圾类别如下所示进行更改。当我在history = model.fit_generator
行运行时,我得到了以下错误:
ValueError: Error when checking target: expected dense_2 to have shape (3,) but got array with shape (2,)
回答:
第一个问题:我可以获得训练和验证的准确率,但我想得到单张图片的预测结果。如何做到这一点?
正如你在文档中看到的,你完全可以使用model.predict(x)
,只要你的x
是:
– Numpy数组(或类似数组),或者是数组列表(如果模型有多个输入)。
– 如果模型有命名输入,则是将输入名称映射到相应数组/张量的字典。
– 返回(输入,目标)或(输入,目标,样本权重)的生成器或keras.utils.Sequence。
你只需要编写读取.jpg图像并将其输入模型的代码即可。
第二个问题:是否有办法在不完全达到100%的情况下进行预测?我是说,如果我们有两个类别(猫和狗)并且测试月亮图片,我想得到这样的结果:
你可以创建第三个类别’垃圾’,为此你需要将网络的最后一层更改为:
Dense(3, activation='softmax')
并将损失函数更改为categorical_crossentropy
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
并将class_mode
更改为categorical
而不是binary
。
在这种情况下,你将得到狗:15%,猫:10%,垃圾:75%的结果
关于conv2D错误的编辑:
ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (1024, 1024)
你有:
Conv2D(16, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
这意味着一张图像是(height, width, channel)
。
如文档所示,由于这是输入层,你需要提供4D格式,形状为:(samples, rows, cols, channels)
。如果你只想提供一张图像,你需要有一个形状为(1, rows, cols, channels)
的数组。