2

Directly below is an example that works followed by ones that don't.

library(keras)

# placeholder data
Y <- data.frame(y1=1:100,y2=1:100)
X <- data.frame(x1=1:100,x2=1:00,x3=1:100)

# add covariates
input <- layer_input(shape=dim(X)[2],name="covars")

# add hidden layers
base_model <- input  %>%
  layer_dense(units = 3, activation='relu') %>%
  layer_dense(units = 2, activation='relu') 

# add outputs
y1 <- base_model %>% 
  layer_dense(units = 1, name="y1") 

y2 <- base_model %>% 
  layer_dense(units = 1, name="y2") 

# combine
model <- keras_model(input,list(y1,y2))

This is simple case where there are only two outputs. What about the case with many outputs and you don't want to script each one like I did above for y1 and y2? This adds the outputs in a loop:

# add outputs in loop
for(i in 1:dim(Y)[2]){
  y <- colnames(Y)[i]
  outstring <- paste0(
    sprintf("%s <- base_model %%>%%", y), 
    sprintf(" layer_dense(units = 1, name='%s')",y)
  )
  eval(parse(text=outstring))
}

But I cannot figure out how to pass a list of the outputs to the compile function. This attempt:

Ylist <- do.call(c, apply(Y, 2, list))
model <- keras_model(input,Ylist)

Returns the following error:

Error in py_call_impl(callable, dots$args, dots$keywords) : 
  TypeError: unhashable type: 'list' 

I also tried keras_array():

model <- keras_model(input,keras_array(Ylist))

Which returned:

Error in py_call_impl(callable, dots$args, dots$keywords) : 
  TypeError: unhashable type: 'numpy.ndarray' 

I am okay with not naming the outputs if there is a way around my for-loop that uses sprintf(). The problem I am working on has over 20 outputs I want to predict simultaneously.

Blundering Ecologist
  • 1,199
  • 2
  • 14
  • 38
Scott Worland
  • 1,352
  • 1
  • 12
  • 15

1 Answers1

1

This works,

Ylist <- paste0("list(",paste(colnames(Y),sep="",collapse=","),")")
model <- keras_model(input,eval(parse(text=Ylist)))
Scott Worland
  • 1,352
  • 1
  • 12
  • 15