切片不更新循环外的值

时间:2017-09-22 12:13:44

标签: arrays go slice

我试图在Go中遇到Adaline神经元的问题,我对数组的铲子有问题,我在for循环中更新它的值,看起来就像它们一样更新,但是当我尝试从循环外部访问新值时,它们总是相同的,它们只是在第一次迭代中更新。这是代码:

//This functions creates a [][]float64 and fill it with random numbers
weights := initWeights(inputLength)

// data is a [][]float 64 and expectedY a []float64
for i := 0; i < 10; i++ {
    for j := range data {
        //Calculate estimate
        var estimate float64 = 0
        for x := range data[j]{
            estimate += data[j][x] * weights[x]
        }

        // Update weights (range passes values as a copy)
        for x := 0; x < len(weights); x++ {

            weights[x] = learningRate * (expectedY[j] - estimate) * data[j][x]
        }
        //PRINT #1
    }
    //PRINT #2
    //
    //Some more stuff
    // 
}

如果我在循环之前打印weights,它看起来像这样:

[-0.6046602879796196 0.6645600532184904 -0.4246374970712657 0.06563701921747622 0.09696951891448456 -0.5152126285020654 0.21426387258237492 0.31805817433032985 0.28303415118044517]

所以它是正确创建的。在我开始循环以调整神经元重量之后。这是奇怪的事情发生的地方。

如果我在#1中打印,我可以看到数组在每次迭代中都在更新,但是当我在#2中打印时,数组的值总是相同的,它的计算结果是权重循环的第一次迭代。

打印#1

[0.06725611377611064 0 0 0.03490734755724929 0.014819026508554914 0.023919277971577904 0.021858582731470875 0.0051309928461725374 0.06915084698345737]
[0.030417970260300468 0.0274737201080031 0 0.02479712906046004 0.01662460439529523 0.014007493148808682 0.029246218179487176 0.004413401238393224 0.05947980105651245]
[0.008861875440076036 0 0.01792998206766924 0.017854161778140868 0.004333887749441702 0.020137868898735412 0.0125224790185058 0.008249247500686795 0.030328115811348512]. 

打印#2

[0.007796061340871362 0 0.011035383661848988 0.01289960904315235 0.003797667051516503 0.009918694200771232 0.015234505189042204 0.0008236738380263619 0.023072096303259435]
[0.007796061340871362 0 0.011035383661848988 0.01289960904315235 0.003797667051516503 0.009918694200771232 0.015234505189042204 0.0008236738380263619 0.023072096303259435]
[0.007796061340871362 0 0.011035383661848988 0.01289960904315235 0.003797667051516503 0.009918694200771232 0.015234505189042204 0.0008236738380263619 0.023072096303259435]

过去两天我一直在努力解决这个问题,我无法弄清楚发生了什么,我希望你们能帮助我。

- 更新 -
这是一个更完整且可运行的版本https://play.golang.org/p/qyZGSJSKcs

在游戏中,看起来代码工作正常......我的计算机中完全相同的代码在每次迭代时输出完全相同的切片。

唯一的区别是,不是固定的切片,而是从两个有几百行的csv文件创建它们,所以我猜测问题来自那里,我将继续调查。

如果有帮助,请提供原始数据:
培训数据:https://pastebin.com/H3YgFF0a
验证数据:https://pastebin.com/aeK6krxD

2 个答案:

答案 0 :(得分:1)

不要提供删除了位的部分代码,只提供一个可运行的示例 - 执行此操作的过程可能会帮助您找到问题。为此目的,并不真正需要initWeights函数 - 最好使用已知的起始数据。

以下是添加数据时的不完整代码。该算法似乎倾向于某一组结果(可能是,不同的数据,它可能会在10次运行中更快到达,我已经将运行增加到100)。

https://play.golang.org/p/IqfCjNtd8a

你确定这不按预期工作吗?您是否有预期结果的测试数据来测试?考虑到你发布的代码,我希望print 2始终匹配打印最后一个打印1,但它显然是不完整的。

[编辑] 目前尚不清楚这是一个go代码问题,而不是你的算法/数据令你惊讶的结果。

你需要:

  1. 提供代码(您现在已经完成了此操作,但没有显示问题的代码)
  2. 将代码/数据减少到显示错误的最小值
  3. 制作一个测试,以最少的数据显示令人惊讶的结果
  4. 如果您无法使用静态数据重现,请向我们展示如何将数据加载到变量中,因为这可能是您的问题所在。您确定要加载预期的数据,而不是加载一行的大量副本吗?你确定算法没有按预期工作(如果是这样的话)?您对结果的描述与您向我们展示的内容不符。

答案 1 :(得分:0)

发现它!这是一件愚蠢的事情......权重更新过程是累积的

w(i+1) = w(i) + learningRate * (expected - estimated) * data[j][i]

所以我忘了将+添加到权重分配

weights[x] += learningRate * (expectedY[j] - estimate) * data[j][x]

以下是完整的代码段正常工作:

for i := 0; i < cylces; i++ {
    for j := range data {
        //Calculate estimate
        estimate = 0
        for x := range data[j]{
            estimate += data[j][x] * weights[x]
        }

        // Update weights (range passes values as a copy)
        for x := 0; x < len(weights); x++ {
            weights[x] += learningRate * (expectedY[j] - estimate) * data[j][x]
        }
    }

    errorData = 0
    for j := range data {
        estimate = 0
        for x := range data[j] {
            estimate += data[j][x] * weights[x]
        }
        errorData += (expectedY[j] - estimate) * (expectedY[j] - estimate)
    }
    errorsCyles = append(errorsCyles, errorData / float64(len(data)))
}