我想加载预先训练的模型并开始对图像进行测试。
这是我认为可行的代码:
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras import backend as K
base_model = InceptionV3(weights='imagenet', include_top=False)
from __future__ import absolute_import, division, print_function
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
#Preprocessing
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_images = train_images / 255.0
test_images = test_images / 255.0
#Preprocessing
test_loss, test_acc = base_model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)
相反,它说:“您必须在训练/测试之前编译模型”
在这里https://keras.io/applications/在InceptionV3上看:他们似乎在导入模型后对其进行编译和拟合。他们为什么这样做呢?
答案 0 :(得分:2)
大多数经过预训练的图像分类模型都已在ImageNet数据集上进行了预训练,因此您在调用base_model = InceptionV3(weights='imagenet', include_top=False)
时会从该训练中加载参数权重。 include_top=False
参数实际上从模型中截取了预测层,您需要将其添加并在自己的数据集(在这种情况下为Fashion MNIST)上训练。
转移学习方法并不能完全摆脱所有训练,但是可以做到,因此您只需要根据数据集的特定数据对模型进行微调即可。由于该模型已经学会了如何通过在ImageNet上进行训练来识别基本的甚至有些复杂的形状,因此现在只需对其进行训练即可识别出某些形状组合在您的数据上下文中意味着什么。
话虽如此,但我相信即使将模型model.predict(x)
更改为include_top=False
,您仍应该能够在某些经过预处理的图像x上调用include_top=True
将该图像分为ImageNet的1000个类别之一,而不是Fashion MNIST的一个类别。
答案 1 :(得分:1)
与Fashion MNIST相比,InceptionV3模型在非常不同的图像上进行了训练。您在本教程中看到的是转移学习的一个实例。大致在迁移学习中,您可以将模型分为特征提取模块和分类模块。卷积层和池化层的目标是使特征提取自动化,以便我们可以实现从原始图像像素到能够很好描述图像的代表性特征集的理想转换。
这些图像然后被馈送到分类模块,其中目标是采用这些功能并实际进行分类。这就是在卷积和合并之后附加的密集层的目标。还要注意,InceptionV3模型是在ImageNet图像上训练的,该图像具有1000个类。为了将ImageNet成功应用于Fashion MNIST数据集,您将需要重新训练Dense层,以便转换层和合并层可以提取从图像中提取的特征并对其进行分类。因此,将include_top=False
设置为已完成的操作,但还必须附加一些密集层并对其进行重新训练。另外,由于Fashion MNIST数据集,请确保指定最后一层具有10个类。
但是,有些陷阱是InceptionV3可以拍摄299 x 299尺寸的图像,而Fashion MNIST可以拍摄28 x 28的图像。您需要调整图像的大小,并人为地填充三维尺寸的图像,使其成为RGB 。因为从28 x 28到299 x 299的尺寸要求两个尺寸都增加10倍,所以以这种分辨率调整图像大小可能在感觉上不会很好。 InceptionV3可以加载到可以更改预期输入图像大小的模型中。遗憾的是,最小的图像大小是InceptionV3的75 x 75,因此我们必须使用该图像然后将其调整为75 x75。要调整图像的大小,您可以使用{{1}中的Scikit-images resize
方法}。另外,如果您打算使用InceptionV3,则需要像训练之前一样在网络中对输入图像进行预处理。
因此:
skimage.transform
请注意,我必须更改来自InceptionV3基本模型的数据的预期输入形状,使其为75 x 75 x 3,其中3表示期望的彩色图像。另外,我必须在将数据除以255之前将其转换为浮点数,否则数据仍将是无符号的8位整数,因此唯一的值将为0或1,从而大大降低了准确性。另外,我创建了存储图像的RGB版本的新数组,这些数组不仅调整为75 x 75,而且还使用了InceptionV3在训练图像之前使用的相同方法进行了预处理。我应该提到的另一件事是,我们需要在Dense图层之前设置图层,以免在它们上进行训练。我们想使用这些层来提供图像的特征描述符,这些图像被抽入Dense层进行分类。最后,请注意,用于训练和测试数据的标签是从0到9枚举的。因此,您需要的损失函数将是稀疏分类交叉熵,该标签旨在容纳单值标签。分类交叉熵损失函数期望一热编码。
我们最终编译了模型,因此可以对其进行设置以进行训练,然后进行训练。最后,我们评估测试数据的准确性。当然,这需要进行一些调整,尤其是所需的密集层数以及要选择进行训练的时期数。
调整图像的大小并为其创建一个新的数组将花费一些时间,因为我们分别循环遍历60000个训练图像和10000个测试图像。您需要在这里耐心等待。为了节省内存,我从内存中删除了原始训练和测试图像,以补偿预处理后的图像。
由于Fashion MNIST数据集的自由度比ImageNet小得多,因此您可以摆脱使用比正常情况少的图层而获得高精度模型的麻烦。 ImageNet数据库由失真度,对象方向,位置和大小各不相同的图像组成。如果您构建的模型仅由几个conv和pool层组成,再加上平整度和几个致密层,则不仅需要花费更少的时间进行训练,而且您将获得性能出色的模型。
答案 2 :(得分:1)
您在Keras文档中显示的示例与您要执行的示例不同。他们适合模型以执行转移学习。
您似乎只想加载经过预训练的模型,然后在某些数据集上评估其损失/准确性。问题在于,要调用model.evaluate
,您首先需要定义损失和指标(包括准确性),为此,您需要调用model.compile(loss = ..., metrics = ..., optimizer = ...)
,因为这是唯一的Keras调用设置模型的损失和指标。
如果由于某些原因您不想这样做,则可以对数据集调用y_pred = model.predict
,并在y_true
和{{上使用想要的损失和指标的任何python实现1}}。外部化评估时,无需编译模型。