Mik*_*ley 1 r image generator keras
我想训练一个卷积网络来解决图像数据上的多类、多标签问题。由于数据的性质和原因,我就不告诉你,这将是最好的,如果我可以使用自定义[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
)
Run Code Online (Sandbox Code Playgroud)
事情在训练时冻结,没有给我任何错误信息或任何东西。我还针对我的原始问题使用自定义图像数据生成器进行了尝试,结果相同。
请注意,如果我只是fit
手动使用和输入训练数据,则该网络训练得很好:
play.network %>% fit(generator_next(mikes.custom.iterator)[[1]],generator_next(mikes.custom.iterator)[[2]], epochs = 1, batch_size = 1)
#trains just fine
Run Code Online (Sandbox Code Playgroud)
我想我知道问题所在,但我不知道解决方案。如果您向它询问我的自定义迭代器的类,它会给出
class(mikes.custom.iterator)
[1] "python.builtin.iterator" "rpytools.generator.RGenerator" "python.builtin.object"
Run Code Online (Sandbox Code Playgroud)
而如果我使用内置函数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"
Run Code Online (Sandbox Code Playgroud)
所以我的猜测是train_datagen
和/或train_generator
具有mikes.custom.iterator
不具有的属性,并且fit_generator
试图调用mikes.custom.iterator
使用除基本函数以外的函数generator_next
(理论上这是它真正需要的全部)。但mikes.custom.iterator
即使在网上搜索了两个小时后,我也不知道它们可能是什么,或者如何正确构建。
帮助任何人?
在 R 中,您可以使用<<-
运算符构建迭代器。这对构建自定义生成器函数非常有帮助;并且兼容 Keras 的fit_generator()
功能。
一些最小的例子:
# 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
)
Run Code Online (Sandbox Code Playgroud)
从上面的函数中,您可以通过调用生成器来简单地检查结果数组:
gen()
Run Code Online (Sandbox Code Playgroud)
或者您也可以使用简单的 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
)
Run Code Online (Sandbox Code Playgroud)
我不得不承认这个过程有点复杂,需要大量的编程。您应该查看François Chollet本人撰写的这篇特色博客文章,或kerasgenerator
我个人开发的软件包。