尊敬的读者您好。 关于神经网络,已经写了很多文章,并说了很多,主要是关于如何以及为什么可以应用它们。 此外,在某种程度上,人们对两个重要问题的关注不多:a)如何简化和快速计算神经网络(对指数的一种计算是通过编程语言的库函数来实现的,通常不少于15-20个处理器指令),b)什么,至少部分是构建网络的逻辑-实际上,在训练网络后获得的巨大重量和位移值矩阵在某种程度上并不能真正帮助理解该网络发现的模式(它们仍然处于隐藏状态,确定它们的任务是柳树的任务 和灰 - 有时也很重要)。 我将讨论为普通的直接分布神经网络解决这些问题的一种方法,同时我尝试使用最少的数学方法。
一点理论
从数学的角度来看,直接分配网络是一个非常大的函数,其中包括网络输入的值,加权系数和神经元的位移。 在层的每个神经元中,层的输入值(向量X)乘以神经元的权重(向量
),加上偏移量
并输入激活功能
形成层神经元的输出。
激活函数的计算可能不是很简单,例如,它们通常包含指数(指数S型,双曲正切)。 如果看一下实现指数的汇编代码,您会发现,首先,很多并不总是需要的检查,其次,指数本身的计算通常至少需要两个操作:
因此,如果我们想加快网络的计算速度,那么首要任务就是简化激活函数的计算。 您可以尝试通过提高速度来牺牲一点质量,用一个更简单的函数来代替经典激活函数的计算,该函数(在可用的输入数据上)会得到大致相同的结果。 一般而言,这是一个经典的插值问题:我们有一组由原始函数A(s)计算的值,并且我们选择了一个给出非常相似值的简单函数。 这样的简单函数a可以是普通多项式,也可以是具有负幂的多项式,或者类似的东西。 我使用了四种类型的此类函数:
;
;
;
;
假设对于每个神经元,我们设法用一个稍微简单的神经元替换了激活函数-例如,可以使用最小二乘法来完成。 这种替换本身可能不会带来很大的收益。 但是您可以在这里尝试另一个技巧:
- 编写由网络作为整体计算得出的解析巨大的函数NET(X);
- 用为其获得的替换功能a替换NET(X)中的原始功能A。
- 简化以代数形式获得的NET(X)(或者,使用一些现成的代码对符号进行符号简化)。 这已经是可能的(至少比我们尝试使用原始功能(例如,使用指数简化网络)要容易得多)。
结果,我们得到了一些更简单,也许在数学上更明显的东西-在这里您已经可以尝试了解网络实现了什么样的功能。
这是解释构造的网络逻辑的选项。
当然,所描述的任务只是用文字看起来很简单。 为了在程序中使用,我需要编写自己的代码以简化表达式的表达。 此外,我假设一个具有功能A的神经元可以有多个选择来替代激活功能,所以我解决了一个更复杂的问题
因此,一般的任务也归结为列举此类功能的选项,并为每个此类选项简化网络的符号表示。 在这里,只有并行化计算才有帮助。
结果
结果令我高兴。 我用激活函数“指数乙状结肠”加速了八个神经元(具有输入权重和位移)的三层网络(三个输入)。 如时间测量所示,有可能获得约40%的时间增益而没有明显的质量损失。
我说明。 这是源网络数据:


第三层是输出层:

如果将输入指定为a,b和c,则在替换和简化之后,网络功能NET如下:
double a2 = a*a; double b2 = b*b; double c2 = c*c; double a3 = a2*a; double b3 = b2*b; double c3 = c2*c; double z01 = sqrt(-1.6302e-02+7.9324e-01*a+9.65149e-01*b+5.64151e-01*c); double z06 = sqrt(1.583708e+00-8.907654e-01*a-2.844379e-01*a2+1.050942e+00*a3+1.178096e+01*b-1.865618e+00*b*a-3.145465e+00*b*a2-5.777153e+00*b2+3.138123e+00*b2*a-1.043599e+00*b3+1.32778e+00*c+5.849582e-01*c*a-3.440382e+00*c*a2+1.838371e+00*c*b+6.864703e+00*c*b*a-3.42434e+00*c*b2-3.013361e-01*c2+3.754167e+00*c2*a-3.745404e+00*c2*b-1.365524e+00*c3+1.014237e-01*z01); double NET = (-1.477593e+00)/(z06)+1.370237e+00-6.303167e-02*a-1.495051e-03*a2+2.33748e-02*a3+5.558024e-02*b+1.178189e-02*b*a-6.996071e-02*b*a2+1.837937e-02*b2+6.97974e-02*b2*a-2.321149e-02*b3+7.924241e-02*c+3.392287e-03*c*a-7.652018e-02*c*a2-1.214263e-02*c*b+1.526831e-01*c*b*a-7.616337e-02*c*b2-1.915279e-03*c2+8.349931e-02*c2*a-8.33044e-02*c2*b-3.037166e-02*c3+1.949161e-02*z01;
获胜 -我重复40%的时间,而对质量没有太大损害。 我认为这种方法可以应用在计算神经网络的速度至关重要的情况下,例如,如果它是在两次或三次循环中重复计算的话。
此类问题的一个示例 :网格上空气动力学问题的数值解,并且在其每个节点中,神经网络都会计算一些有用的预测,例如,以更精确地计算湍流粘度。 然后,我们有一个外部时间周期,其中嵌入了一个双精度或三周期坐标,并且已经在内部进行了神经网络的计算。 在这种情况下,简化不仅仅是适当和有用的。