Go实现反向传播时,调用sigmoidPrime为何修改delta矩阵?
反向传播中delta矩阵意外被修改的问题
我正在研究神经网络,参考Michael Nielsen的《Neural Networks and Deep Learning》,将书中首个Python网络代码转为Go应用,目前核心问题出在反向传播函数中:
前向传播阶段代码
// Definitions above for i := 0; i < len(nn.weights); i++ { var z mat.Dense weights := nn.weights[i] biases := nn.biases[i] z.Mul(weights, a) z.Add(&z, biases) zs[i] = &z applySigmoid := func(_, _ int, v float64) float64 { return sigmoid(v) } z.Apply(applySigmoid, &z) a = &z activations[i] = a }
问题现象
反向传播时,我定义delta为最后一层激活矩阵与标签y的cost_derivative,随后对zs最后一个矩阵调用Apply执行sigmoidPrime函数,却发现delta矩阵的值也被修改(二者内存地址不同)。相关输出如下:
0xc0000120d8 ⎡0.09982711116022883⎤ ⎢0.24260080224285077⎥ ⎢0.15233709720227542⎥ ⎢0.19494995716396032⎥ ⎢0.15726110223847964⎥ ⎢0.11059359868590982⎥ ⎢0.17026207248890898⎥ ⎢0.15609114217030096⎥ ⎢ -0.810915969767469⎥ ⎣0.15840349924957667⎦ 11111111111111111111111111 0xc0000120d8 ⎡ 0.2493781922654036⎤ ⎢0.24635733720120548⎥ ⎢ 0.2485551795164905⎥ ⎢0.24763962253727612⎥ ⎢0.24846065795203182⎥ ⎢0.24923712159141503⎥ ⎢0.24819689472860218⎥ ⎢ 0.2484833845383838⎥ ⎢ 0.2130189186834713⎥ ⎣0.24843830572599868⎦ 22222222222222222222222222
对应反向传播代码片段
delta := nn.cost_derivative(activations[len(activations)-1], y) fmt.Println(&delta) fmt.Println(mat.Formatted(delta)) fmt.Println("11111111111111111111111111") applySigmoidPrime := func(_, _ int, v float64) float64 { return sigmoidPrime(v) } zs[len(zs)-1].Apply(applySigmoidPrime, zs[len(zs)-1]) fmt.Println(&delta) fmt.Println(mat.Formatted(delta)) fmt.Println("22222222222222222222222222") delta.MulElem(delta, zs[len(zs)-1]) nabla_b[len(nabla_b)-1] = delta nabla_w[len(nabla_w)-1].Mul(delta, activations[len(activations)-1].T()) time.Sleep(100000000000)
已确认zs[len(zs)-1]与delta内存地址不同,但delta仍被修改。尝试使用临时矩阵、手动循环替代GoNum的Apply方法均无效,导致权重与偏置无法正确调整,请问该现象的原因是什么?
内容的提问来源于stack exchange,提问作者NRed12
相关产品推荐
相关产品推荐

