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 模型有两个 softmax 输出吗?

经典神经网络 | 从Inception v1到Inception v4全解析

Inceptionv3 分类错误

针对 C++ 和 python 的 tensorflow 的 Inception v3 指南

pytorch 图像分类