在训练模型之前,我们将实现三种新的图像预处理方法——零均值化、patch Preprocessing和随机裁剪(也称为10-cropping或过采样)。之后,我们将利用Krizhevsky等人2012年的论文《ImageNet Classification with Deep Convolutional Neural Networks 》提出的AlexNet网络结构训练猫狗数据集,并在测试集上评估性能,另外,为了提高准确度,我们将对测试集使用过采样方法。在下面结果中,我们将看到使用AlexNet网络架构+裁剪方法可以获得比赛的top50。
if self.binarize: labels = np_utils.to_categorical(labels,self.calsses) # 预处理 if self.preprocessors isnotNone: proImages = [] for image in images: for p in self.preprocessors: image = p.preprocess(image) proImages.append(image) images = np.array(proImages)
同样也可以设置是否进行数据增强处理:
1 2 3 4
if self.aug isnotNone: (images,labels) = next(self.aug.flow(images, labels,batch_size = self.batchSize))
# -*- coding: utf-8 -*- # 加载所需模块 from keras.models import Sequential from keras.layers import BatchNormalization from keras.layers import Conv2D from keras.layers import MaxPooling2D from keras.layers import Activation from keras.layers import Flatten from keras.layers import Dropout from keras.layers import Dense from keras.regularizers import l2 from keras import backend as K
# Block #4: first set of FC => RELU layers model.add(Flatten()) # 拉平 # 全连接层 model.add(Dense(4096,kernel_regularizer=l2(reg))) model.add(Activation('relu')) model.add(BatchNormalization(axis = chanDim)) model.add(Dropout(0.5))
# Block #5: second set of FC => RELU layers model.add(Dense(4096,kernel_regularizer=l2(reg))) model.add(Activation('relu')) model.add(BatchNormalization(axis = chanDim)) model.add(Dropout(0.5))
# -*- coding: utf-8 -*- #加载所需模块 import matplotlib matplotlib.use('Agg') from config import dogs_vs_cats_config as config from pyimagesearch.preprocessing import imagetoarraypreprocessor as IAP from pyimagesearch.preprocessing import simplespreprocessor as SP from pyimagesearch.preprocessing import patchpreprocessor as PP from pyimagesearch.preprocessing import meanpreprocessor as MP from pyimagesearch.callbacks import trainingmonitor as TM from pyimagesearch.io import hdf5datasetgenerator as HDF from pyimagesearch.nn.conv import alexnet from keras.preprocessing.image import ImageDataGenerator from keras.optimizers import Adam import json import os
# -*- coding: utf-8 -*- from config import dogs_vs_cats_config as config from pyimagesearch.preprocessing import imagetoarraypreprocessor as IAP from pyimagesearch.preprocessing import simplespreprocessor as SP from pyimagesearch.preprocessing import patchpreprocessor as PP from pyimagesearch.preprocessing import meanpreprocessor as MP from pyimagesearch.preprocessing import croppreprocessor as CP from pyimagesearch.io import hdf5datasetgenerator as HDF from pyimagesearch.utils.ranked import rank5_accuracy from keras.models import load_model import numpy as np import progressbar import json
从磁盘中加载RGB均值数据,并初始化图像预处理和加载预先训练好的AlexNet网络:
1 2 3 4 5 6 7 8 9 10 11 12
# 加载RGB均值数据 means = json.loads(open(config.DATASET_MEAN).read())
# 遍历测试集 for (i,(images,labels)) inenumerate(testGen.generator(passes=1)): #遍历图像数据集 for image in images: # 10-cropping,返回10个特征图像数据 crops = cp.preprocess(image) crops = np.array([iap.preprocess(c) for c in crops], dtype = 'float32') pred = model.predict(crops) predictions.append(pred.mean(axis = 0)) # 更新进度条 pbar.update(i)
# 计算rank-1准确度 pbar.finish() print("[INFO] predicting on test data (with crops)....") (rank1,_) = rank5_accuracy(predictions,testGen.db['labels']) print("[INFO'] rank-1: {:.2f}%".format(rank1 * 100)) testGen.close()
执行以下命令,查看性能结果:
1 2 3 4 5 6 7
$ python crop_accuracy.py [INFO] loading model... [INFO] predicting on test data (no crops)... [INFO] rank-1: 92.60% Evaluating: 100% |####################################| Time: 0:01:12 [INFO] predicting on test data (with crops)... [INFO] rank-1: 94.00%
# -*- coding: utf-8 -*- # 加载所需要模块 from keras.applications import ResNet50 from keras.applications import imagenet_utils from keras.preprocessing.image import img_to_array from keras.preprocessing.image import load_img from sklearn.preprocessing import LabelEncoder from pyimagesearch.io import hdf5datasetwriter as HDF from imutils import paths import numpy as np import progressbar import argparse import random import os
# 命令行参数 ap = argparse.ArgumentParser() ap.add_argument('-d',"--dataset",required = True, help = 'path to input dataset') ap.add_argument("-0",'--output',required = True, help = 'path ot output hdf5 file') ap.add_argument('-b','--batch_size',type = int,default = 16, help='batch size of images to ba passed through network') ap.add_argument('-s','--buffer_size',type=int,default=1000, help = 'size of feature extraction buffer') args = vars(ap.parse_args()) # batch bs = args['batch_size']
其中:
datset:输入数据的路径
output: 输出路径
batch_size: batch数量的大小,默认为16
buffer_size: 默认1000,每1000次进行一次 操作
从磁盘中读取数据集并提取相应的标签数据:
1 2 3 4 5 6 7 8 9
print("[INFO] loading images...") imagePaths = list(paths.list_images(args['dataset'])) # 混洗数据 random.shuffle(imagePaths) # 标签获取 labels = [p.split(os.path.sep)[-1].split(".")[0] for p in imagePaths] # 编码编码化 le = LabelEncoder() labels = le.fit_transform(labels)
$ ls -l ../datasets/kaggle_dogs_vs_cats/hdf5/features.hdf5 -rw-rw-r-- adrian 409806272 Jun 3 07:17 output/dogs_vs_cats_features.hdf5
基于这些特征向量,我们将训练一个逻辑回归分类器。
逻辑回归
新建一个名为train_model.py文件,并写入以下代码:
1 2 3 4 5 6 7 8
# 加载所需模块 from sklearn.linear_model import LogisticRegression from sklearn.model_selection import GridSearchCV from sklearn.metrics import classification_report from sklearn.metrics import accuracy_score import argparse import pickle import h5py
解析命令行参数:
1 2 3 4 5 6 7 8 9
#命令行参数 ap = argparse.ArgumentParser() ap.add_argument("-d","--db",required = True, help = 'path HDF5 datasetbase') ap.add_argument('-m','--model',required=True, help='path to output model') ap.add_argument('-j','--jobs',type=int,default=-1, help = '# of jobs to run when tuning hyperparameters') args = vars(ap.parse_args())
其中:
db: HDF5数据集的路径
model:模型输出路径
jobs:资源使用数,默认值为-1,即使用全部资源
从HDF5数据集中读取数据,并进行数据划分——75%的数据用于训练,25%用于测试:
1 2 3
# 读取hdf5数据集 db = h5py.File(args['db'],'r') i = int(db['labels'].shape[0] * 0.75)# 分割点