Java 我的神经网络有更好的激活功能吗?

Java 我的神经网络有更好的激活功能吗?,java,neural-network,bufferedimage,activation-function,sigmoid,Java,Neural Network,Bufferedimage,Activation Function,Sigmoid,我正在写一个识别手写字母的程序。我有500px*500px的图像作为缓冲图像导入,我将每个像素的getRBG()值作为神经网络的输入,因此有250000个输入。getRGB()的值范围从-16777216(表示写入)到-1(表示白色背景)。从输入到第一个隐藏节点的权重在0到1之间随机化。我一直在使用sigmoid函数1/(1+e^(-x))作为我的激活函数来获取0和1之间的所有值。然而,我的问题是,由于有这么多的输入,当我将它们的点积与权重相加时,我会得到一个巨大的数字(例如,1.3E8或-1.

我正在写一个识别手写字母的程序。我有500px*500px的图像作为缓冲图像导入,我将每个像素的getRBG()值作为神经网络的输入,因此有250000个输入。getRGB()的值范围从-16777216(表示写入)到-1(表示白色背景)。从输入到第一个隐藏节点的权重在0到1之间随机化。我一直在使用sigmoid函数
1/(1+e^(-x))
作为我的激活函数来获取0和1之间的所有值。然而,我的问题是,由于有这么多的输入,当我将它们的点积与权重相加时,我会得到一个巨大的数字(例如,
1.3E8
-1.3E8
)。然后,当我把这个数字输入到sigmoid函数中时,结果总是都是1或0,因此它基本上没有向第二个隐藏节点传递任何有价值的信息。此外,由于图像主要为白色,因此大多数输入为-1

我调整了代码,使其在点积之后打印值,然后在值通过sigmoid函数之后打印

After dot product with weights, before sigmoid function: 
-1.3376484582733577E8   
-1.3382651127917042E8   
-1.3438475698429278E8   
-1.3356711106666781E8   
-1.3470225249402404E8   
-1.3372922925798771E8   
-1.3211961536262843E8   
-1.3512040351863045E8   

After sigmoid function: 
0.0 
0.0 
0.0 
0.0 
0.0 
0.0 
0.0 
0.0 
为了编辑getRGB()值,我使用了函数
newRGBValue=(getRGB()+2)*(-1)
,因此所有的值都在-1到16777214之间。但是,当我将所有这些值传递给sigmoid函数时,它只返回1,因为具有这些值的新点积是巨大的正数(如下面的输出所示)


这个程序有没有更好的激活功能?或者有没有一种方法可以操纵输入,从而使sigmoid函数适用?对于这篇长篇大论的文章,我深表歉意,并提前感谢您提供的见解。

规范化您的输入。也就是说,对于每个图像,计算像素值的平均值
mu
和方差
sigma
,并用归一化值
(v-mu)/sigma
替换旧像素值
v
。这消除了像素值的巨大负值

也考虑使用平均分布的初始随机权重,平均值为0,方差为1,以使点积的期望值为0。然后,最好切换到tanh激活函数,该函数以0为中心,从而加快学习速度(如果点积接近0)

After dot product, before sigmoid function: 
1.3198725189415371E8    
1.3345978405544662E8    
1.3375036029244222E8    
1.3278472449389385E8    
1.328751157809899E8 
1.3309195657860701E8    
1.34090008925348E8  
1.3300517803640646E8

After: 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0