反向传播二维神经元网络 C++

Backpropagation 2-Dimensional Neuron Network C++

我正在学习二维神经元网络,所以我面临很多障碍,但我相信这是值得的,我真的很享受这个学习过程。

这是我的计划:让 2-D NN 用于识别数字图像。图片是 5 x 3 的网格,我准备了 10 张从 0 到 9 的图片。例如,这将是数字 7:

数字 7 的索引 0、1、2、5、8、11、14 为 1(或 3、4、6、7、9、10、12、13 为 0 无关紧要)等等在。因此,我的输入层将是一个 5 x 3 的神经元层,我将只给它 个零(不在两者之间,索引取决于我给层提供的图像) .

然而,我的输出层将是 10 个神经元的一维层。取决于哪个数字被识别,某个神经元将触发值 1,其余的应该为零(不应该触发)。

我已经完成了所有的实现,但我在计算方面遇到了问题,非常感谢任何帮助。我在所有输出神经元上得到了极高的错误率和极低(负)的输出值,并且即使在第 10,000 遍时,值(错误和输出)也不会改变。

我想更进一步 post 我的反向传播方法,因为我认为问题出在其中。但是,为了分解我的工作,我很想先听听一些评论,我想知道我的设计是否平易近人。

感谢任何 ideas/comments/guidance 并提前致谢

嗯,根据上面的描述,我认为它的设计和做法是正确的!关于激活函数的选择,请记住这些函数有助于获得具有最大激活数的神经元,而且它们的代数性质(例如易导数)有助于反向传播的定义。考虑到这一点,您就不必担心激活函数的选择了。

你上面提到的范围,对应于输入缩放的过程,最好让你的输入图像在0到1的范围内。这有助于缩放误差面并有助于速度和收敛的优化过程。因为你的输入集是由图像组成的,而每个图像是由像素组成的,所以一个像素可以达到的最小值和最大值分别是 0 和 255。要在此示例中缩放输入,必须将每个值除以 255。

现在,关于训练问题,你试过检查你的梯度计算例程是否正确吗? 通过使用成本函数,并评估成本函数,J?如果没有,请尝试生成一个玩具向量 theta,其中包含您的神经网络中涉及的所有权重矩阵,并使用梯度的定义评估每个点的梯度,对于 Matlab 示例很抱歉,但它应该是易于移植到 C++:

perturb = zeros(size(theta));
e = 1e-4;
for p = 1:numel(theta)
    % Set perturbation vector
    perturb(p) = e;
    loss1 = J(theta - perturb);
    loss2 = J(theta + perturb);
    % Compute Numerical Gradient
    numgrad(p) = (loss2 - loss1) / (2*e);
    perturb(p) = 0;
end

评估函数后,将数值梯度与使用反向传播计算的梯度进行比较。如果每次计算的差小于3e-9,那么你的实现应该是正确的。

推荐看一下斯坦福人工智能实验室的UFLDL教程,里面有很多神经网络及其范式相关的资料,值得一看!

http://ufldl.stanford.edu/wiki/index.php/Main_Page

http://ufldl.stanford.edu/tutorial/