在Keras模型中,当列车和验证样本很小时如何测量过度拟合

pdu*_*ois 9 r machine-learning neural-network deep-learning keras

我有以下情节:

在此输入图像描述

使用以下数量的样本创建模型:

                class1     class2
train             20         20
validate          21         13
Run Code Online (Sandbox Code Playgroud)

根据我的理解,情节显示没有过度拟合.但我认为,由于样本非常小,我不确定该模型是否足够通用.

除上述情节外,还有其他方法可以测量过度拟合吗?

这是我的完整代码:

library(keras)
library(tidyverse)


train_dir <- "data/train/"
validation_dir <- "data/validate/"



# Making model ------------------------------------------------------------


conv_base <- application_vgg16(
  weights = "imagenet",
  include_top = FALSE,
  input_shape = c(150, 150, 3)
)

# VGG16 based model -------------------------------------------------------

# Works better with regularizer
model <- keras_model_sequential() %>%
  conv_base() %>%
  layer_flatten() %>%
  layer_dense(units = 256, activation = "relu", kernel_regularizer = regularizer_l1(l = 0.01)) %>%
  layer_dense(units = 1, activation = "sigmoid")

summary(model)

length(model$trainable_weights)
freeze_weights(conv_base)
length(model$trainable_weights)


# Train model -------------------------------------------------------------
desired_batch_size <- 20 

train_datagen <- image_data_generator(
  rescale = 1 / 255,
  rotation_range = 40,
  width_shift_range = 0.2,
  height_shift_range = 0.2,
  shear_range = 0.2,
  zoom_range = 0.2,
  horizontal_flip = TRUE,
  fill_mode = "nearest"
)

# Note that the validation data shouldn't be augmented!
test_datagen <- image_data_generator(rescale = 1 / 255)


train_generator <- flow_images_from_directory(
  train_dir, # Target directory
  train_datagen, # Data generator
  target_size = c(150, 150), # Resizes all images to 150 × 150
  shuffle = TRUE,
  seed = 1,
  batch_size = desired_batch_size, # was 20
  class_mode = "binary" # binary_crossentropy loss for binary labels
)

validation_generator <- flow_images_from_directory(
  validation_dir,
  test_datagen,
  target_size = c(150, 150),
  shuffle = TRUE,
  seed = 1,
  batch_size = desired_batch_size,
  class_mode = "binary"
)

# Fine tuning -------------------------------------------------------------

unfreeze_weights(conv_base, from = "block3_conv1")

# Compile model -----------------------------------------------------------



model %>% compile(
  loss = "binary_crossentropy",
  optimizer = optimizer_rmsprop(lr = 2e-5),
  metrics = c("accuracy")
)


# Evaluate  by epochs  ---------------------------------------------------------------


#  # This create plots accuracy of various epochs (slow)
history <- model %>% fit_generator(
  train_generator,
  steps_per_epoch = 100,
  epochs = 15, # was 50
  validation_data = validation_generator,
  validation_steps = 50
)

plot(history)
Run Code Online (Sandbox Code Playgroud)

Mar*_*jko 10

这里有两件事:

  1. 对您的数据进行分层 - 您的验证数据与您的训练集具有完全不同的类分布(训练集是平衡的而验证集 - 不是).这可能会影响您的损失和指标值.最好对结果进行分层,这样两组的类比率都是相同的.

  2. 如此少的数据点使用更粗略的验证模式 - 您可能会看到总共只有74个图像.在这种情况下 - 将所有图像加载到numpy.array(您仍然可以使用flow函数进行数据扩充)并使用在文件夹中存储数据时很难获得的验证模式不是问题.sklearn我建议你使用的模式(from )是:

    • 分层k折交叉验证 - 你将数据划分为k个块 - 并且对于 k-1个块的每个选择- 首先在 k-1上训练你的模型,然后计算留给验证的那个的度量.最终结果是在验证块上获得的结果的平均值.当然,您不仅可以检查平均值,还可以检查损失分布的其他统计数据(例如,最小值,最大值,中位数等).您还可以将它们与每个折叠的训练集上获得的结果进行比较.
    • 留一法 - 这是先前架构的一个特例 - 其中 /折叠的数量等于数据集中的示例数.这种方法被认为是衡量模型性能的最粗略方法.它很少用于深度学习,因为训练过程通常很慢,数据集很大,以便在合理的时间内完成计算.


小智 5

我建议将预测视为下一步.

例如,从顶部图和所提供样本的数量来判断,您的验证预测在两个准确度之间波动,并且这些预测之间的差异恰好是一个猜测正确的样本.

因此,您的模型预测或多或少相同的结果(正负一个观察)与拟合无关.这是一个不好的迹象.

而且,对于所提供的样本数量,特征的数量和可训练参数(权重)太高.所有这些重量都没有机会实际接受训练.


Ale*_*vic 5

您的验证损失始终低于培训损失.我对你的结果非常怀疑.如果你看一下验证的准确性,它就不应该那样.

数据越少,对任何事物的信心就越小.所以当你不确定过度拟合时,你是对的.这里唯一有用的是通过数据扩充或与其他数据集结合来收集更多数据.