我想实现各种数学函数,例如 Sigmoid (Logistic)、ReLU 等。除了其中的每一个,我还想实现它们的导数。
鉴于这些数学函数都是非常简单的单行函数,我想让它们内联。此外,我希望能够按名称将函数组织成单个实体,并能够像这样调用常规激活或派生函数:
Sigmoid.Activate(0.5)
Sigmoid.Derivate(0.5)
最后,我希望能够将这些存储为对象的一个字段,因此如果我要为神经网络合并一个神经元,我将能够拥有一个名为 activation
并且可以这样调用它:
this->activation.Derivate(this->input);
在寻找合适的方法来完成此任务时,我感到很矛盾。我读过,一般来说,静态内联函数是一种代码味道。然而,为每个使用这些函数的对象创建一个单独的实例似乎是多余的并且浪费内存。事实上,拥有任何实例似乎都是浪费,因为我基本上只想将两个函数组合成一个名称。我考虑过为每个函数使用命名空间,但那样我就无法指定对象应该使用哪个函数。
静态类似乎是唯一有效的解决方案。有没有更优雅的方法来做到这一点?
最佳答案
这可能不符合您的所有条件,但我认为它很有用。类并不能解决所有问题,所以为什么不让类的 activation
字段成为返回(值,导数)对的函数指针类型:
// Example library
using value_derivative = std::pair<double,double>;
enum ReturnType {
VALUE,
DERIVATIVE
};
using ActivationFunction = std::function<value_derivative(double)>;
value_derivative sigmoid(double z) {
double ez = exp(-z);
double val = 1.0/(1+ez);
return std::make_pair(val, val*(1.0-val));
}
// Example usage
ActivationFunction activation = sigmoid;
auto act = activation(1);
double value = std::get<VALUE>(act);
double derivative = std::get<DERIVATIVE>(act);
std::tie(value,derivative) = activation(2);
请注意,这样做的一个附带好处是,当激活函数有一个很好的微分方程时,在计算值时使用中间项通常更容易计算导数。
关于C++:将数学函数及其导数分组到一个实体中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53400499/