[英]Deep learning: the code for backpropagation in Python
我正在阅读免费的在线书籍,并且正在为某些代码而苦苦挣扎。
(代码来自 Michael Nielsen)
class Network(object):
def update_mini_batch(self, mini_batch, eta):
"""Update the network's weights and biases by applying
gradient descent using backpropagation to a single mini batch.
The "mini_batch" is a list of tuples "(x, y)", and "eta"
is the learning rate."""
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
for x, y in mini_batch:
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
self.weights = [w-(eta/len(mini_batch))*nw
for w, nw in zip(self.weights, nabla_w)]
self.biases = [b-(eta/len(mini_batch))*nb
for b, nb in zip(self.biases, nabla_b)]
def backprop(self, x, y):
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
# feedforward
activation = x
activations = [x] # list to store all the activations, layer by layer
zs = [] # list to store all the z vectors, layer by layer
for b, w in zip(self.biases, self.weights):
z = np.dot(w, activation)+b
zs.append(z)
activation = sigmoid(z)
activations.append(activation)
# backward pass
因为它说mini_batch
是一个元组列表(x, y)
,所以 function backprop
中x
的参数是一个标量,对吧? 如果是这样,因为w
(权重)是一个矩阵(比如它的维度是n*p
),它的行在第l
层有n
神经元,列在l-1
层有p
个神经元。 那么, x
必须是nx 1
向量。 我感到困惑。
在本书的示例中,它使用了[2,3,1]
,即三层分别具有 2,3 和 1 个神经元。 因为第一层输入,它有两个元素。 所以第 2 层的权重矩阵有 3*2 维。 似乎x
应该是一个长度为 2 的向量来与w
进行矩阵乘法。
此外,关于C_x
关于激活 a 的偏导数的代码如下:
def cost_derivative(self, output_activations, y):
"""Return the vector of partial derivatives \partial C_x /
\partial a for the output activations."""
return (output_activations-y)
我检查了我理解的公式( output_activations-y
)意味着成本的变化。 但这应该除以激活的变化吗?
你可以帮帮我吗?
因为它说“mini_batch”是元组“(x,y)”的列表,所以function反向传播中x的参数是一个标量,对吧?
不,“批次”一词对应于 python 列表。 在批处理/python 列表中有像(x, y)
这样的对,其中x
表示输入向量, y
是 label。 x
的形状取决于您如何创建网络 object。 在[2, 3, 1]
的情况下,x 应该是形状为(2,)
的向量。
但这应该除以激活的变化吗?
不。
首先,您正在考虑的内容称为“数值微分”。 既然你没有成本的变化,你不应该通过激活的变化来分割它。
其次,作者使用的东西叫做“解析微分”。 比如说,你有一个 function f(x, y) = 0.5*(xy)^2
。 f
w.r.t 的偏导数。 x
是xy
。 因此,您不需要将它除以x
的变化。 但是,您需要注意实际使用的成本 function 以便导出正确的导数。 有时,如何计算这些值并不明显。 在这种情况下,损失是均方误差,如在线书籍中所述。
回复评论:
输入为vector_x = (1,2,3)的训练集
训练集应该是一个包含一组训练样本的容器,其中每个训练样本由一个输入和对应的 label 组成。 因此,小批量的示例可能是 python 列表,例如: [([0, 1], [1, 2]), ([2, 1], [3, 2])]
,这表明存在是两个训练样本。 第一个是([0, 1], [1, 2])
,第二个是([2, 1], [3, 2])
。 以第一个为例,它的输入是[0, 1]
(形状为(2,)
的向量),它的 output 是[1, 2]
,也就是说,输入和期望的 output 都是单次训练样本可以是向量。 您的问题( [(1,a),(2,b),(3,c)]
)有一些含糊之处,所以我更喜欢我的解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.