然后,evaluate_model()函数可以被更新为调用tta_evaluate_model()以获得模型精度分数。
#fitandevaluateadefinedmodeldefevaluate_model(model, trainX, trainY, testX, testY): #fitmodelmodel.fit(trainX, trainY, epochs=3, batch_size=128, verbose=0) #evaluatemodelusingttaacc=tta_evaluate_model(model, testX, testY) returnacc
将所有这些结合在一起,下面列出了使用TTA的CNN for CIFAR-10重复评估的完整示例
#cnnmodelforthecifar10problemwithtest-timeaugmentationimportnumpyfromnumpyimportargmaxfromnumpyimportmeanfromnumpyimportstdfromnumpyimportexpand_dimsfromsklearn.metricsimportaccuracy_scorefromkeras.datasets.cifar10importload_datafromkeras.utilsimportto_categoricalfromkeras.preprocessing.imageimportImageDataGeneratorfromkeras.modelsimportSequentialfromkeras.layersimportConv2Dfromkeras.layersimportMaxPooling2Dfromkeras.layersimportDensefromkeras.layersimportFlattenfromkeras.layersimportBatchNormalization#loadandreturnthecifar10datasetreadyformodelingdefload_dataset(): #loaddataset (trainX, trainY), (testX, testY) =load_data() #normalizepixelvaluestrainX=trainX.astype('float32') /255testX=testX.astype('float32') /255#onehotencodetargetvaluestrainY=to_categorical(trainY) testY=to_categorical(testY) returntrainX, trainY, testX, testY#definethecnnmodelforthecifar10datasetdefdefine_model(): #definemodelmodel=Sequential() model.add(Conv2D(32, (3, 3), activation='relu', padding='same', kernel_initializer='he_uniform', input_shape=(32, 32, 3))) model.add(BatchNormalization()) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu', padding='same', kernel_initializer='he_uniform')) model.add(BatchNormalization()) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) model.add(Dense(128, activation='relu', kernel_initializer='he_uniform')) model.add(BatchNormalization()) model.add(Dense(10, activation='softmax')) #compilemodelmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) returnmodel#makeapredictionusingtest-timeaugmentationdeftta_prediction(datagen, model, image, n_examples): #convertimageintodatasetsamples=expand_dims(image, 0) #prepareiteratorit=datagen.flow(samples, batch_size=n_examples) #makepredictionsforeachaugmentedimageyhats=model.predict_generator(it, steps=n_examples, verbose=0) #sumacrosspredictionssummed=numpy.sum(yhats, axis=0) #argmaxacrossclassesreturnargmax(summed) #evaluateamodelonadatasetusingtest-timeaugmentationdeftta_evaluate_model(model, testX, testY): #configureimagedataaugmentationdatagen=ImageDataGenerator(horizontal_flip=True) #definethenumberofaugmentedimagestogeneratepertestsetimagen_examples_per_image=7yhats=list() foriinrange(len(testX)): #makeaugmentedpredictionyhat=tta_prediction(datagen, model, testX[i], n_examples_per_image) #storeforevaluationyhats.append(yhat) #calculateaccuracytestY_labels=argmax(testY, axis=1) acc=accuracy_score(testY_labels, yhats) returnacc#fitandevaluateadefinedmodeldefevaluate_model(model, trainX, trainY, testX, testY): #fitmodelmodel.fit(trainX, trainY, epochs=3, batch_size=128, verbose=0) #evaluatemodelusingttaacc=tta_evaluate_model(model, testX, testY) returnacc#repeatedlyevaluatemodel, returndistributionofscoresdefrepeated_evaluation(trainX, trainY, testX, testY, repeats=10): scores=list() for_inrange(repeats): #definemodelmodel=define_model() #fitandevaluatemodelaccuracy=evaluate_model(model, trainX, trainY, testX, testY) #storescorescores.append(accuracy) print('> %.3f'%accuracy) returnscores#loaddatasettrainX, trainY, testX, testY=load_dataset() #evaluatemodelscores=repeated_evaluation(trainX, trainY, testX, testY) #summarizeresultprint('Accuracy: %.3f (%.3f)'% (mean(scores), std(scores)))
考虑到重复评估和用于评估每个模型的较慢的手动测试时间增加,运行这个示例可能需要一些时间。
在这种情况下,我们可以看到性能从没有增加测试时间的测试集上的68.6%提高到增加测试时间的测试集上的69.8%。
>0.719>0.716>0.709>0.694>0.690>0.694>0.680>0.676>0.702>0.704Accuracy: 0.698 (0.013)
TTA如何调优
选择能给模型性能带来最大提升的扩展配置可能是一项挑战。
不仅有许多可选择的扩展方法和每种方法的配置选项,而且在一组配置选项上适合和评估模型的时间可能会花费很长时间,即使适合快速的GPU。
相反,我建议对模型进行一次调整并将其保存到文件中。例如:
#savemodelmodel.save('model.h5')
然后从单独的文件加载模型,并在一个小的验证数据集或测试集的一个小子集上评估不同的测试时间增强方案。
例如:
... #loadmodelmodel=load_model('model.h5') #evaluatemodeldatagen=ImageDataGenerator(...) ...
一旦找到了一组能够带来最大提升的扩展选项,您就可以在整个测试集中评估模型,或者像上面那样进行重复的评估实验。
测试时间扩展配置不仅包括ImageDataGenerator的选项,还包括为测试集中每个示例生成平均预测的图像数量。
在上一节中,我使用这种方法来选择测试时间的增加,发现7个示例比3个或5个更好,而且随机缩放和随机移动似乎会降低模型的精度。
记住,如果你也为训练数据集使用图像数据增强,并且这种增强使用一种涉及计算数据集统计数据的像素缩放(例如,你调用datagen.fit()),那么这些相同的统计数据和像素缩放技术也必须在测试时间增强中使用。
总结
在本文章中,您将发现测试时增强可以提高用于图像分类任务的模型的性能。
具体来说,你学会了:
测试时间增广是数据增广技术的应用,通常用于在训练中进行预测。
如何在Keras中从头开始实现测试时间增强。
如何使用测试时间增强来提高卷积神经网络模型在标准图像分类任务中的性能。