【问题标题】:How to evaluate() and predict() from generator like data in R keras如何从生成器中评估()和预测(),如 R keras 中的数据
【发布时间】:2018-01-26 09:16:06
【问题描述】:

我有以下代码。数据集可以下载herehere。该数据集包含分类为catdog 的图像。

这段代码的任务是训练猫狗图像数据。 因此,给定一张图片,它可以分辨出它是猫还是狗。 它的动机是page。下面是运行成功的代码:

library(keras)


# Organize dataset --------------------------------------------------------
#options(warn = -1)

# Ths input
original_dataset_dir <- "data/kaggle_cats_dogs/original/"


# Create new organized dataset directory ----------------------------------

base_dir <- "data/kaggle_cats_dogs_small/"
dir.create(base_dir)

train_dir <- file.path(base_dir, "train")
dir.create(train_dir)

validation_dir <- file.path(base_dir, "validation")
dir.create(validation_dir)

test_dir <- file.path(base_dir, "test")
dir.create(test_dir)

train_cats_dir <- file.path(train_dir, "cats")
dir.create(train_cats_dir)

train_dogs_dir <- file.path(train_dir, "dogs")
dir.create(train_dogs_dir)

validation_cats_dir <- file.path(validation_dir, "cats")
dir.create(validation_cats_dir)

validation_dogs_dir <- file.path(validation_dir, "dogs")
dir.create(validation_dogs_dir)

test_cats_dir <- file.path(test_dir, "cats")
dir.create(test_cats_dir)

test_dogs_dir <- file.path(test_dir, "dogs")
dir.create(test_dogs_dir)

# Copying files from original dataset to newly created directory
fnames <- paste0("cat.", 1:1000, ".jpg")
dum <- file.copy(file.path(original_dataset_dir, fnames), 
          file.path(train_cats_dir)) 


fnames <- paste0("cat.", 1001:1500, ".jpg")
dum <- file.copy(file.path(original_dataset_dir, fnames), 
          file.path(validation_cats_dir))

fnames <- paste0("cat.", 1501:2000, ".jpg")
dum <- file.copy(file.path(original_dataset_dir, fnames),
          file.path(test_cats_dir))

fnames <- paste0("dog.", 1:1000, ".jpg")
dum <- file.copy(file.path(original_dataset_dir, fnames),
          file.path(train_dogs_dir))

fnames <- paste0("dog.", 1001:1500, ".jpg")
dum <- file.copy(file.path(original_dataset_dir, fnames),
          file.path(validation_dogs_dir)) 

fnames <- paste0("dog.", 1501:2000, ".jpg")
dum <- file.copy(file.path(original_dataset_dir, fnames),
          file.path(test_dogs_dir))

options(warn = -1)

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


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


model <- keras_model_sequential() %>% 
  conv_base %>%
  layer_flatten() %>% 
  layer_dense(units = 256, activation = "relu") %>% 
  layer_dense(units = 1, activation = "sigmoid")

summary(model)

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



# Train model -------------------------------------------------------------

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
  batch_size = 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),
  batch_size = 20,
  class_mode = "binary"
)


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

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


# Fit ---------------------------------------------------------------

history <- model %>% fit_generator(
  train_generator,
  steps_per_epoch = 100,
  epochs = 30,
  validation_data = validation_generator,
  validation_steps = 50
)


# Plot --------------------------------------------------------------------
plot(history)

我的问题是我如何根据image_data_generator()flow_images_from_directory() 使用test_dir 中的数据来evaluate()predict_class() 数据。

我试过了,但没有用:

test_generator <- flow_images_from_directory(
  test_dir,                  # Target directory  
  train_datagen,              # Data generator
  target_size = c(150, 150),  # Resizes all images to 150 × 150
  batch_size = 20,
  class_mode = "binary"       # binary_crossentropy loss for binary labels
)
model %>% evaluate(test_generator, test_generator)
# Error in dim(x) <- length(x) : invalid first argument

model %>% predict_classes(test_generator)
# Error in dim(x) <- length(x) : invalid first argument

【问题讨论】:

  • 你试过evaluate_generator和predict_generator吗?如果你使用预测,你需要使用 class_mode=NULL 因为你不想传递标签
  • 与您已有的非常相似:model %>% evaluate_generator(test_generator, steps=num_test_images)
  • 还有另一个错字/问题。您对 test_generator 使用“train_datagen”而不是“test_datagen”
  • train_generator$class_indices 为您提供您的类的字典(例如,猫:0,狗:1)。有了它,您可以使用 ifelse(predictions > 0.5, 1, 0) 来获得每行 0 或 1 类。您可以根据准确度/召回率权衡选择阈值 0.5

标签: r deep-learning keras


【解决方案1】:

由于您使用的是生成器,因此您应该使用函数 evaluate_generator/predict_generator:

model %>% evaluate_generator(test_generator, steps=num_test_images)
model %>% predict_generator(test_generator, steps=num_test_images)

predict_generator 将返回一个列表或概率,您可以使用 ifelse 将其转换为类:

ifelse(predictions > 0.5, 1, 0)

train_generator$class_indices 会给你一个类索引的字典(例如 {'cat': 0, 'dog': 1})

【讨论】:

  • 为什么模型在预测这些时会返回一个带有 num_test_images * batch_size 的矩阵?当我使用 steps = Num_test_images/batch_size 进行预测时,它给出了确切的数字,但预测是错误的......我需要等待 num_test_images*batch_size 进行预测,然后获取顶部的 num_test_images 并且这些与数据集匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-30
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多