10分钟搞懂一个基于C的最简神经网络
10分钟0基础搞懂一个基于C的最简神经网络
00 这是什么
一个 150行纯C代码 的神经网络,不调任何库,用手写的矩阵运算 + 反向传播,教会网络认识 XOR(异或) 逻辑。读完你能摸清神经网络的骨架,还能自己调参玩起来。
01 网络长什么样
输入层(2) → 隐藏层(4) → 输出层(1) x0,x1 h0..h3 y
2个输入
:XOR 的两个操作数(0或1) 4个隐藏神经元
:网络的“思考空间”,太少学不会 XOR,太多浪费 1个输出
:0~1 之间的数,越接近0表示“假”,越接近1表示“真”
每个连接都有一个权重 W,每个神经元都有一个偏置 b。这些就是网络要学的东西。
02 三件套:前向 → 反向 → 更新
神经网络训练就是一个死循环做三件事:
前向传播 (forward)
输入 x → W1*x + b1 → sigmoid → 隐藏层激活值 a1 → W2*a1 + b2 → sigmoid → 输出 a2(预测值)
把输入一层层算过去,得到预测结果。
反向传播 (backward)
输出层误差 = (预测值 - 真实值) × sigmoid'(a2)隐藏层误差 = (W2的转置 × 输出层误差) × sigmoid'(a1)
误差从输出层往回传,算出每个神经元对误差“贡献”了多少。
更新权重 (update_weights)
W = W - 学习率 × delta × 输入b = b - 学习率 × delta
沿着误差减小的方向挪一小步。学习率控制步长。
03 激活函数:Sigmoid
double sigmoid(double x) { return 1.0 / (1.0 + exp(-x));}把任意实数压到 (0, 1) 区间,给网络引入非线性。没有它,多层网络等价于一层,根本学不会 XOR。
其导数长得漂亮:sigmoid'(a) = a * (1 - a),反向传播时直接用激活值算,不需要重新算指数。
04 为什么是 XOR
XOR 是神经网络的 hello world——线性不可分,单层网络搞不定,必须有隐藏层。学会了 XOR,就理解了“深度”的意义。
05 损失函数:MSE
loss += 0.5 * (预测 - 真实)²
均方误差。前面的 0.5 是为了求导后消掉平方的2,纯属数学便利。
06 可以玩的参数
改这些参数重新编译运行,观察输出变化:
学习率 lr | train() | 0.5 | 0.01:学太慢,loss降不动;调成 5.0:直接发散,loss爆炸 |
训练轮数 epochs | train() | 1000000 | 10000:没学会,输出不准;XOR 不需要这么多轮只是图稳 |
| 隐藏层大小 | #define HIDDEN_SIZE | 4 | 2:可能学不会或很不稳定;改成 8:收敛更快 |
| 随机种子 | init_net()srand(42) | 42 | |
| 权重初始化范围 | * 2.0 - 1.0 | [-1, 1] | * 0.2 - 0.1:初始权重太小,梯度消失,学不动;改成 * 6.0 - 3.0:太大,sigmoid饱和,也学不动 |
| 训练数据 | targets[4] | {0,0,0,1} 就是 AND;换成 {0,1,1,1} 就是 OR——会发现比 XOR 好学得多 |
实操建议
把 main() 里的 train() 调用改成:
train(&net, inputs, targets, 4, 10000, 0.1);
观察 loss 曲线和最终预测值,感受“没学会”是什么样。再逐步加大 epochs 或调学习率,看什么时候能学会。
07 极简心智模型
网络 = 一堆权重参数训练 = 反复做:猜 → 看差多少 → 反着传误差 → 参数挪一小步推理 = 只做前向传播,输出就是答案
三个核心公式刻进脑子里:
output = sigmoid(W × input + b) | |
delta = error × sigmoid'(output) | |
W = W - lr × delta × input |
08 完整运行
gcc -o nn try.c -lm./nn
输出示例:
Epoch 0, Loss = 0.253278Epoch 1000, Loss = 0.249450...Epoch 999000, Loss = 0.000003Testing XOR:0 XOR 0 = 0.000144 (expected 0)0 XOR 1 = 0.999682 (expected 1)1 XOR 0 = 0.999677 (expected 1)1 XOR 1 = 0.000194 (expected 0)
09 下一步
搞懂这个150行之后,顺藤摸瓜去看这些概念不会有陌生感:
ReLU
替换 sigmoid:解决梯度消失,现代网络标配 Softmax + 交叉熵
:分类问题的标配输出+损失组合 Batch/批次训练
:不是一个个样本更新,而是一批一起算平均梯度 Adam 优化器
:自动调学习率,比固定 lr 聪明得多 过拟合 & 正则化
:网络背答案而不是学规律
这150行C代码,就是所有深度学习框架(PyTorch、TensorFlow)在做的事情——只是它们把矩阵运算搬到了GPU,加了自动求导,包了层Python而已。
注:转载文章来源于网络,版权归原作者或企业所有,侵删!