在 R 中封装“neuralnet”,整流线性单元 (ReLU) 激活函数?
Package ‘neuralnet’ in R, rectified linear unit (ReLU) activation function?
我正在尝试使用 R 包神经网络中预先实现的 "logistic" 和 "tanh" 以外的激活函数。具体来说,我想使用整流线性单元 (ReLU) f(x) = max{x,0}。请在下面查看我的代码。
我相信如果由(例如)定义,我可以使用自定义函数
custom <- function(a) {x*2}
但如果我设置 max(x,0) 而不是 x*2,那么 R 会告诉我 'max is not in the derivatives table',对于“>”运算符也是如此。所以我正在寻找一个明智的解决方法,因为我认为在这种情况下 max 的数值积分不会成为问题。
nn <- neuralnet(
as.formula(paste("X",paste(names(Z[,2:10]), collapse="+"),sep="~")),
data=Z[,1:10], hidden=5, err.fct="sse",
act.fct="logistic", rep=1,
linear.output=TRUE)
有什么想法吗?我有点困惑,因为我认为 neuralnet
包不会进行分析差异化。
可以用可微函数来逼近max函数,例如:
custom <- function(x) {x/(1+exp(-2*k*x))}
变量 k 决定了近似的准确性。
其他近似值可以从 "Analytic approximations" 节中的等式导出:https://en.wikipedia.org/wiki/Heaviside_step_function
neuralnet
包的内部结构将尝试区分提供给 act.fct
的任何函数。可以看源码here.
在第 211 行,您将找到以下代码块:
if (is.function(act.fct)) {
act.deriv.fct <- differentiate(act.fct)
attr(act.fct, "type") <- "function"
}
differentiate
函数是deriv
函数的更复杂的用法,您也可以在上面的源代码中看到。因此,目前无法向 act.fct
提供 max(0,x)
。它需要在代码中放置一个例外来识别 ReLU 和 知道 导数。获得源代码,将其添加并提交给维护人员进行扩展将是一个很好的练习(但这可能有点多)。
但是,关于一个明智的解决方法, 您可以使用 softplus function,它是 ReLU 的平滑近似。您的自定义函数如下所示:
custom <- function(x) {log(1+exp(x))}
您也可以在 R 中查看此近似值:
softplus <- function(x) log(1+exp(x))
relu <- function(x) sapply(x, function(z) max(0,z))
x <- seq(from=-5, to=5, by=0.1)
library(ggplot2)
library(reshape2)
fits <- data.frame(x=x, softplus = softplus(x), relu = relu(x))
long <- melt(fits, id.vars="x")
ggplot(data=long, aes(x=x, y=value, group=variable, colour=variable))+
geom_line(size=1) +
ggtitle("ReLU & Softplus") +
theme(plot.title = element_text(size = 26)) +
theme(legend.title = element_blank()) +
theme(legend.text = element_text(size = 18))
我正在尝试使用 R 包神经网络中预先实现的 "logistic" 和 "tanh" 以外的激活函数。具体来说,我想使用整流线性单元 (ReLU) f(x) = max{x,0}。请在下面查看我的代码。
我相信如果由(例如)定义,我可以使用自定义函数
custom <- function(a) {x*2}
但如果我设置 max(x,0) 而不是 x*2,那么 R 会告诉我 'max is not in the derivatives table',对于“>”运算符也是如此。所以我正在寻找一个明智的解决方法,因为我认为在这种情况下 max 的数值积分不会成为问题。
nn <- neuralnet(
as.formula(paste("X",paste(names(Z[,2:10]), collapse="+"),sep="~")),
data=Z[,1:10], hidden=5, err.fct="sse",
act.fct="logistic", rep=1,
linear.output=TRUE)
有什么想法吗?我有点困惑,因为我认为 neuralnet
包不会进行分析差异化。
可以用可微函数来逼近max函数,例如:
custom <- function(x) {x/(1+exp(-2*k*x))}
变量 k 决定了近似的准确性。
其他近似值可以从 "Analytic approximations" 节中的等式导出:https://en.wikipedia.org/wiki/Heaviside_step_function
neuralnet
包的内部结构将尝试区分提供给 act.fct
的任何函数。可以看源码here.
在第 211 行,您将找到以下代码块:
if (is.function(act.fct)) {
act.deriv.fct <- differentiate(act.fct)
attr(act.fct, "type") <- "function"
}
differentiate
函数是deriv
函数的更复杂的用法,您也可以在上面的源代码中看到。因此,目前无法向 act.fct
提供 max(0,x)
。它需要在代码中放置一个例外来识别 ReLU 和 知道 导数。获得源代码,将其添加并提交给维护人员进行扩展将是一个很好的练习(但这可能有点多)。
但是,关于一个明智的解决方法, 您可以使用 softplus function,它是 ReLU 的平滑近似。您的自定义函数如下所示:
custom <- function(x) {log(1+exp(x))}
您也可以在 R 中查看此近似值:
softplus <- function(x) log(1+exp(x))
relu <- function(x) sapply(x, function(z) max(0,z))
x <- seq(from=-5, to=5, by=0.1)
library(ggplot2)
library(reshape2)
fits <- data.frame(x=x, softplus = softplus(x), relu = relu(x))
long <- melt(fits, id.vars="x")
ggplot(data=long, aes(x=x, y=value, group=variable, colour=variable))+
geom_line(size=1) +
ggtitle("ReLU & Softplus") +
theme(plot.title = element_text(size = 26)) +
theme(legend.title = element_blank()) +
theme(legend.text = element_text(size = 18))