Inceptionv3 分类错误
Posted
技术标签:
【中文标题】Inceptionv3 分类错误【英文标题】:Wrong classification with Inceptionv3 【发布时间】:2020-11-15 20:00:30 【问题描述】:我使用了一个带有先前训练过的权重的初始模型,并使用 TENSORFLOW IN PRACTICE 导师 Laurence Moroney 提供的数据集添加了几个密集层来对马与人类进行分类。 我认为该模型已经完美训练,但它做出的预测始终是一匹马。
上图清楚地表明准确度相当不错。
我用来实时上传图片到colab并进行预测的代码如下:
import numpy as np
from google.colab import files
from keras.preprocessing import image
uploaded = files.upload()
for fn in uploaded.keys():
# predicting images
path = '/content/' + fn
img = image.load_img(path, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
classes = model.predict(images, batch_size=10)
print(classes[0])
if classes[0]>0.5:
print(fn + " is a horse")
else:
print(fn + " is a human")
用于训练模型的代码如下:
!wget --no-check-certificate \
https://storage.googleapis.com/mledu-datasets/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5 \
-O /tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5
local_weights = '/tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'
from tensorflow.keras.applications.inception_v3 import InceptionV3
pre_trained_model = InceptionV3(include_top = False,
weights = None,
input_shape = (150, 150, 3))
pre_trained_model.load_weights(local_weights)
for layer in pre_trained_model.layers:
layer.trainable = False
last_layer = pre_trained_model.get_layer('mixed7')
print(last_layer.output_shape)
last_output = last_layer.output
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras import Model
from tensorflow.keras.optimizers import RMSprop
x = layers.Flatten()(last_output)
x = layers.Dense(1024, activation = 'relu')(x)
x = layers.Dropout(0.2)(x)
x = layers.Dense(1, activation = 'sigmoid')(x)
model = Model(pre_trained_model.input, x)
model.compile(optimizer = RMSprop(lr=0.0001),
loss = 'binary_crossentropy',
metrics = ['accuracy'])
!wget --no-check-certificate https://storage.googleapis.com/laurencemoroney-blog.appspot.com/horse-or-human.zip -O /tmp/horse-or-human.zip
# Get the Horse or Human Validation dataset
!wget --no-check-certificate https://storage.googleapis.com/laurencemoroney-blog.appspot.com/validation-horse-or-human.zip -O /tmp/validation-horse-or-human.zip
import zipfile
import os
local_zip = '/tmp/horse-or-human.zip'
ref_zip = zipfile.ZipFile(local_zip, 'r')
ref_zip.extractall('/tmp/train')
ref_zip.close()
local_zip = '/tmp/validation-horse-or-human.zip'
ref_zip = zipfile.ZipFile(local_zip, 'r')
ref_zip.extractall('/tmp/validate')
ref_zip.close()
train_dir = '/tmp/train'
validate_dir = '/tmp/validate'
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
width_shift_range = 0.2,
height_shift_range = 0.2,
rotation_range = 0.2,
shear_range = 0.2,
horizontal_flip = True,
zoom_range = 0.2)
training_generator = train_datagen.flow_from_directory(train_dir,
target_size = (150, 150),
class_mode = 'binary',
batch_size = 64)
test_datagen = ImageDataGenerator(rescale = 1./255)
validation_generator = test_datagen.flow_from_directory(validate_dir,
target_size = (150, 150),
class_mode = 'binary',
batch_size = 64)
history = model.fit_generator(training_generator,
validation_data = validation_generator,
epochs = 20,
verbose = 2,
)
【问题讨论】:
能否请您发布您的完整代码。 我已经更新了问题,请查看上方! 【参考方案1】:主要问题:原因是缺少重新缩放。当使用图像数据生成器时,给出了重新缩放因子。但是,当手动上传图像时,缺少重新缩放的代码。你必须添加一个x = x/255.0
。
您必须使用classes<0.5
。因此,如果概率 > 0.5,那么我们将其归类为人,而不是您指定的马。您可以使用training_generator.class_indices
进行检查,这将为您提供:
考虑以下两个例子(我从数据集中拿一张马的图片和一张人的图片来说明它):
错误的结果:
# predicting images
path = '/tmp/train/humans/human01-00.png'
img = image.load_img(path, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
# = x/255.0
images = np.vstack([x])
classes = model.predict(images, batch_size=10)
print(classes)
if classes<0.5:
print(path + " is a horse")
else:
print(path + " is a human")
path = "/tmp/train/horses/horse01-0.png"
img = image.load_img(path, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
#x = x/255.0
images = np.vstack([x])
classes = model.predict(images, batch_size=10)
print(classes)
if classes<0.5:
print(path + " is a horse")
else:
print(path + " is a human")
输出:
您可以看到两者都被错误分类。然而,被错误地归类为人类。你错了,你的模型总是预测人类,因为 1 是人类,0 是马。
正确结果:
# predicting images
path = '/tmp/train/humans/human01-00.png'
img = image.load_img(path, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = x/255.0
images = np.vstack([x])
classes = model.predict(images, batch_size=10)
print(classes)
if classes<0.5:
print(path + " is a horse")
else:
print(path + " is a human")
path = "/tmp/train/horses/horse01-0.png"
img = image.load_img(path, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = x/255.0
images = np.vstack([x])
classes = model.predict(images, batch_size=10)
print(classes)
if classes<0.5:
print(path + " is a horse")
else:
print(path + " is a human")
输出:
所以你可以看到它被正确分类了。
因此,请记住您的“>”是错误的。如果它被分类为 1 (>0.5),它被分类为人类。否则,如果小于 0.5 则作为马。
(您可能被课程中的官方剪纸示例误导了,代码中也缺少该示例。这是一个报告的问题。)
【讨论】:
非常感谢!我还没有尝试过剪刀石头布的例子,但我会记住这一点!以上是关于Inceptionv3 分类错误的主要内容,如果未能解决你的问题,请参考以下文章
在 Tensorflow 中使用 InceptionV3 进行预测
经典神经网络 | 从Inception v1到Inception v4全解析