我正在阅读 free online book 并且我在代码的某些部分苦苦挣扎。
(代码来源于 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)
,所以函数 x
中 backprop
的参数是一个标量,对吧?如果是这样,因为w
(权重)是一个矩阵(假设它的维度是n*p
),它的行在第n
层有l
个神经元,列有{{ p
层中的 1}} 个神经元。那么,l-1
必须是 x
向量。我感到很困惑。
在书中的例子中,它使用了 n x 1
,即分别具有 2,3 和 1 个神经元的三层。因为第一层输入,它有两个元素。所以第二层的权重矩阵有 3*2 维。似乎 [2,3,1]
应该是一个长度为 2 的向量来与 x
进行矩阵乘法。
另外,w
关于激活a的偏导代码如下:
C_x
我检查了公式,我知道 (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)
) 表示成本的变化。但这是否应该除以激活的变化?
你能帮我吗?
答案 0 :(得分:1)
因为它说 "mini_batch" 是一个元组列表 "(x, y)",所以函数 backprop 中 x 的参数是一个标量,对吗?
没有。 “batch”这个词对应于一个python列表。在批处理/python 列表中,有像 (x, y)
这样的对,其中 x
代表输入向量,y
是标签。 x
的形状取决于您创建网络对象的方式。在 [2, 3, 1]
的情况下,x 应该是形状为 (2,)
的向量。
但这应该除以激活的变化吗?
没有
首先,你在想什么叫做“数值微分”。既然你没有成本的变化,你不应该用激活的变化来划分。
其次,作者使用的称为“分析微分”。假设您有一个函数 f(x, y) = 0.5*(x-y)^2
。 f
w.r.t. 的偏导数x
是 x-y
。因此,您不需要将其除以 x
的变化。但是,您需要注意所使用的实际成本函数,以便推导出正确的导数。有时,如何计算这些值并不明显。在这种情况下,损失是均方误差,如在线书中所述。
回复评论:
<块引用>输入为vector_x = (1,2,3)的训练集
训练集应该是一个包含一组训练样本的容器,其中每个训练样本由一个输入和对应的标签组成。所以,小批量的一个例子可能是一个 python 列表,如:[([0, 1], [1, 2]), ([2, 1], [3, 2])]
,它表明有两个训练样本。第一个是([0, 1], [1, 2])
,第二个是([2, 1], [3, 2])
。以第一个为例,它的输入是[0, 1]
(形状为(2,)
的向量),它的输出是[1, 2]
,这意味着单个的输入和期望的输出训练样本可以是向量。您的问题 ([(1,a),(2,b),(3,c)]
) 中存在一些歧义,因此我更愿意解释。