深度学习 Keras 1.3 分类照片中的物体

卷积神经网络现在能够在一些电脑视觉任务上胜过人类的肉眼,例如图像分类。

也就是说,给出一个物体的照片,我们可以让电脑来回答这个照片是1000个特定 种类物体中的哪一类这样的问题。

在本教程中,我们将使用几个Keras己经内建好的预训练模型来进行图像分类, 其中包括了:

  • VGG16
  • VGG19
  • ResNet50
  • InceptionV3
  • InceptionResNetV2
  • Xception
  • MobileNet

基于 VGG16 实现简单的照片分类器

1.获取范例图像

首先,我们需要一个测试用的图像。我下载了这张图片,是几只非洲象:

https://www.elephantvoices.org/images/slider/evimg16tf.jpg

接下来,我们编写程序,让计算机告诉我们图片里是什么东西

2.加载VGG模型

加载在 Keras 中己经预训练好的 VGG-16 的权重模型。

from keras.applications.vgg16 import VGG16

# 载入权重
model_vgg16 = VGG16()

3.加载和准备图像

接下来,我们可以将图像加载进来,并转换成预训练网络所要求的张量规格。

Keras 提供了一些工具来帮助完成这一步骤。

首先,我们可以使用 load_img() 函数加载图像,并将其大小调整为 224×224 像素所需的大小。

from keras.preprocessing.image import load_img

# 载入图像
img_file = 'resources/evimg16tf.jpg'
image = load_img(img_file, target_size=(224, 224)) # 因为VGG16的模型的输入是224x224

接下来,我们可以将像素转换为 NumPy 数组,以便我们可以在 Keras 中使用它。我们可以使用这个 img_to_array() 函数。

from keras.preprocessing.image import img_to_array

# 将图像资料转为numpy array
image = img_to_array(image) # RGB

print("image.shape:", image.shape)

VGG16 网络期望 单色阶(grey) 或 多色阶图像(rgb) 来作为输入,

这意味著输入数组需要是转换成四个维度:

(图像批次量,图像高,图像宽, 图像色阶数) ->
(batch_size, img_height, img_width, img_channels)

我们只有一个样本(一个图像),可以通过调用 reshape() 来重新调整数组的形状,并添加额外的维度。

# 调整张量的维度
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))

print("image.shape:", image.shape)

接下来,我们需要按照 VGG 训练 ImageNet 数据一样的方法来对图像进行前处理。具体怎么做呢,论文里谈到:

The only preprocessing we do is subtracting the mean RGB value, computed on the training set, from each pixel.

Very Deep Convolutional Networks for Large-Scale Image Recognition, 2014.

from keras.applications.vgg16 import preprocess_input

# 准备VGG模型的图像
image = preprocess_input(image)

4.做一个预测

我们可以调用模型中的 predict() 函数来预测图像属于 1000 个已知对像类型的机率。

# 预测所有产出类别的机率

y_pred = model_vgg16.predict(image)

5.解释预测

Keras 提供了一个函数来解释称为 decode_predictions() 的概率。

它可以返回一个类别的列表和每一个类别机率,

为了简单起见,我们这里只打印出机率最高的预测结果。

from keras.applications.vgg16 import decode_predictions

# 将机率转换为类别标签
label = decode_predictions(y_pred)

# 检索最可能的结果,例如最高的概率
label = label[0][0]

# 打印预测结果
print('%s (%.2f%%)' % (label[1], label[2]*100))
*** 下面几个模型我没运行过,代码是拷贝的 ***

基于 VGG19 实现简单的照片分类器

from keras.applications.vgg19 import VGG19
from keras.preprocessing import image
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.vgg19 import preprocess_input
from keras.applications.vgg19 import decode_predictions

# 载入权重
model_vgg19 = VGG19(weights='imagenet')
# 载入图像档
img_file = 'evimg16tf.jpg'
image = load_img(img_file, target_size=(224, 224)) # 因为VGG19的模型的输入是224x224

# 将图像资料转为numpy array
image = img_to_array(image) # RGB
print("image.shape:", image.shape)

# 调整张量的维度
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
print("image.shape:", image.shape)

# 准备模型所需要的图像前处理
image = preprocess_input(image)

# 预测所有产出类别的机率
y_pred = model_vgg19.predict(image)

# 将机率转换为类别标签
label = decode_predictions(y_pred)

# 检索最可能的结果,例如最高的概率
label = label[0][0]

# 打印预测结果
print('%s (%.2f%%)' % (label[1], label[2]*100))

基于 ResNet50 实现简单的照片分类器

from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.resnet50 import preprocess_input
from keras.applications.resnet50 import decode_predictions

# 载入权重
model_resnet50 = ResNet50(weights='imagenet')

# 载入图像档
img_file = 'evimg16tf.jpg'

# 因为ResNet的模型的输入是224x224
image = load_img(img_file, target_size=(224, 224)) 

# 将图像资料转为numpy array
image = img_to_array(image) # RGB
print("image.shape:", image.shape)

# 调整张量的维度
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
print("image.shape:", image.shape)

# 准备模型所需要的图像前处理
image = preprocess_input(image)

# 预测所有产出类别的机率
y_pred = model_resnet50.predict(image)

# 将机率转换为类别标签
label = decode_predictions(y_pred)

# 检索最可能的结果,例如最高的概率
label = label[0][0]

# 打印预测结果
print('%s (%.2f%%)' % (label[1], label[2]*100))

基于 InceptionV3 实现简单的照片分类器

from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.inception_v3 import preprocess_input
from keras.applications.inception_v3 import decode_predictions

# 载入权重
model_inception_v3 = InceptionV3(weights='imagenet')

# 载入图像档
img_file = 'image.jpg'
# InceptionV3的模型的输入是299x299
img = load_img(img_file, target_size=(299, 299)) 

# 将图像资料转为numpy array
image = image.img_to_array(img) # RGB
print("image.shape:", image.shape)

# 调整张量的维度
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
print("image.shape:", image.shape)

# 准备模型所需要的图像前处理
image = preprocess_input(image)

# 预测所有产出类别的机率
y_pred = model_inception_v3.predict(image)

# 将机率转换为类别标签
label = decode_predictions(y_pred)

# 检索最可能的结果,例如最高的概率
label = label[0][0]

# 打印预测结果
print('%s (%.2f%%)' % (label[1], label[2]*100))

基于 InceptionResNetV2 实现简单的照片分类器

from keras.applications.inception_resnet_v2 import InceptionResNetV2
from keras.preprocessing import image
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.inception_resnet_v2 import preprocess_input
from keras.applications.inception_resnet_v2 import decode_predictions

# 载入权重
model_inception_resnet_v2 = InceptionResNetV2(weights='imagenet')

# 载入图像档
img_file = 'evimg16tf.jpg'

# InceptionResNetV2的模型的输入是299x299
image = load_img(img_file, target_size=(299, 299)) 

# 将图像资料转为numpy array
image = img_to_array(image) # RGB
print("image.shape:", image.shape)

# 调整张量的维度
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
print("image.shape:", image.shape)

# 准备模型所需要的图像前处理
image = preprocess_input(image)

# 预测所有产出类别的机率
y_pred = model_inception_resnet_v2.predict(image)

# 将机率转换为类别标签
label = decode_predictions(y_pred)

# 检索最可能的结果,例如最高的概率
label = label[0][0]

# 打印预测结果
print('%s (%.2f%%)' % (label[1], label[2]*100))

基于 MobileNet 实现简单的照片分类器

from keras.applications.mobilenet import MobileNet
from keras.preprocessing import image
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.mobilenet import preprocess_input
from keras.applications.mobilenet import decode_predictions

# 载入权重
model_mobilenet = MobileNet(weights='imagenet')

# 载入图像档
img_file = 'evimg16tf.jpg'

# MobileNet的模型的输入是224x224
image = load_img(img_file, target_size=(224, 224)) 

# 将图像资料转为numpy array
image = img_to_array(image) # RGB
print("image.shape:", image.shape)

# 调整张量的维度
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
print("image.shape:", image.shape)

# 准备模型所需要的图像前处理
image = preprocess_input(image)

# 预测所有产出类别的机率
y_pred = model_mobilenet.predict(image)

# 将机率转换为类别标签
label = decode_predictions(y_pred)

# 检索最可能的结果,例如最高的概率
label = label[0][0]

# 打印预测结果
print('%s (%.2f%%)' % (label[1], label[2]*100))

总结 (Conclusion)

在这篇文章中有一些个人学习到的一些有趣的重点:

在Keras中己经预建了许多高级的图像识别的网络及预训练的权重
需要了解每种高级图像识别的网络的结构与输入的张量
了解不同高级图像识别的网络的训练变数量与预训练的权重可以有效帮助图像识别类型的任务


转载请注明来源。 欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。 可以在下面评论区评论,也可以邮件至 sharlot2050@foxmail.com。

文章标题:深度学习 Keras 1.3 分类照片中的物体

字数:2k

本文作者:夏来风

发布时间:2021-01-28, 22:27:01

原始链接:http://www.demo1024.com/blog/ai-ml-keras-1.3/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。