我刚读过“制作你自己的神经网络”一书。现在我正在尝试用Python创建NeuralNetwork类。我使用sigmoid激活功能。我写了基本代码并试图测试它。但我的实施根本没有正常工作。经过长时间的调试和对书中代码的比较,我发现非常大的数字的sigmoid是1,因为Python对它进行了舍入。我使用numpy.random.rand()
生成权重,此函数仅返回0到1之间的值。在对所有权重和输入的产品求和之后,我获得了非常大的数字。我用numpy.random.normal()
函数修复了这个问题,该函数从范围(-1,1)生成随机数。但我有一些问题。
答案 0 :(得分:1)
这个问题的答案显然取决于背景。 “好”意味着什么。 sigmoid激活函数将导致输出介于0和1之间。因此,它们是二进制分类的标准输出激活,您希望神经网络输出0到1之间的数字 - 输出被解释为概率您的输入在指定的类中。但是,如果您在整个神经网络中使用sigmoid激活函数(即在中间层中),您可以考虑切换到RELU激活函数。从历史上看,S形激活函数在整个神经网络中被用作引入非线性的一种方式,因此神经网络可以做的不仅仅是近似线性函数。然而,发现sigmoid激活很大程度上受到消失梯度问题的影响,因为函数是非常平坦的。因此,现在,大多数中间层将使用RELU激活函数(或者更奇特的东西 - 例如SELU / Leaky RELU / etc。)对于小于0的输入,RELU激活函数为0,并且对于大于0的输入,它等于输入。已经发现它足以将非线性引入神经网络。
一般来说,您不希望处于输出如此巨大或太小以至于计算不稳定的状态。如前所述,帮助解决此问题的一种方法是使用不同的激活功能(例如RELU)。帮助解决这个问题的另一种方法,甚至更好的方法是通过例如更好地初始化权重。 Xavior-Glorot initialization方案或简单地将它们初始化为较小的值,例如在[-.01,。01]范围内。基本上,您可以缩放随机初始化,以便您的输出具有良好的值范围,而不是一些巨大或微小的数字。你当然也可以做到这两点。
您可以使用更高精度的浮点数来使python保持更多的小数。例如。您可以使用np.float64而不是np.float32 ...但是,这会增加计算复杂性,可能不是必需的。今天大多数神经网络使用32位浮点数,它们工作得很好。有关解决问题的更好方法,请参见第1点和第2点。
这个问题过于宽泛。我会说,在学习神经网络方面,Andrew Ng教授的课程和专业是我最强烈的建议。