在研究神经网络的反向传播的时候,不解一点,就是修改的是神经网络的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关联而已。