本课目标
理解神经网络的计算本质(矩阵乘法 + 非线性激活 + 梯度下降),用 Keras 训练 CNN 识别手写数字,准确率 99%+。
"神经网络"这四个字吓退了多少工程师。但剥开来看,一个神经元就是三行代码:矩阵乘法、加偏置、过激活函数。堆一千层也还是这三件事。本讲从手写一个感知机开始,让你亲眼看到:深度学习没那么玄。
核心内容
手写感知机:一个神经元的真相
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
class Perceptron:
def __init__(self, n_features, lr=0.1):
self.W = np.random.randn(n_features) * 0.01
self.b = 0.0
self.lr = lr
def forward(self, X):
return sigmoid(X @ self.W + self.b)
def train_step(self, X, y):
pred = self.forward(X)
error = pred - y
grad_W = X.T @ (error * pred * (1 - pred)) / len(X)
grad_b = np.mean(error * pred * (1 - pred))
self.W -= self.lr * grad_W
self.b -= self.lr * grad_b
20 行代码,一个能训练的神经元。forward 做预测,train_step 算梯度、更新参数。深度学习的"深"只是把几百个这样的神经元堆在一起,用链式法则逐层传递梯度——这个叫反向传播,框架帮你自动做了。
你不需要手写反向传播,但你需要知道:模型训练 = 反复执行"预测 → 算误差 → 反向传播 → 更新参数"。把握了这个循环,后面的 CNN、RNN、Transformer 都只是换了"怎么预测"这一步。
Keras CNN:MNIST 手写数字,99% 准确率
import tensorflow as tf
from tensorflow import keras
(X_train, y_train), (X_test, y_test) = keras.datasets.mnist.load_data()
X_train = X_train[..., None] / 255.0
X_test = X_test[..., None] / 255.0
model = keras.Sequential([
keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
keras.layers.MaxPooling2D(),
keras.layers.Conv2D(64, 3, activation='relu'),
keras.layers.MaxPooling2D(),
keras.layers.Flatten(),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(10, activation='softmax'),
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(X_train, y_train, epochs=5, validation_split=0.1, batch_size=128)
每层职责:Conv2D 提取局部特征(边缘→纹理→形状),MaxPooling 降采样增强抗位移能力,softmax 输出 0-9 的概率分布。adam 是自适应学习率的梯度下降变体——新手默认选它,大部分场景不需要调。
过拟合:训练集 99%,测试集 88%
validation_split=0.1 划出验证集。训练日志里 val_loss 上升但 train_loss 下降 = 模型在"背诵"训练集而不是"理解"规律。对策:数据增强(一张图变成十张)、Dropout(随机关神经元)、早停(val_loss 不降了就停)。
动手练习
- 跑通 MNIST CNN,观察 5 个 epoch 的 val_accuracy 曲线
- 去掉所有卷积层只留 Dense,对比准确率差距——体会"卷积为什么在图像上碾压全连接"