我正试图在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
。然而,由于您已经定义了构造函数,您可能根本没有定义它。