Использование пользовательской функции генератора R с помощью fit_generator (Keras, R) - PullRequest
0 голосов
/ 18 ноября 2018

Я хотел бы обучить сверточную сеть для решения многоклассовой, многокомпонентной задачи с данными изображения.Из-за характера данных и по причинам, которые я вам пощадил, было бы лучше, если бы я мог использовать пользовательскую функцию генератора R для подачи в команду fit_generator вместо ее встроенных image_data_generator и flow_images_from_directory команды (которые я успешно смог заставить работать, но не для этой конкретной проблемы).

Здесь (https://www.rdocumentation.org/packages/keras/versions/2.2.0/topics/fit_generator)) говорится, что я могу сделать это, не приводя никаких примеров.Я попробовал следующее: Вот чрезвычайно урезанный пример того, что я пытаюсь сделать (этот код полностью самодостаточен):

library(keras)
library(reticulate)      #for py_iterator function

play.network = keras_model_sequential() %>%
  layer_dense(units = 10, activation = "relu", input_shape = c(10)) %>%
  layer_dense(units = 1, activation = "relu")

play.network %>% compile(
  optimizer = "rmsprop",
  loss = "mse"
)

mikes.custom.generator.function = function()     #generates a 2-list of a random 1 x 10 array, and a scalar
{
  new.func = function()
  {
    arr = array(dim = c(1,10))
    arr[,] = sample(1:10, 10, replace = TRUE)/10
    return(list(arr,runif(1)))
  }
}

mikes.custom.iterator = py_iterator(mikes.custom.generator.function())          #creates a python iterator object

generator_next(mikes.custom.iterator)                 #correctly returns a 2-member list consisting of a 1 x 10 array, and a scalar
generator_next(mikes.custom.iterator)[[1]]            #a 1 x 10 array
generator_next(mikes.custom.iterator)[[2]]            #a scalar

#try to fit with "fit_generator":

play.network %>% fit_generator(                       #FREEZES.
  mikes.custom.iterator,
  steps_per_epoch = 1,
  epochs = 1
)

Эта вещь зависает во время обучения, не давая мне ошибкисообщение или что-то еще. Я также попробовал его с помощью специального генератора данных изображения для моей исходной задачи, тот же результат.

Обратите внимание, что эта сеть работает очень хорошо, если я просто использую fit и ввожу данные тренировки вручную:

play.network %>% fit(generator_next(mikes.custom.iterator)[[1]],generator_next(mikes.custom.iterator)[[2]], epochs = 1, batch_size = 1)      

#trains just fine

Я думаю, что знаю проблему, но не знаю решения. Если вы спросите его для класса моего пользовательского итератора, он даст

class(mikes.custom.iterator)

[1] "python.builtin.iterator"  "rpytools.generator.RGenerator"  "python.builtin.object" 

, тогда как если япостроитьИтератор, использующий встроенные команды image_data_generator и flow_images_from_directory, дает

train_datagen <- image_data_generator(rescale = 1/255)

class(train_datagen)

[1] "keras.preprocessing.image.ImageDataGenerator" "keras_preprocessing.image.ImageDataGenerator" "python.builtin.object"

train_generator <- flow_images_from_directory(
  train_dir,
  train_datagen,
  ....
)

class(train_generator)

[1] "python.builtin.iterator" "keras_preprocessing.image.DirectoryIterator" "keras_preprocessing.image.Iterator"        "tensorflow.python.keras.utils.data_utils.Sequence" "python.builtin.object"

Так что я предполагаю, что train_datagen и / или train_generator имеют атрибуты, которых у mikes.custom.iterator нет, и fit_generator пытается вызвать mikes.custom.iterator, используя функции, отличные от базовых generator_next (что в теории - это все, что действительно нужно).Но я не знаю, какими они могут быть, или как правильно построить mikes.custom.iterator даже после двухчасового поиска в Интернете.

Помогите кому-нибудь?

Ответы [ 2 ]

0 голосов
/ 05 января 2019

В R вы можете построить итератор, используя оператор <<-. Это очень полезно для создания собственной функции генератора; и он совместим с функцией fit_generator() Keras.

Некоторый минимальный пример:

# example data
data <- data.frame(
  x = runif(80),
  y = runif(80),
  z = runif(80)
)

# example generator
data_generator <- function(data, x, y, batch_size) {

  # start iterator
  i <- 1

  # return an iterator function
  function() {

    # reset iterator if already seen all data
    if ((i + batch_size - 1) > nrow(data)) i <<- 1

    # iterate current batch's rows
    rows <- c(i:min(i + batch_size - 1, nrow(data)))

    # update to next iteration
    i <<- i + batch_size

    # create container arrays
    x_array <- array(0, dim = c(length(rows), length(x)))
    y_array <- array(0, dim = c(length(rows), length(y)))

    # fill the container
    x_array[1:length(rows), ] <- data[rows, x]
    y_array[1:length(rows), ] <- data[rows, y]

    # return the batch
    list(x_array, y_array)

  }

}

# set-up a generator
gen <- data_generator(
  data = data.matrix(data),
  x = 1:2, # it is flexible, you can use the column numbers,
  y = c("y", "z"), # or the column name
  batch_size = 32
)

Функция выше, вы можете просто проверить полученные массивы, вызвав генератор:

gen()

Или вы также можете протестировать генератор, используя простую модель Keras:

# import keras
library(keras)

# set up a simple keras model
model <- keras_model_sequential() %>% 
  layer_dense(32, input_shape = c(2)) %>% 
  layer_dense(2)

model %>% compile(
  optimizer = "rmsprop",
  loss = "mse"
)

# fit using generator
model %>% fit_generator(
  generator = gen,
  steps_per_epoch = 100, # will auto-reset after see all sample
  epochs = 10
)

Я должен признать, что этот процесс немного сложен и требует обширного программирования. Вам следует проверить это избранное сообщение в блоге самого Франсуа Шоле или пакета kerasgenerator, который я разрабатываю лично.

0 голосов
/ 12 декабря 2018
sampling_generator <- function(X_data, Y_data, batch_size) {
  function() {
    rows <- sample(1:nrow(X_data), batch_size, replace = TRUE)
    list(X_data[rows,], Y_data[rows,])
  }
}

model %>% 
  fit_generator(sampling_generator(X_train, Y_train, batch_size = 128), 
            steps_per_epoch = nrow(X_train) / 128, epochs = 10)

Я нашел этот ответ в FAQ по R keras, который, кажется, работает

https://keras.rstudio.com/articles/faq.html#how-can-i-use-keras-with-datasets-that-dont-fit-in-memory

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...