# 随机梯度下降

SGD()实现随机梯度下降算法。

## 入参

training\_data：训练样本集。\
epochs：迭代次数\
mini\_batch\_size：每次随机取的样本数\
eta：学习率\
test\_data：如果有设置test\_data，每一次迭代结束后用测试数所来检查一下当前迭代之后的效果。在这一章中不讲这部分内容。

## 一次迭代

直观上，每一次迭代是指随机取mini\_batch\_size个数据对算法做一次参数调整。\
但这种方法的问题是：每次都是全部样本中随机取，很有可能部分样本取了很多次而部分样本始终没有取到。

书上所谓的每一次迭代是这样的：\
`for j in range(epochs):`\
1\. 对全部样本进行一次随机化\
`random.shuffle(training_data)`\
2\. 将全部样本分成$$\frac{样本数}{mini\_batch\_size}$$份，每一份的样本数为mini\_batch\_size。\
`training_data[k:k+mini_batch_size] for k in range(0, n, mini_batch_size)]`\
3\. 依次取每一份对算法做一次参数调整。\
`update_mini_batch(mini_batch, eta)`\
这样所有样本都刚好轮一遍，称为一次迭代。\
一次迭代中每一次的参数调整所使用的样本是随机的。

## 一次参数调整

`update_mini_batch()`实现一次参数的调整。\
这个函数是真正将梯度更新算法与神经元相结合的地方。但代码很直观。\
1\. 依次基于**每个样本**计算**所有神经元**的偏导。

```python
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
```

backprop()不在本章介绍的范围，知道它是求偏导的函数就可以了。\
2\. 把每个样本的计算结果加起来，就是基于**所有样本**计算的**所有神经元**的偏导。

```python
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)]
```

1. 针对**每个神经元**计算它们新参数 &#x20;

   ```
   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)]
   ```

**说明：** 1. `delta_nabla_b`、`delta_nabla_w`、`nabla_b`、`nabla_w`、`self.weights`、`self.biases`这些变量存储的都是整个神经网络的参数，所以结构都是样同的。参照[初始化](https://windmising.gitbook.io/nielsen-nndl/introduction/shi-xian-shu-zi-fen-lei-de-shen-jing-wang-luo/2)页面中的例子\
2\. nb、dnb、w、nw、b、nb存储的是一层神经网络的参数，相当于是上面这些变量list中的一项。\
3\. 上面这些计算看不去有点绕，把初始化看懂这里就好理解了。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://windmising.gitbook.io/nielsen-nndl/introduction/shi-xian-shu-zi-fen-lei-de-shen-jing-wang-luo/4.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
