如何在R Keras中复制DNN而不重复使用层名称

lsmd5eda  于 2023-06-03  发布在  其他
关注(0)|答案(1)|浏览(107)

TLDR:

这个问题几乎就在标题中。我知道如何在python中更改图层名称,如图所示。此处:
[https://stackoverflow.com/questions/49550182/keras-rename-model-and-layers.](https://stackoverflow.com/questions/49550182/keras-rename-model-and-layers.%5C)然而,在r中这样做并不起作用。像model$input$name <- "Input_1"这样的东西会导致错误Error: AttributeError: can't set attribute,而在R中,层没有我可以编辑的_name
尝试使用attr(model$input, "name") <- "Input_1更改属性也不起作用,导致错误消息:
Error: AttributeError: Can't set the attribute "input", likely because it conflicts with an existing read-only @property of the object. Please choose a different name.
这似乎是一个相当明显和常见的问题,但我找不到任何关于如何在R中做到这一点的文档。任何建议都很感激。

有关如何解决此问题的更多上下文:

我正在做一个项目,需要在一个更大的模型中重用某些子模型,如下面的最小工作示例所述:

library(tensorflow)
library(keras)

inputs <- layer_input(shape = 1, name = "Input")

output <- inputs %>%
  layer_dense(units = 1, activation = "linear")
linear_model <- keras_model(inputs, output)

output <- inputs %>%
  layer_dense(units = 32, activation = "relu") %>%
  layer_dense(units = 1, activation = "linear")
deep_model <- keras_model(inputs, output)

linear_clone <- clone_model(linear_model)
output <- layer_concatenate(list(linear_clone$output,
                                 deep_model$output)) %>%
  layer_dense(1, use_bias = FALSE)
deep_model_adapted <- keras_model(list(linear_clone$input, inputs), output)

最后一行导致错误Error: ValueError: The name "Input" is used 2 times in the model. All layer names should be unique.。我理解此错误消息。我不知道如何规避这一点。我知道我可以简单地将linear_model连接到deep_model_adapted。然而,在最终的应用程序中,linear_modellinear_clone将具有不同的权重,这使得这种方法不适用。如果有一个替代clone_model的方法,可以让我指定新的层名或生成新的层名(尚未使用,在创建新层时默认情况下是这样做的),这也可以回答我的问题。

5kgi1eie

5kgi1eie1#

虽然这并没有回答最初的问题,但我设法自己解决了潜在的问题,方法是迭代复制DNN的每一层,并使用内置工具创建新名称,该工具只选择尚未使用的名称。
我的解决方案只适用于相应函数中指定的层类型,但它们可以通过简单地将它们包含在clone_layer_newName函数中来适应其他层。无论如何,我相信任何头脑正常的人都宁愿修改r-keras代码本身,而不是这样做,但也许有人会发现这很有用。这甚至适用于涉及多个层的连接的相当复杂的架构。

clone_layer_newName <- function(original_layer)
{
  layerName <- original_layer$name
  if(str_detect(layerName, "Input"))
  {
    return(layer_input(shape = original_layer$input_shape[[1]][[2]]))
  }
  else
  {
    inboundNodes <- original_layer$inbound_nodes[[1]]$inbound_layers
    if(str_detect(layerName, "dense"))
    {
      return(clone_layer_newName(inboundNodes) %>%
               layer_dense(units = original_layer$get_config()$units,
                           activation = original_layer$get_config()$activation,
                           use_bias = original_layer$get_config()$use_bias,
                           input_shape = original_layer$input_shape[[2]]))
    }else if(str_detect(layerName, "dropout"))
    {
      return(clone_layer_newName(inboundNodes) %>%
               layer_dropout(rate = original_layer$get_config()$rate,
                             input_shape = original_layer$get_config()$batch_input_shape[[2]]))
    }else if(str_detect(layerName, "concatenate"))
    {
      return(layer_concatenate(lapply(inboundNodes,
                                      clone_layer_newName) %>% unlist()))
    }
  }
  # layerName <- original_layer$name
  # new_layer <- layer_dense(clone_layer_newName(inboundLayers))
}
findInput <- function(currentInput)
{
  if(str_detect(currentInput$node$layer$name, "input"))
  {
    return(currentInput)
  }else
  {
    if(is.list(currentInput$node$layer$input))
    {
      return(lapply(currentInput$node$layer$input, findInput))
    }else
    {
      return(findInput(currentInput$node$layer$input))
    }
  }
  lapply(currentInput$layer$node, findInput)
}
clone_model_newNames <- function(original_model)
{
  newOutput <-
    clone_layer_newName(original_model$layers[[length(original_model$layers)]])
  newInput <- findInput(newOutput$node$layer$input)
  newModel <- keras_model(newInput, newOutput)
  newModel %>% set_weights(original_model %>% get_weights())
  return(newModel)
}

相关问题