【问题标题】:Error using predict_generator with custom generator in Keras R interface在 Keras R 界面中将 predict_generator 与自定义生成器一起使用时出错
【发布时间】:2018-01-31 22:04:43
【问题描述】:

我一直在阅读使用 R 进行深度学习,在第 6 章中介绍了生成器。以下是产生(样本、输出)的生成器,在 fit_generator 或评估生成器中使用时没有问题:

generator <- function(data, lookback, delay, min_index, max_index,
                      shuffle = FALSE, batch_size = 60, step = 1) {
  if (is.null(max_index))
    max_index <- nrow(data) - delay - 1
  i <- min_index + lookback
  function() {
    if (shuffle) {
      rows <- sample(c( (min_index+lookback) : max_index ), size = batch_size)
    } else {
      if (i + batch_size >= max_index)
        i <<- min_index + lookback
      rows <- c(i : min(i + batch_size - 1, max_index))
      rows
      length(rows)
      i <<- i + length(rows)
    }

    samples <- array(0, dim = c(length(rows), 
                                lookback / step,
                                dim(data)[[-1]]))
    targets <- array(0, dim = c(length(rows)))

    for (j in 1:length(rows)) {
      indices <- seq(rows[[j]] - lookback, rows[[j]], 
                     length.out = dim(samples)[[2]])
      samples[j,,] <- data[indices,]
      targets[[j]] <- data[rows[[j]] + delay, 9]
    }            

    list(samples, targets)
  }
}

test_gen <- generator(
  data,
  lookback = lookback,
  delay = delay,
  min_index = validation_index+1,
  max_index = NULL,
  step = step,
  batch_size = batch_size
)
## no issues here
test_steps <- (nrow(data) - validation_index+1 - lookback) / batch_size
perf <- my_model %>% evaluate_generator(test_gen, steps = test_steps)

但是,当尝试将生成器更改为仅生成样本时:

generator_pred <- function(data, lookback, delay, min_index, max_index,
                      shuffle = FALSE, batch_size = 60, step = 1) {
  if (is.null(max_index))
    max_index <- nrow(data) - delay - 1
  i <- min_index + lookback
  function() {
    if (shuffle) {
      rows <- sample(c( (min_index+lookback) : max_index ), size = batch_size)
    } else {
      if (i + batch_size >= max_index)
        i <<- min_index + lookback
      rows <- c(i : min(i + batch_size - 1, max_index))
      rows
      length(rows)
      i <<- i + length(rows)
    }

    samples <- array(0, dim = c(length(rows), 
                                lookback / step,
                                dim(data)[[-1]]))

    for (j in 1:length(rows)) {
      indices <- seq(rows[[j]] - lookback, rows[[j]], 
                     length.out = dim(samples)[[2]])
      samples[j,,] <- data[indices,]
    }            
    samples
  }
}

test_gen_pred <- generator_pred(
      data,
      lookback = lookback,
      delay = delay,
      min_index = validation_index+1,
      max_index = NULL,
      step = step,
      batch_size = batch_size
    )

test_steps <- (nrow(data) - validation_index+1 - lookback) / batch_size
predict_generator(my_model, test_gen_pred, steps = test_steps)

我收到一个关于等效 python 生成器返回一个用于比较的数组的错误:

Exception in thread Thread-1064:
Traceback (most recent call last):
  File "C:\Users\PBORDE~1\AppData\Local\CONTIN~1\ANACON~1\envs\R-TENS~1\lib\threading.py", line 916, in _bootstrap_inner
    self.run()
  File "C:\Users\PBORDE~1\AppData\Local\CONTIN~1\ANACON~1\envs\R-TENS~1\lib\threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\PBORDE~1\AppData\Local\CONTIN~1\ANACON~1\envs\R-TENS~1\lib\site-packages\keras\utils\data_utils.py", line 579, in data_generator_task
    generator_output = next(self._generator)
  File "C:/Users/pbordeaux/Documents/R/win-library/3.4/reticulate/python\rpytools\generator.py", line 23, in __next__
    return self.next()
  File "C:/Users/pbordeaux/Documents/R/win-library/3.4/reticulate/python\rpytools\generator.py", line 39, in next
    if (res == self.completed):
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

我读到生成器必须返回 predict_on_batch 作为输入的相同对象。我成功运行了以下内容:

test_gen_pred <- generator_pred(
  data,
  lookback = lookback,
  delay = delay,
  min_index = validation_index+1,
  max_index = NULL,
  step = step,
  batch_size = batch_size
)

t <- test_gen_pred()
predict_on_batch(my_model, t)

生成器接口是否未正确实现?我检查了当 test_gen_pred() 被调用时,它返回了一个形状正确的张量,并且确实如此,因为我可以通过它的调用成功调用 predict_on_batch。

【问题讨论】:

    标签: r keras


    【解决方案1】:

    您也可以使用kerasgenerator 包中的series_generator(),如果您想将其用于预测,它会提供return_target 选项。

    一些简单的例子

    首先进行一些监督设置:

    # example data
    data <- data.frame(
      x = runif(80),
      y = runif(80),
      z = runif(80)
    )
    
    # variables
    x <- c("x", "y")
    y <- 2:3
    
    # supervise settings
    lookback <- 10
    timesteps <- 10
    
    # number of train sample
    train_length <- 40
    
    # data settings
    batch_size <- 10
    
    # train row indices
    train_end <- nrow(data)
    train_start <- train_end - train_length + 1
    
    # number of steps to see full data
    train_steps <- train_length / batch_size
    

    然后你可以像这样定义生成器:

    # import libs
    library(kerasgenerator)
    
    # train generator
    train_gen <- series_generator(
      data = data,
      y = y,
      x = x,
      lookback = lookback,
      timesteps = timesteps,
      start_index = train_start,
      end_index = train_end,
      batch_size = batch_size,
      return_target = TRUE
    )
    
    # predict generator
    predict_gen <- series_generator(
      data = data,
      y = y,
      x = x,
      lookback = lookback,
      timesteps = timesteps,
      start_index = train_start,
      end_index = train_end,
      batch_size = batch_size,
      return_target = FALSE
    )
    

    让我们在示例模型上尝试数据生成器:

    # import libs
    library(keras)
    
    # initiate a sequential model
    model <- keras_model_sequential()
    
    # define the model
    model %>%
    
      # layer lstm
      layer_lstm(
        name = "lstm",
        input_shape = list(timesteps, length(x)),
        units = 16,
        dropout = 0.1,
        recurrent_dropout = 0.1,
        return_sequences = FALSE
      ) %>%
    
      # layer output
      layer_dense(
        name = "output",
        units = length(y)
      )
    
    # compile the model
    model %>% compile(
      optimizer = "rmsprop",
      loss = "mse"
    )
    
    # model summary
    summary(model)
    
    # set number of epochs
    epochs <- 10
    
    # model fitting
    history <- model %>% fit_generator(
      generator = train_gen,
      steps_per_epoch = train_steps,
      epochs = epochs
    )
    
    # history plot
    plot(history)
    
    # evaluate on train dataset
    model %>% evaluate_generator(
      generator = train_gen,
      steps = train_steps
    )
    
    # predict on train dataset
    model %>% predict_generator(
      generator = predict_gen,
      steps = train_steps
    )
    

    如果您对预测感兴趣,它也提供forecast_generator()。有关完整示例,请参阅 vignettes

    免责声明:我是包的作者。

    【讨论】:

      【解决方案2】:

      我这几天一直在寻找完全相同的答案,终于通过让我的 pred_generator 返回一个 list(而不是直接的样本)来让它工作!

      在你的情况下:

      generator_pred <- function(data, lookback, delay, min_index, max_index,
                        shuffle = FALSE, batch_size = 60, step = 1) {
          <...>            
          list(samples)
        }
      }
      

      【讨论】:

      • 谢谢!我最终完全使用了不同的设置,因为我无法让它工作。非常感谢
      • @pbordeaux 你能分享一下你是怎么解决的吗?
      猜你喜欢
      • 2011-05-16
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-20
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多