r-将S4插槽设置为功能并表示神经网络层



我正试图在R中编写一些类。这是一个神经网络层类的开始。它正在生成我不知道如何更正的警告和错误。

# Slot definitions
setClass(
 Class="neuralNetworkLayer",
 representation=representation(
   input = "vector",
   linearOutput = "vector",
   squashedOutput = "vector",
   hasBias = "logical",
   bias = "vector",
   weights = "vector",
   gains = "matrix",
   squashFcn = "closure",
   squashFcnDerivative = "closure"
 )
)
# Constructors
NeuralNetworkLayer <- function(nInput,nOutput,hasBias=TRUE,squashFcn,squashFcnDerivative) {
  nc = list(
    input = c(rep(NA,nInput)),
    linearOutput = c(rep(NA,nOutput)),
    squashedOutput = c(rep(NA,nOutput)),
    hasBias = hasBias,
    bias = c(rep(NA,nOutput)),
    weights = c(rep(NA,nOutput)),
    gain = matrix(data=weights, nrow = nInput, ncol = nOutput),
    squashFcn = squashFcn,   # source of warning / error
    squashFcnDerivative = squashFcnDerivative,
    get = function(x) nc[[x]],
    set = function(x, value) nc[[x]] <<- value,
    props = list()
  )
  #Add a few more functions
  nc$addProp = function(name, value) {
    p <- nc$props
    p[[name]] <- value
    assign('props', p, envir=nc)
  }
  nc <- list2env(nc)
  class(nc) <- "NeuralNetwork"
  return(nc)
}
  tanhDerivative <- function(x) {
    d = 1 - tan(x)^2  
    return(d)
  }
  test <- NeuralNetworkLayer(nInput=4,nOutput=5,hasBias=TRUE,
                             squashFcn=tanh,squashFcnDerivative=tanhDerivative)

生成的消息是

Warning message:
undefined slot classes in definition of "neuralNetworkLayer": squashFcn(class "closure"),
squashFcnDerivative(class "closure")
Error in as.vector(x, mode) : 
  cannot coerce type 'closure' to vector of type 'any' 

这两条消息都表示基类闭包不能用于插槽。如何传递函数?

根据两个答案中的建议,可以生成以下代码。这解决了将函数传递到插槽,然后使用该函数的原始问题。为了完整性,提出了修正的神经网络层类。

setClass(
  Class="neuralNetworkLayer",
  representation=representation(
    nInput = "numeric",
    nOutput = "numeric",
    squashFcn = "function",
    derivSquashFcn = "function",
    gains = "matrix",
    hasBias = "logical",
    bias = "matrix",
    linOutput = "matrix",
    squashOutput = "matrix"
  )
)
getClass("neuralNetworkLayer")
getSlots("neuralNetworkLayer")
sf <- function(x){
  f = tanh(x)
  return(f)
}
dsf <- function(x) {
  d = 1 - tan(x)^2  
  return(d)
}
# Create an object of class 
hh = new("neuralNetworkLayer",squashFcn=sf,nInput=5,nOutput=5,hasBias=TRUE,
                        derivSquashFcn = dsf) 
hh@squashFcn(3)
hh@derivSquashFcn(3)

错误/警告:

 undefined slot classes in definition of "neuralNetworkLayer": squashFcn(class "closure")

意味着没有定义插槽,因为没有定义"闭包"类型。

您尝试将插槽(属性)定义为通用函数,其中一个想法是使用ANY(我认为插槽的默认值)类型:

neuralNetworkLayer <- 
setClass(
  Class="neuralNetworkLayer",
  representation=representation(
    squashFcn = "ANY"
  )
)

然后,例如,您这样实例化您的类:

# Constructors
hh = neuralNetworkLayer(squashFcn=function(x)print(x)) ## dummy function here 
hh@squashFcn(10)
[1] 10

也就是说,我认为您应该考虑将函数槽定义为一个真正的方法(请参见setMethod)。方法是要有类型化(更安全)的对象,否则没有充分的理由使用S4系统和更容易使用S3方法。

我不明白为什么你定义了一个neuralNetworkLayer S4类,而你的构造函数却没有使用它。你只是在创建一个普通的R列表(在NeuralNetworkLayer的返回对象中没有槽)。在构造函数中,您应该在某个地方调用new

无论如何,您的错误并不像您所想的那样与closure无关。您只是没有定义weights对象,它恰好也是一个R函数。当你说:

    weights = c(rep(NA,nOutput)),
    gains = matrix(data=weights, nrow = nInput, ncol = nOutput),

您正在创建一个名为weights的列表元素,但没有创建一个名称为weights的对象。当您定义gains元素时,R只是为weights找到它的R函数,并试图强迫它将其放入矩阵中,从而给出错误。您可以在NeuralNetworkLayer:的第一行中定义weights

    weights = c(rep(NA,nOutput))

然后,当您定义nc时,将我上面写的第一行替换为:

    weights = weights,

并且你的函数不会产生任何错误。

对于S4类定义的警告部分,只需使用function而不是closure。然而,由于您已经定义了构造函数,您可能根本没有定义它。

最新更新