Python的传递引用

  在研究神经网络的反向传播的时候,不解一点,就是修改的是神经网络的paramets,为什么影响内部的神经元(层),比如Affine层;因为除了创建的时候,使用params作为Affine层的构造函数参数之外,根本没有再使用。关系如下:

 1 class TwoLayerNet:
 2 
 3     def __init__(self, input_size, hidden_size, output_size, weight_init_std = 0.01):
 4         self.params = {}
 5         self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
 6         self.params['b1'] = np.zeros(hidden_size)
 7         ... ...
 8 
 9         self.layers = OrderedDict()
10         self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1'])
11         ... ...

  后来才发现其实python里面也是和Java一样,对于对象类型传值是传递引用。

  为什么呢?因为你会发现如果是对于值进行修改,将会体现出来Affine层的变化;但是如果你要是直接对于值进行变化,比如设置为None,或者设置一个新的值,那么就不会发生变化:

1 network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
2 print("before first layer parames: ", network.layers['Affine1'].W[0])
3 network.params["W1"] = None
4 print("after first layer parames: ", network.layers['Affine1'].W[0])

  但是如果你做的是减法,则会发现W值发生了变化:

1     for key in ('W1', 'b1', 'W2', 'b2'):
2         network.params[key] -= learning_rate * grad[key]
3     print("grad[key]: ", grad[key])
4     print("after  first layer parames: ", network.layers['Affine2'].W[0])

  这个就是因为Affine的W是network的params的引用,如果你设置为None之后,其实改变的是params的引用,但是原本的引用仍然存在,只不过没有和params关联而已。

原文地址:https://www.cnblogs.com/xiashiwendao/p/10983153.html