> For the complete documentation index, see [llms.txt](https://book.ncrnalab.org/teaching/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.ncrnalab.org/teaching/5.model-programming.md).

# 5.Model Programming

神经网络（Neural Networks）在机器学习领域中是一种强大的工具，例如，可以用NN拟合复杂的数学公式和模式。以下是如何使用神经网络拟合数学公式的基本步骤：

## 1) 背景与原理

### 1. 单层感知机

对于输入 $$x \in R$$ ，感知机首先将其映射到一个标量 $$z= w^{\top} x+b,$$\
再通过激活函数（阶跃、sigmoid 等）得到输出 $$\hat y=\sigma(z)$$。感知机能拟合所有**线性可分**布尔函数（AND、OR、NOT 等）——权重与阈值示例如下：

![](/files/X3ShExldv3hiqLnsYtW5)

| 逻辑函数 | $$w$$   | $$b$$ |
| ---- | ------- | ----- |
| AND  | ((1,1)) | (-2)  |
| OR   | ((1,1)) | (-1)  |
| NOT  | ((-1))  | (0)   |

![](/files/30QbCS8Ybay94zKdc83S)

> 感知机无法表示XOR，1969 年的《Perceptrons》对此给出经典反例。

### 2. 多层感知机（MLP）

通过在输入与输出之间加入隐藏层（非线性激活），MLP 可以逼近任意连续函数。含一层隐藏层的表达式

$$
\begin{aligned}\mathbf h &=\phi!\bigl(W^{(1)}\mathbf x+\mathbf b^{(1)}\bigr), \\
\hat y   &=\psi!\bigl(W^{(2)}\mathbf h+b^{(2)}\bigr).\end{aligned}
$$

**XOR 示例** PPT 给出的两隐层神经元权重可实现

$$
h\_1=\text{AND}(x\_1,\lnot x\_2),\quad\
h\_2=\text{AND}(\lnot x\_1,x\_2),\quad\
\hat y=h\_1\lor h\_2,
$$

从而精确复现 XOR 函数。

![](/files/mjVCNqW9QO7jTJuivyod)

### 3. 训练与评估

PPT 采用 **均方误差 (MSE)** 作为损失：

$$
\mathcal L=\frac1N\sum\_{i=1}^{N}\bigl(\hat y^{(i)}-y^{(i)}\bigr)^2,
$$

并将数据随机切分为 *Training* / *Test*，在 512 个隐藏神经元的 MLP 上训练至收敛，再用测试集评估预测误差——同样适用于一般数学公式拟合任务。

## 2) 步骤式指南

![](/files/Zo0pmbOy0XmhdAFnwrlT)

### 1. 数据准备

首先，你需要准备用于训练神经网络的数据集。这些数据应包含输入值和对应的输出值，这些输出值由你想要拟合的数学公式计算得出。

### 2. 选择网络结构

选择一个适合你问题的神经网络结构。对于大多数数学公式拟合问题，一个前馈神经网络（Feedforward Neural Network）就足够了。你需要决定网络的层数、每层的神经元数量以及激活函数。

### 3. 数据预处理

对输入数据进行预处理，如归一化或标准化，以确保神经网络能够更有效地学习。

### 4. 构建网络

使用深度学习框架（如TensorFlow、PyTorch等）构建神经网络。以下是一个使用PyTorch的简单示例：

```python
import torch
import torch.nn as nn
import torch.optim as optim
# 定义网络结构
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(n_inputs, 128)  # 输入层到隐藏层
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(128, 128)       # 隐藏层到隐藏层
        self.fc3 = nn.Linear(128, n_outputs) # 隐藏层到输出层
    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu(x)
        x = self.fc3(x)
        return x
# 实例化网络
net = Net()
```

### 5. 训练网络

使用训练数据来训练神经网络。这通常涉及前向传播、计算损失、反向传播和更新权重。

```python
criterion = nn.MSELoss()  # 使用均方误差作为损失函数
optimizer = optim.Adam(net.parameters(), lr=0.001)  # 使用Adam优化器
# 训练循环
for epoch in range(n_epochs):
    for inputs, labels in train_loader:
        optimizer.zero_grad()   # 清空梯度
        outputs = net(inputs)   # 前向传播
        loss = criterion(outputs, labels)  # 计算损失
        loss.backward()         # 反向传播
        optimizer.step()        # 更新权重
```

### 6. 评估和测试

使用测试数据集评估神经网络的性能。如果网络能够很好地拟合测试数据，那么它很可能也能够很好地拟合未知的数学公式。

### 7. 使用网络进行预测

一旦网络训练完成，你就可以使用它来预测新的输入值对应的输出值。

```python
# 使用训练好的网络进行预测
with torch.no_grad():
    predictions = net(test_inputs)
```

### 8. 预期结果

| ![](/files/m4SHWR22Afoj2tfwkq2V) | ![](/files/Ek0ZRXC9xLRXl7EmWjnK) | ![](/files/M8yWAc6Z23dDtujK8KbS) |
| -------------------------------- | -------------------------------- | -------------------------------- |
| ![](/files/3L2EQcisF98R9m4JfDsP) | ![](/files/INdR8HVkMaCp2Cx2dxMK) | ![](/files/OhlcCPwdmIKHwxtmuPKY) |

## 3) 报告要求

* **提交一份完整的工作报告** (中英文不限)，需要提供主要的代码

> 报告模板可以参考如下文章：
>
> [2017 Attention is all you need](https://proceedings.neurips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf)

* **注意事项**
* 确保你的数据集足够大且具有代表性，以便神经网络能够学习到数学公式的真实模式。
* 调整网络结构和超参数（如学习率、层数、神经元数量等）可能会影响网络的学习能力和最终性能。
* 过拟合是一个常见问题，可以通过正则化、提前停止或使用更多的训练数据来缓解。\
  通过以上步骤，你可以使用神经网络来拟合复杂的数学公式。
