将S4插槽设置为起作用并表示神经网络层

时间:2014-09-21 12:05:51

标签: r list closures 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)

2 个答案:

答案 0 :(得分:1)

错误/警告:

 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方法。

答案 1 :(得分:1)

我不明白你在构造函数没有使用它时定义neuralNetworkLayer S4类的原因。您只是创建一个普通的R列表(NeuralNetworkLayer的返回对象中没有插槽)。在构造函数中,您应该在某处调用new

无论如何,您的错误与您可能认为的closure无关。您刚刚没有定义它碰巧也是R函数的weights对象。当你说:

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

您正在创建名为weights的列表的元素,但您没有创建名为weights的对象。当您定义gains元素时,R只会找到weights的R函数并尝试强制将其放入矩阵中,从而产生错误。您只需在weights的第一行中定义NeuralNetworkLayer

    weights = c(rep(NA,nOutput))

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

    weights = weights,

并且您的函数不会给出任何错误。

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