伟大而有用的文章素材
谢谢!
是的,已经计划好了)
德米特里,我一开始没意识到为什么要在输入值上添加正弦和余弦值。
neuron.setOutputVal(inputVals.At(i)+(i%2==0 ? sin(i) : cos(i)) );
我还需要一些建议--我是否应该尝试以某种方式使输入数据正常化,以完成我的任务?
在我所理解的示例中,一切都是 "按原样 "给出的。但是,即使是在分形示例中,也有一些振荡指标从 0 到 1,而根据不同的工具,价格可能比 1 高得多。
在对非标准化输入进行训练时,这难道不会产生初始偏差吗?
德米特里,请告诉我为什么要在输入值上添加正弦和余弦。
我还需要一些建议--我是否应该尝试以某种方式使输入数据正常化,以完成我的任务?
在我所理解的示例中,一切都是 "按原样 "给出的。但是,即使在分形示例中,一些振荡器的振幅也是从 0 到 1,而根据不同的工具,价格可能比 1 高得多。
在对非标准化输入进行训练时,这难道不会产生初始偏差吗?
@Dmitriy Gizlyk,这个问题是在学习和使用库时提出的:
在计算隐藏层梯度的方法中,你添加了outputVal
这是为了在后面的计算输出梯度方法中补偿其值,以实现普遍性,对吗?
你还添加了梯度归一化。
bool CNeuron::calcHiddenGradients(CLayer *&nextLayer) { double targetVal=sumDOW(nextLayer)+outputVal; return calcOutputGradients(targetVal); } //+------------------------------------------------------------------+ bool CNeuron::calcOutputGradients(double targetVal) { double delta=(targetVal>1 ? 1 : targetVal<-1 ? -1 : targetVal)-outputVal; gradient=(delta!=0 ? delta*activationFunctionDerivative(outputVal) : 0); return true; }
问题是,如果不对目标值进行归一化,而是 像这样对最终的 delta 进行归一化,是否会更正确?
double delta=targetVal-outputVal; delta=delta>1?1:delta<-1?-1:delta;
为什么?举例:如果输出值接近 1,而下一层的总加权梯度也很高且为正值,那么我们现在得到的最终 delta 值接近零,这似乎是不对的。
毕竟,梯度的 delta 值应该与下一层的误差成正比,也就是说,当神经元的有效权重为负时(也可能在其他一些情况下),神经元受到的误差惩罚要小于权重为正时。我的解释可能比较简单,但我希望熟悉这门学科的人能够理解我的想法:)也许您已经注意到了这一点,并做出了这样的决定,如果能说明原因,那将会很有意思。
OCL 代码也是如此
__kernel void CalcHiddenGradient(__global double *matrix_w, __global double *matrix_g, __global double *matrix_o, __global double *matrix_ig, int outputs, int activation) { .............. switch(activation) { case 0: sum=clamp(sum+out,-1.0,1.0)-out; sum=sum*(1-pow(out==1 || out==-1 ? 0.99999999 : out,2));
@Dmitriy Gizlyk,这个问题是在学习和使用图书馆时产生的:
在隐藏层的梯度计算方法中,你添加了outputVal
这是为了在计算输出梯度方法中进一步补偿其值,以实现普遍性,对吗?
您还添加了梯度归一化
问题是,如果不对目标值进行归一化,而是对最终的 delta 进行归一化,是否会更正确?
为什么?例如:如果输出值接近 1,而下一层的总加权梯度也很高且为正值,那么现在我们得到的最终 delta 值接近 0,这似乎是不对的。
毕竟,梯度的 delta 值应该与下一层的误差成正比,也就是说,当神经元的有效权重为负时(也可能在其他一些情况下),神经元受到的误差惩罚要小于权重为正时。我的解释可能比较简单,但我希望熟悉这门学科的人能够理解我的想法:)也许你已经注意到了这一点,并做出了这样的决定,如果能说明原因,那将会很有意思。
OCL 代码也是如此
并非如此。我们会检查目标值,就像在隐藏层中,我们会将 outpuVal 加入梯度以获得目标值并检查其值。如果我们惩罚神经元的偏差并无限增加权重系数,就会导致权重溢出。毕竟,如果某个神经元的权重值等于 1,而随后传递错误信息的层则认为我们应该将权重值增加到 1.5。因此,我将目标值限制在激活函数可接受值的范围内。而超出范围的调整则由后续层的权重来完成。
其实不然。我们要检查目标值,就像在隐藏层中,我们将 outpuVal 加到梯度上以得到目标值并检查其值一样。如果我们惩罚神经元的偏差并无限制地增加权重系数,就会导致权重溢出。毕竟,如果某个神经元的权重值等于 1,而随后传递错误信息的层却要求我们将权重值增加到 1.5。因此,我将目标值限制在激活函数可接受值的范围内。而超出范围的调整则由后续层的权重来完成。
我想我做到了。但我还是想知道,这样的例子是否正确:
如果网络犯了一个错误,在实际值为 1 时给出了 0。那么从最后一层开始,上一层的梯度加权(我的理解很可能是)为正,并且可能大于 1,比如说 1,6。
假设上一层有一个神经元产生了 +0.6,即它产生了正确的值,那么它的权重就应该增加。通过这种归一化处理,我们可以削减其权重的变化。
结果是 norm(1,6)=1。1-0,6=0,4,如果我们按照我的建议进行归一化处理,结果将是 1。在这种情况下,我们会减慢正确神经元的放大速度。
您怎么看?
关于权重的无限增加,我听说在 "误差函数不好 "的情况下会出现这种情况,比如有很多局部极小值而没有明显的全局极小值,或者函数不是凸的,诸如此类,我不是超级专家,我只是相信你可以而且应该用无限权重和其他方法来解决这个问题。
我要求做一个实验来测试这两种变体。如果我想好了如何进行测试 )
新文章 神经网络变得轻松(第九部分):操作归档已发布:
我们已经经历了很长一段路,并且函数库中的代码越来越庞大。 这令跟踪所有连接和依赖性变得难以维护。 因此,我建议为先前创建的代码创建文档,并保持伴随每个新步骤进行更新。 正确准备的文档将有助我们看到操作的完整性。
一旦程序完成,您将收到一个现成的文档。 Some screenshots are shown below. 附件中提供了完整的文档。
作者:Dmitriy Gizlyk