gpt4 book ai didi

java - 神经网络反向传播无法正确计算权重

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:52:54 25 4
gpt4 key购买 nike

目前,我在反向传播算法方面遇到了问题。我正在尝试实现它并使用它来识别面孔的方向(左、右、下、直)。基本上,我有 N 个图像,读取像素并将其值(0 到 255)更改为 0.0 到 1.0 之间的值。所有图像均为 32*30。我有一个包含 960 个神经元的输入层、一个包含 3 个神经元的隐藏层和一个包含 4 个神经元的输出层。例如,输出 <0.1,0.9,0.1,0.1> 表示此人向右看。我遵循了伪代码。但是,它无法正常工作——它无法计算正确的权重,因此无法处理训练和测试示例。以下是部分代码:

    // main function - it runs the algorithm
private void runBackpropagationAlgorithm() {
for (int i = 0; i < 900; ++i) {
for (ImageUnit iu : images) {
double [] error = calcOutputError(iu.getRatioMatrix(), iu.getClassification());
changeHiddenUnitsOutWeights(error);
error = calcHiddenError(error);
changeHiddenUnitsInWeights(error,iu.getRatioMatrix());
}
}
}

// it creates the neural network
private void createNeuroneNetwork() {
Random generator = new Random();
for (int i = 0; i < inHiddenUnitsWeights.length; ++i) {
for (int j = 0; j < hiddenUnits; ++j) {
inHiddenUnitsWeights[i][j] = generator.nextDouble();
}
}
for (int i = 0; i < hiddenUnits; ++i) {
for (int j = 0; j < 4; ++j) {
outHddenUnitsWeights[i][j] = generator.nextDouble();
}
}
}
// Calculates the error in the network. It runs through the whole network.
private double [] calcOutputError(double[][] input, double [] expectedOutput) {
int currentEdge = 0;
Arrays.fill(hiddenUnitNodeValue, 0.0);
for (int i = 0; i < input.length; ++i) {
for (int j = 0; j < input[0].length; ++j) {
for (int k = 0; k < hiddenUnits; ++k) {
hiddenUnitNodeValue[k] += input[i][j] * inHiddenUnitsWeights[currentEdge][k];
}
++currentEdge;
}
}
double[] out = new double[4];
for (int j = 0; j < 4; ++j) {
for (int i = 0; i < hiddenUnits; ++i) {
out[j] += outHddenUnitsWeights[i][j] * hiddenUnitNodeValue[i];
}
}
double [] error = new double [4];
Arrays.fill(error, 4);
for (int i = 0; i < 4; ++i) {
error[i] = ((expectedOutput[i] - out[i])*(1.0-out[i])*out[i]);
//System.out.println((expectedOutput[i] - out[i]) + " " + expectedOutput[i] + " " + out[i]);
}
return error;
}

// Changes the weights of the outgoing edges of the hidden neurons
private void changeHiddenUnitsOutWeights(double [] error) {
for (int i = 0; i < hiddenUnits; ++i) {
for (int j = 0; j < 4; ++j) {
outHddenUnitsWeights[i][j] += learningRate*error[j]*hiddenUnitNodeValue[i];
}
}
}

// goes back to the hidden units to calculate their error.
private double [] calcHiddenError(double [] outputError) {
double [] error = new double[hiddenUnits];
for (int i = 0; i < hiddenUnits; ++i) {
double currentHiddenUnitErrorSum = 0.0;
for (int j = 0; j < 4; ++j) {
currentHiddenUnitErrorSum += outputError[j]*outHddenUnitsWeights[i][j];
}
error[i] = hiddenUnitNodeValue[i] * (1.0 - hiddenUnitNodeValue[i]) * currentHiddenUnitErrorSum;
}
return error;
}

// changes the weights of the incomming edges to the hidden neurons. input is the matrix of ratios
private void changeHiddenUnitsInWeights(double [] error, double[][] input) {
int currentEdge = 0;
for (int i = 0; i < input.length; ++i) {
for (int j = 0; j < input[0].length; ++j) {
for (int k = 0; k < hiddenUnits; ++k) {
inHiddenUnitsWeights[currentEdge][k] += learningRate*error[k]*input[i][j];
}
++currentEdge;
}
}
}

随着算法的运行,它计算出越来越大的权重,最终接近无穷大(NaN 值)。我检查了代码。 las,我没有设法解决我的问题。我将非常感谢任何愿意帮助我的人。

最佳答案

我没有检查你的所有代码。我只想给你一些一般性的建议。我不知道您的目标是 (1) 学习人脸的方向还是 (2) 实现您自己的神经网络。

在情况 (1) 中,您应该考虑 those 之一图书馆。它们只是工作,并为您提供更灵活的配置选项。例如,标准反向传播是神经网络最差的优化算法之一。收敛取决于学习率。我看不到您在实现中选择了哪个值,但它可能太高了。还有其他优化算法不需要学习率或在训练期间对其进行调整。此外,隐藏层中的 3 个神经元很可能是不够的。大多数用于图像的神经网络都有成百上千个隐藏单元。我建议您首先尝试使用完全开发的库来解决您的问题。如果它确实有效,请尝试实现您自己的 ANN 或高兴。 :)

在情况 (2) 中,您应该首先尝试解决一个更简单的问题。取一个很简单的人工数据集,然后取一个standard benchmark然后用你的数据试试。验证反向传播实现是否有效的一个好方法是与 numerical differentation method 进行比较。 .

关于java - 神经网络反向传播无法正确计算权重,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11991651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com