Python 具有高精度但低val_acc的Keras模型

Python 具有高精度但低val_acc的Keras模型,python,tensorflow,keras,deep-learning,Python,Tensorflow,Keras,Deep Learning,我正在使用牛津IIIT宠物数据集的resnet50转移学习对37种猫和狗进行分类。其思想是使用Keras代码密切跟踪fastai实现。然而,我成功地获得了高达90%的训练准确率,但似乎无法将我的val_准确率提高到高于随机猜测的水平(1/37或~3%val_acc) 知道Keras如何计算验证acc吗?我如何改进它?还是我的预处理步骤有问题?非常感谢 为了获得验证步骤,我使用sklearn StratifiedShuffleSplit获得一个平衡的验证集 # Create dataframe w

我正在使用牛津IIIT宠物数据集的resnet50转移学习对37种猫和狗进行分类。其思想是使用Keras代码密切跟踪fastai实现。然而,我成功地获得了高达90%的训练准确率,但似乎无法将我的val_准确率提高到高于随机猜测的水平(1/37或~3%val_acc)

知道Keras如何计算验证acc吗?我如何改进它?还是我的预处理步骤有问题?非常感谢

为了获得验证步骤,我使用sklearn StratifiedShuffleSplit获得一个平衡的验证集

# Create dataframe with labels and filenames
annotations = pd.read_csv("annotation/list.txt",header=None,delim_whitespace=True)

annotations.drop([1,2,3],axis=1, inplace=True)
annotations.columns = ["filenames"]

# Create label columns
trans = str.maketrans("_0123456789","           ")
annotations["labels"] = annotations["filenames"].str.translate(trans).str.strip()
annotations["filenames"] = annotations["filenames"] +".jpg" 

然后,构建我的生成器并训练我的模型

from tensorflow.keras.preprocessing.image import ImageDataGenerator

bs = 64

def normalize(x):
  imagenet_mean = np.array([0.485, 0.456, 0.406]).reshape(1,1,3)
  imagenet_sd = np.array([0.229, 0.224, 0.225]).reshape(1,1,3)
  return (x- imagenet_mean)/imagenet_sd



train_datagen = ImageDataGenerator(rescale=1/255.,
                                  horizontal_flip = True,
                                  rotation_range=10,
                                  width_shift_range = 0.1,
                                  height_shift_range =0.1,
                                  brightness_range =(0.9,1.1),
                                  shear_range =0.1,
                                  preprocessing_function=normalize)

train_generator = train_datagen.flow_from_dataframe(dataframe=annotations,
                                                   directory =os.getcwd(),
                                                   x_col="filenames",
                                                   y_col="labels",
                                                   target_size = (224,224),
                                                   batch_size = bs,
                                                   )


val_datagen = ImageDataGenerator(rescale=1/255.,
                                preprocessing_function=normalize)

validation_generator = val_datagen.flow_from_dataframe(dataframe=validation,
                                                   directory =os.getcwd(),
                                                   x_col="filenames",
                                                   y_col="labels",
                                                   target_size = (224,224),
                                                   batch_size=bs,
                                                   )


from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras import optimizers
from tensorflow.keras import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Flatten, BatchNormalization, Dropout


base_model = ResNet50(include_top=False,weights="imagenet")
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Flatten()(x)
x = BatchNormalization(epsilon=1e-05,momentum=0.1)(x)
x = Dropout(0.25)(x)
x = Dense(512,activation="relu")(x)
x = BatchNormalization(epsilon=1e-05,momentum=0.1)(x)
x = Dropout(0.5)(x)
predictions = Dense(37,activation="softmax")(x)

model = Model(inputs=base_model.input,outputs=predictions)

for layer in base_model.layers:
    layer.trainable = False

lr= 0.001
opti = optimizers.Adam(lr=lr, decay=lr/50)
model.compile(optimizer=opti,
             loss="categorical_crossentropy",
             metrics=["accuracy"])

model.fit_generator(train_generator,
                   epochs=10,
                   validation_data = validation_generator)

for layer in base_model.layers:
    layer.trainable = True

model.fit_generator(train_generator,
                   epochs=10,
                   validation_data = validation_generator)


你不是在洗牌你的数据。如果将
shuffle=True
参数传递到
model.fit\u生成器中,会发生什么情况?如果没有,请尝试通过
steps\u per\u epoch=len(序列生成器)//bs
validation\u steps=len(序列生成器)//bs
。高序列精度和低验证精度通常是过度拟合的样子-您是否做了任何检查,以检查情况是否如此?这看起来像一个相当大的模型,你试过更小的吗?如果我们能看到一个模型也会有所帮助。summary()对于这一点,如果拟合过度,我认为我的val_acc应该在下降之前增加,但自第一个纪元以来,它还没有从3-4%移走。我不得不尝试洗牌,这是我的第一个想法,但我认为洗牌的默认设置是正确的。我将再次更新SHUGFLE和step_per_epoch不工作。还有其他建议吗?@Beneblau,请您提供注释数据(如果不是机密的话),以便我们可以尝试重现您的问题,然后努力解决。谢谢
from tensorflow.keras.preprocessing.image import ImageDataGenerator

bs = 64

def normalize(x):
  imagenet_mean = np.array([0.485, 0.456, 0.406]).reshape(1,1,3)
  imagenet_sd = np.array([0.229, 0.224, 0.225]).reshape(1,1,3)
  return (x- imagenet_mean)/imagenet_sd



train_datagen = ImageDataGenerator(rescale=1/255.,
                                  horizontal_flip = True,
                                  rotation_range=10,
                                  width_shift_range = 0.1,
                                  height_shift_range =0.1,
                                  brightness_range =(0.9,1.1),
                                  shear_range =0.1,
                                  preprocessing_function=normalize)

train_generator = train_datagen.flow_from_dataframe(dataframe=annotations,
                                                   directory =os.getcwd(),
                                                   x_col="filenames",
                                                   y_col="labels",
                                                   target_size = (224,224),
                                                   batch_size = bs,
                                                   )


val_datagen = ImageDataGenerator(rescale=1/255.,
                                preprocessing_function=normalize)

validation_generator = val_datagen.flow_from_dataframe(dataframe=validation,
                                                   directory =os.getcwd(),
                                                   x_col="filenames",
                                                   y_col="labels",
                                                   target_size = (224,224),
                                                   batch_size=bs,
                                                   )


from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras import optimizers
from tensorflow.keras import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Flatten, BatchNormalization, Dropout


base_model = ResNet50(include_top=False,weights="imagenet")
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Flatten()(x)
x = BatchNormalization(epsilon=1e-05,momentum=0.1)(x)
x = Dropout(0.25)(x)
x = Dense(512,activation="relu")(x)
x = BatchNormalization(epsilon=1e-05,momentum=0.1)(x)
x = Dropout(0.5)(x)
predictions = Dense(37,activation="softmax")(x)

model = Model(inputs=base_model.input,outputs=predictions)

for layer in base_model.layers:
    layer.trainable = False

lr= 0.001
opti = optimizers.Adam(lr=lr, decay=lr/50)
model.compile(optimizer=opti,
             loss="categorical_crossentropy",
             metrics=["accuracy"])

model.fit_generator(train_generator,
                   epochs=10,
                   validation_data = validation_generator)

for layer in base_model.layers:
    layer.trainable = True

model.fit_generator(train_generator,
                   epochs=10,
                   validation_data = validation_generator)

By the 10 epochs before unfreezing my layers

loss = 0.2189
acc = 0.9255
val_loss = 5.5082
val_acc = 0.0401