以下介绍如何在Keras里跑Imagenet2012,以及其中的坑。

版本说明:

  • Tensorflow 2.2.0
  • Python 3.5

数据集下载

方法一:官网下载文件。以Imagenet2012为例,数据集均可以在Imagenet官网 下载,具体地,Imagenet2012下载网址

Warning:值得注意的是,validation部分的图片标签在 Development kit (Task 1 & 2)中,需要下载该文件。

方法二:Tensorflow常年维护一个数据集即时获取的PyPI仓库,即tensorflow_datasets,但如何使用有待补充…

数据预处理和准备

首先是validation标签问题,这个问题很大,因为Imagenet官网toolkit给的标签(ILSVRC2012_ID)和Caffe、Keras的标签是不一致的,跑代码时需要用对应框架的标签。(证据ILSVRC2012_img_val数据集的使用, 下载imagenet2012数据集以及label说明)。我的处理方法是下载Caffe对应的Imagenet2012的标签,跑Keras时用这个标签。

然后是预处理,预处理大概分几步:

  1. Convert the image/images into batch format
  2. expand_dims will add an extra dimension to the data at a particular axis, we want the input matrix to the network to be of the form (batchsize, height, width, channels), thus we add the extra dimension to the axis 0.
  3. prepare the image for the XXX model

Note:不同的模型对应的不同的preprocess_input方法,要注意对应。要注意input_shape大小。同时注意,preprocess_input只能处理一张图片,处理多张图片的结果是不一样的。

以下是对图片进行 VGG19 处理的示例代码 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from keras.preprocessing import image
from keras.applications.vgg19 import preprocess_input
from keras.models import Model
from tqdm import tqdm
import numpy as np
import os
dir_str = 'ILSVRC2012_val'
l = os.listdir(dir_str)
l = sorted(l)

def processIMG(img_path):
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = preprocess_input(x)
return x

l_test = []
for i in tqdm(l):
img_path = os.path.join(dir_str, i)
x = processIMG(img_path)
l_test.append(x)
np.save(dir_str+'_299_inception_resnet_v2',l_test)

用预训练模型参数测试

Reference:

示例代码 :

1
2
3
4
5
6
7
8
9
import tensorflow as tf 
sgd = keras.optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
num_classes = 1000
y_test = np.load('val.gt.npy') # label data
y_test = keras.utils.to_categorical(y_test, num_classes)
i = np.load('ILSVRC2012_val_224_mobilenetv2.npy') # preprocessed image data
mmobile = keras.applications.mobilenet_v2.MobileNetV2(input_shape=None, include_top=True, weights='imagenet', input_tensor=None, pooling=None, classes=1000)
mmobile.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy', tf.keras.metrics.TopKCategoricalAccuracy(k=5, name="top_k_categorical_accuracy", dtype=None)])
mmobile.evaluate(i, y_test)

Note:血泪教训:Keras虽然有中文文档,但更新比英文慢,看英文版本会准确些