【问题标题】:How to write a Data Generator for a Keras model using multiple inputs如何使用多个输入为 Keras 模型编写数据生成器
【发布时间】:2020-01-05 13:22:14
【问题描述】:

我需要一些帮助才能让 Keras 模型在 RStudio 中工作。当我有多个输入并使用数据生成器时,就会出现问题。

Keras 报告输入错误。传递给模型的 numpy 数组不是它所期望的。

以下玩具示例重现了该问题。当模型正常拟合时(没有数据生成器),它运行正常,但当安装了生成器时,它会崩溃。

设置数据

library(magrittr)
library(keras)

# Create 10 examples of input data and 10 labels

input1 <- matrix(1:20,  ncol=2, nrow=10, byrow=T)   # [1,2; 3,4; 5,6 ... 19,20]
input2 <- matrix(1:30,  ncol=3, nrow=10, byrow=T)    # [1,2,3; 4,5,6 5,6,7 ... 28,29,30]
labels <- seq(0.1,1,0.1)                            # [0,1,0.2,0.3 ... 1.0]

构建和运行模型

# define input tensors for the two inputs
in_a <- layer_input(shape = c(2), name = "input1")
in_b <- layer_input(shape = c(3), name = "input2")

# concatenate the inputs and follow them by an output layer
out <- layer_concatenate(c(in_a, in_b), axis=-1, name="concat") %>% 
  layer_dense(units = 1, activation = 'linear', name="output")

# build the model
model <- keras_model(inputs = list(in_a, in_b), outputs = out)

#compile & run
model %>% compile(loss = "mse", optimizer = "adam")
model %>% fit(list(input1, input2), labels, epochs = 5)

带生成器的模型

# The generator will alternatively select the first five input rows and then the second five ad infinitum
data_sample_generator <- function(input1, input2, labels) {

  first_five <- 1

  function() {

    first_five <<- ifelse(first_five == 0,1,0)

    if (first_five==0) {
      rows_to_return <- 1:5 }
    else {
      rows_to_return <- 6:10
    }
  return(list(input1[rows_to_return, ], input2[rows_to_return, ], labels[rows_to_return])) 
    }


}
# Examine generator output
batch <- data_sample_generator(input1, input2, labels)
batch()

# Examine generator output
batch <- data_sample_generator(input1, input2, labels)

batch()    # first sample
[[1]]
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10

[[2]]
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12
[5,]   13   14   15

[[3]]
[1] 0.1 0.2 0.3 0.4 0.5
batch()    # second sample
[[1]]
     [,1] [,2]
[1,]   11   12
[2,]   13   14
[3,]   15   16
[4,]   17   18
[5,]   19   20

[[2]]
     [,1] [,2] [,3]
[1,]   16   17   18
[2,]   19   20   21
[3,]   22   23   24
[4,]   25   26   27
[5,]   28   29   30

[[3]]
[1] 0.6 0.7 0.8 0.9 1.0

这就是我希望从生成器中看到的。现在来拟合模型。


model %>% 
  fit_generator(data_sample_generator(input1,input2,labels),
                steps_per_epoch = 2,
                epochs = 5)
Error in py_call_impl(callable, dots$args, dots$keywords) :   
ValueError: Error when checking model input: the list of Numpy arrays that  
you are passing to your model is not the size the model expected.   
Expected to see 2 array(s),   
but instead got the following list of 1 arrays: 
[array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10]])]...

我不确定我在这里做错了什么。如何修复生成器以提供正确形状的输入?感谢您的帮助。

修改生成器输出

按照@OIDor 的建议,将输出更改为返回 ([input1, input2], labels)

return(list(list(input1[rows_to_return, ], input2[rows_to_return, ]), labels[rows_to_return]))

发电机返回

[[1]]
[[1]][[1]]
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10

[[1]][[2]]
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12
[5,]   13   14   15

[[2]]
[1] 0.1 0.2 0.3 0.4 0.5

这一次,我收到错误消息 ValueError: could not broadcast input array from shape (5,2) into shape (5)

【问题讨论】:

    标签: r input keras generator


    【解决方案1】:

    生成器应该返回一个 tuple2d:

     (X, y)
    

    在你的情况下 X 是一个数组列表,所以它变成:

    ([X1, X2], y)
    

    您的生成器产生:

    list(input1[rows_to_return, ], input2[rows_to_return, ], labels[rows_to_return])
    

    相当于:

    ([X1, X2, y])
    

    我不知道R,但我认为你应该把你的生成器改成这样:

    list(input1[rows_to_return, ], input2[rows_to_return, ]), labels[rows_to_return]
    

    更新:

    现在您已经更新了代码,您传递给模型的输入形状是:

    第一个输入:(5, 2)

    第二个输入:(5, 3)

    输出:(5)

    Keras 错误表明您的模型期望将第一个输入视为(例如):

    [1, 3, 5, 7, 9] 
    

    当你经过时:

    [[1, 3, 5, 7, 9],
    [2, 4, 6, 8, 10]]
    

    所以你应该要么改变你的批处理生成器,要么改变模型的输入形状

    【讨论】:

    • 感谢@OIDor。我看到了问题。我尝试了您的建议(请参阅编辑),但现在我收到错误消息“无法将输入数组从形状 (5,2) 广播到形状 (5)”。
    • 感谢@OIDor。我会试试看。
    猜你喜欢
    • 2020-01-31
    • 2019-03-16
    • 2023-04-07
    • 2018-05-15
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    相关资源
    最近更新 更多