预测生成器 keras 的问题

数据挖掘 机器学习 深度学习 喀拉斯 张量流 预测
2022-02-19 18:49:57

我是带有 tensorflow 后端的 keras 新手,我正在尝试使用预训练网络进行迁移学习。问题是验证集的准确率非常高,在 90% 左右,但在测试集上的准确率非常差,不到 1%。我使用 opencv 读取和调整图像大小解决了这个问题,但我想了解为什么使用 keras 方法会出现这个问题。我在下面粘贴我的代码。

from keras.preprocessing.image import ImageDataGenerator
from keras.applications.xception import preprocess_input
import keras

train_val_datagen = ImageDataGenerator( validation_split=0.25, preprocessing_function=preprocess_input)


train_val_generator = train_val_datagen.flow_from_directory( # subset di allenamento
    directory="./image-dataset/",
    target_size=(299, 299),
    color_mode="rgb",
    batch_size=32,
    class_mode="categorical",
    shuffle=True,
    subset = 'training',
    seed=17)
val_train_generator = train_val_datagen.flow_from_directory( # subset di validation
    directory="./image-dataset/",
    target_size=(299, 299),
    color_mode="rgb",
    batch_size=32,
    class_mode="categorical",
    shuffle=True,
    subset = 'validation',
    seed=17)
final_train_generator = train_val_datagen.flow_from_directory( # set finale di allenamento con tutti i dati
    directory="./image-dataset/",
    target_size=(299, 299),
    color_mode="rgb",
    batch_size=32,
    class_mode="categorical",
    shuffle=True,
    seed=17)

如您所见,我使用 Xception 作为预训练网络,我选择调整图像大小以使其适应网络。

训练后,我为测试数据创建了一个新的迭代器,如下所示:

test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
test_generator = test_datagen.flow_from_directory( 
    directory="./TEST/",
    target_size=(299, 299),
    color_mode="rgb",
    batch_size=1, # predico una alla volta
    shuffle = False,
    class_mode=None # non ce alcuna classe di riferimento
    )
test_generator.reset()

其中预处理函数完全相同。

使用以下代码进行预测:

predictions = model_xcpetion.predict_generator(test_generator, 6104, verbose = 1 )

其中 6104 是测试文件夹中的图像数量。在此之后,我生成了一个带有相对分类概率的图像名称的 csv:

import pandas as pd
import numpy as np
df = pd.DataFrame(predictions)
cols =[('probability of' + str(i)) for i in list(range(1, 30 )) ]
df.columns =  cols
df['images'] = imNames
df.to_csv('predictions_xception_all_data.csv', sep=',') 

其中列代表标签(1 到 29),imNames 是通过 test_generator 的 filenames 属性获得的。最后,我使用具有最高概率值的标签生成了 csv,并计算了获得我之前写的值的准确性。

我用来解决的代码是相同的,但我使用以下代码读取和调整图像大小:

width = 299
height = 299
dim = (width, height)
images = []
# for each img
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
images.append(resized)

其中“img”是使用 skimage.io 的“imread_collection”读取的所有图像

在此先感谢您的帮助。

EDIT1:使用opencv调整大小的图像尚未使用预处理功能进行处理

1个回答

我按照这个讨论的评论中的建议解决了这个问题。我在这里粘贴我的代码:

dizionario = dict({'1': 0,
 '10': 1,
 '11': 2,
 '12': 3,
 '13': 4,
 '14': 5,
 '15': 6,
 '16': 7,
 '17': 8,
 '18': 9,
 '19': 10,
 '2': 11,
 '20': 12,
 '21': 13,
 '22': 14,
 '23': 15,
 '24': 16,
 '25': 17,
 '26': 18,
 '27': 19,
 '28': 20,
 '29': 21,
 '3': 22,
 '4': 23,
 '5': 24,
 '6': 25,
 '7': 26,
 '8': 27,
 '9': 28})

如您所见,我创建了一个字典来将类标签映射到索引。我使用 的输出final_train_generator.class_indices来创建这个字典。predict_generator我使用以下代码创建了预测的 csv 之后:

predicted_class_indices = np.argmax(predictions, axis = 1)
final_predictions = []
for element in predicted_class_indices:
  final_predictions.append(list(dizionario.keys())[list(dizionario.values()).index(element)])
df = pd.DataFrame()
df['class'] = final_predictions
df['imnames'] = imNames
df.to_csv('predictions_xception_all_data_bon.csv', sep=',')

我还在这里粘贴了我在评论中的讨论链接之后更改的代码:

test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
test_generator = test_datagen.flow_from_directory( 
    directory="./TEST/",
    target_size=(299, 299),
    color_mode="rgb",
    batch_size=20, 
    shuffle = False,
    class_mode = "categorical", 
    )
test_generator.reset()
imNames = test_generator.filenames
predictions = model_xcpetion.predict_generator(test_generator, steps=len(test_generator), verbose = 1 )