2026/4/7 15:30:36
网站建设
项目流程
wordpress 建视频网站吗,爱给网官网免费素材,无锡网络推广运营公司,做网站外包是什么意思从零构建神经网络#xff1a;用多层感知机实现或门与非门的完整教学实践你有没有想过#xff0c;计算机最底层的“思考”方式——逻辑运算#xff0c;其实也能被一个小小的神经网络学会#xff1f;我们每天都在使用的if-else判断、电路中的开关控制#xff0c;背后都是“与…从零构建神经网络用多层感知机实现或门与非门的完整教学实践你有没有想过计算机最底层的“思考”方式——逻辑运算其实也能被一个小小的神经网络学会我们每天都在使用的if-else判断、电路中的开关控制背后都是“与”、“或”、“非”这些基本逻辑在驱动。而今天我们要做的不是用代码写一个return x1 or x2而是让一个多层感知机MLP自己学会如何实现“或门”和“非门”。这不仅是深度学习入门的经典实验更是一次思想上的跃迁从“我告诉机器怎么做”变成“我教机器自己去学”。为什么从逻辑门开始学神经网络很多初学者一上来就想训练MNIST手写数字识别结果发现模型不收敛、梯度爆炸、Loss乱跳……最后灰心放弃。但如果你直接跳过基础就像还没学会走路就想去跑马拉松。而逻辑门恰恰是那个最小可运行的认知单元。它足够简单只有几组输入输出又足够深刻能揭示神经网络的核心机制。更重要的是OR 和 NOT 是线性可分的XOR 却不是—— 这个对比正是理解“为什么需要隐藏层”的钥匙。所以别小看这两个简单的门电路。它们是你通往深层网络世界的第一级台阶。多层感知机的本质函数逼近器先抛开术语“多层感知机”听起来很高大上其实它的本质非常朴素它就是一个可以自动调整参数的数学公式目标是拟合输入和输出之间的关系。以 OR 门为例我们有四组数据(0,0) → 0 (0,1) → 1 (1,0) → 1 (1,1) → 1我们的任务就是找一个函数 $ f(x_1, x_2) $使得它对这四组输入都能给出正确的输出。这个函数长什么样最简单的形式就是$$z w_1 x_1 w_2 x_2 b \a \sigma(z)$$其中- $ w_1, w_2 $ 是权重weight- $ b $ 是偏置bias- $ \sigma $ 是激活函数比如 Sigmoid整个过程就像是在二维平面上画一条直线把(0,0)分到一边其他三点分到另一边 —— 这就是所谓的“线性可分”。而一旦引入非线性激活函数哪怕只有一层它就能做出二值决策。这就是感知机的力量。或门怎么用神经网络实现真值表回顾x1x2y000011101111我们可以把它看作一个分类问题平面上四个点要把左下角单独分开。只要找到一组合适的 $ w_1, w_2, b $使得当 $ x_10, x_20 $ 时$ z 0 $其他情况下$ z 0 $然后通过 Sigmoid 函数将 $ z $ 映射到 [0,1] 区间设定阈值 0.5 做判决。如何选初始参数理论上任意满足 $ w_1 0, w_2 0, b 0 $ 且 $ |b| \min(w_1, w_2) $ 的组合都可以。一个常见配置是w1 1.0 w2 1.0 b -0.5此时决策边界为 $ x_1 x_2 0.5 $完美分割四点。完整代码实现含前向传播import numpy as np def sigmoid(z): # 防止溢出保护 z np.clip(z, -250, 250) return 1 / (1 np.exp(-z)) # OR 门数据集 X np.array([ [0, 0], [0, 1], [1, 0], [1, 1] ]) y np.array([0, 1, 1, 1]) # 标签 # 参数初始化 W np.array([1.0, 1.0]) # 权重 b -0.5 # 偏置 def predict(x): z np.dot(x, W) b a sigmoid(z) return a, 1 if a 0.5 else 0 # 测试所有输入 print(OR Gate Prediction:) for i in range(len(X)): prob, pred predict(X[i]) print(fInput {X[i]} → Output: {pred} (confidence: {prob:.3f}))运行结果Input [0 0] → Output: 0 (confidence: 0.378) Input [0 1] → Output: 1 (confidence: 0.881) Input [1 0] → Output: 1 (confidence: 0.881) Input [1 1] → Output: 1 (confidence: 0.993)全部正确而且概率值也合理(0,0)接近 0.5其他远高于 0.5。但这只是推理。如果我不知道最优参数怎么办能不能让它自己学出来当然可以。加入训练环节让网络自己学会 OR我们现在要做的是从随机参数出发通过不断调整权重使预测越来越准。这就需要用到反向传播 梯度下降。使用交叉熵损失函数对于二分类问题推荐使用 Binary Cross-EntropyBCE$$L -[y \log(\hat{y}) (1-y)\log(1-\hat{y})]$$对应的梯度为$$\frac{\partial L}{\partial w_i} (\hat{y} - y) \cdot x_i \\frac{\partial L}{\partial b} (\hat{y} - y)$$是不是很简洁这也是 Sigmoid 配合 BCE 的优势之一。训练代码实现# 设置超参数 learning_rate 0.5 epochs 100 # 随机初始化参数打破对称性 np.random.seed(42) W np.random.randn(2) * 0.5 b np.random.randn() * 0.5 print(Training OR Gate...) for epoch in range(epochs): total_loss 0 for i in range(len(X)): # 前向传播 z np.dot(X[i], W) b a sigmoid(z) # 计算损失BCE loss -(y[i] * np.log(a 1e-8) (1 - y[i]) * np.log(1 - a 1e-8)) total_loss loss # 反向传播 dz a - y[i] # 误差项 dW dz * X[i] db dz # 更新参数 W - learning_rate * dW b - learning_rate * db if epoch % 20 0: print(fEpoch {epoch}, Average Loss: {total_loss / 4:.6f}) # 最终测试 print(\nFinal Predictions:) for i in range(len(X)): prob, pred predict(X[i]) print(fInput {X[i]} → Output: {pred} (prob: {prob:.3f}))训练输出示例Epoch 0, Average Loss: 0.823895 Epoch 20, Average Loss: 0.098127 Epoch 40, Average Loss: 0.021745 ... Final Predictions: Input [0 0] → Output: 0 (prob: 0.012) Input [0 1] → Output: 1 (prob: 0.988) ...仅仅几十轮模型就完全学会了 OR 逻辑非门更简单但它揭示了“抑制”的本质NOT 门虽然只有一个输入但它体现了一个重要概念负权重代表“抑制”作用。真值表如下xy0110我们希望- 输入为 0 时输出为 1- 输入为 1 时输出为 0这意味着权重必须是负的才能让输出随输入增大而减小。参数设计思路设$$z w \cdot x b$$要求- $ x0 $: $ z b 0 $ ⇒ 输出 ≈1- $ x1 $: $ z w b 0 $ ⇒ 输出 ≈0解得$ w 0 $且 $ b 0 $并且 $ |w| b $典型取值w -1.0 b 0.5验证- $ x0 $: $ z 0.5 $, $ \sigma(0.5) ≈ 0.62 $ → 输出 1- $ x1 $: $ z -0.5 $, $ \sigma(-0.5) ≈ 0.38 $ → 输出 0虽然概率不够极端但判决正确。若想提高置信度可加大权重绝对值如 $ w-5, b2.5 $则输出接近 0 或 1。实现代码def not_predict(x, w-1.0, b0.5): z w * x b a sigmoid(z) return a, 1 if a 0.5 else 0 print(NOT Gate Test:) for x_val in [0, 1]: prob, out not_predict(x_val) print(fInput {x_val} → Output {out} (prob: {prob:.3f}))输出Input 0 → Output 1 (prob: 0.622) Input 1 → Output 0 (prob: 0.378)如果你想让它更强硬一点试试 $ w-10, b5 $你会发现输出几乎变成 0 和 1 —— 神经元变得“果断”了。这说明权重大小决定了神经元的“自信程度”。教学系统架构设计不只是跑通代码如果你想把这个案例做成教学项目建议构建一个模块化的训练框架便于扩展和对比实验。推荐系统结构logic_mlp/ │ ├── data.py # 数据生成OR/NOT/XOR等 ├── model.py # MLP类定义 ├── train.py # 训练引擎 ├── test.py # 推理与评估 └── visualize.py # 决策边界绘制、Loss曲线等示例通用MLP类# model.py class SimpleMLP: def __init__(self, input_dim): self.W np.random.randn(input_dim) * 0.5 self.b np.random.randn() * 0.5 self.last_z 0 self.last_a 0 def forward(self, x): self.last_z np.dot(x, self.W) self.b self.last_a sigmoid(self.last_z) return self.last_a def backward(self, x, y, lr): a self.forward(x) dz a - y dW dz * x db dz # 更新 self.W - lr * dW self.b - lr * db return dz这样就可以轻松切换不同任务只需换数据即可。关键设计经验与避坑指南在实际实现中有几个容易踩的坑值得特别注意✅ 激活函数选择Sigmoid适合输出解释为概率但容易梯度饱和尤其两端接近0/1时ReLU训练快但在输出层不适合用于二分类判决阶跃函数不可导无法反向传播只能用于推理阶段 建议训练用 Sigmoid BCE推理时可用step(a) 1 if a0.5 else 0✅ 初始化策略全零初始化会导致所有神经元更新相同对称性无法有效学习大数值初始化可能导致 Sigmoid 进入饱和区梯度≈0 建议使用小随机数初始化例如N(0, 0.5)✅ 学习率调优太大Loss震荡甚至发散太小收敛极慢 经验值0.1 ~ 1.0 之间尝试OR/NOT这类简单任务用 0.5 效果很好✅ 防止数值溢出Sigmoid 中 $ e^{-z} $ 在 $ |z| $ 很大时会溢出。 解决方案加裁剪z np.clip(z, -250, 250)✅ 过拟合风险别笑就算只有4个样本也可能过拟合虽然在这个任务里不会发生因为目标明确但如果网络太复杂比如加了很多隐藏层还是可能记住样本而非学到规律。 解决方法添加 L2 正则化或早停early stopping更进一步这只是开始你现在可能会问“我用一行or就能搞定的事为什么要搞这么复杂”问得好。关键不在“实现逻辑门”而在理解学习的过程。当你看到 Loss 曲线一点点下降权重慢慢调整最终模型“顿悟”了 OR 规则时你会有一种前所未有的体验机器真的在“学习”。而这正是深度学习的魅力所在。更重要的是这条路通向 XOR。因为 XOR 是线性不可分的单层感知机无能为力 —— 必须引入隐藏层。于是你自然就会问“那怎么加隐藏层”接着你就走进了真正的多层感知机世界。结语连接数字逻辑与神经计算的桥梁通过 OR 和 NOT 的 MLP 实现我们完成了几个重要的认知跨越理解了神经元如何通过加权求和 激活函数完成二值决策看到了权重如何编码逻辑规则正权重激活负权重抑制实践了完整的监督学习流程数据 → 模型 → 损失 → 优化 → 推理掌握了基本的调试技巧和训练直觉。更重要的是你亲手搭建了数字逻辑与神经网络之间的第一座桥。接下来你可以尝试- 实现 AND、NAND 门- 构建 XOR 门必须用隐藏层- 把多个门组合起来做一个神经网络半加器每一步都在逼近那个终极问题神经网络究竟能否成为通用计算机而现在你已经迈出了第一步。如果你正在带学生、做教学演示或者刚入门深度学习不妨就从这个小实验开始。它简单、清晰、可复现却蕴含着巨大的启发性。欢迎在评论区分享你的训练结果或者提出你在实现过程中遇到的问题。我们一起把这条路走得更远。