我试图在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
答案 0 :(得分:1)
不要提供删除了位的部分代码,只提供一个可运行的示例 - 执行此操作的过程可能会帮助您找到问题。为此目的,并不真正需要initWeights函数 - 最好使用已知的起始数据。
以下是添加数据时的不完整代码。该算法似乎倾向于某一组结果(可能是,不同的数据,它可能会在10次运行中更快到达,我已经将运行增加到100)。
https://play.golang.org/p/IqfCjNtd8a
你确定这不按预期工作吗?您是否有预期结果的测试数据来测试?考虑到你发布的代码,我希望print 2始终匹配打印最后一个打印1,但它显然是不完整的。
[编辑] 目前尚不清楚这是一个go代码问题,而不是你的算法/数据令你惊讶的结果。
你需要:
如果您无法使用静态数据重现,请向我们展示如何将数据加载到变量中,因为这可能是您的问题所在。您确定要加载预期的数据,而不是加载一行的大量副本吗?你确定算法没有按预期工作(如果是这样的话)?您对结果的描述与您向我们展示的内容不符。
答案 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)))
}