第 10 章 · 04 深度网络 FNN 本节摘要:本节进入深度学习,从最基础的前馈神经网络(FNN)开始。先用 NumPy 手写一个单层网络的反向传播,直观理解「链式法则如何把误差一层层传回去」;再用 TensorFlow 2 / Keras 用几行代码搭出同样的事,感受高级 API 的便利;最后落到一个真正的金融任务——预测美股日度收益,扫描网络架构(层数、宽度、dropout)寻找最佳组合。本节讲清四件事:前馈网络的「线性变换 + 激活」堆叠结构;反向传播与梯度下降的数学直觉;Keras 的 + + 模型搭建套路;以及如何在金融数据上做过拟合防护(早停、dropout、批量归一化)与架构搜索。读完本节,你能搭出能跑的深度收益预测模型,并理解金融深度学习最容易翻车的几个点。
本节摘要:本节进入深度学习,从最基础的前馈神经网络(FNN)开始。先用 NumPy 手写一个单层网络的反向传播,直观理解「链式法则如何把误差一层层传回去」;再用 TensorFlow 2 / Keras 用几行代码搭出同样的事,感受高级 API 的便利;最后落到一个真正的金融任务——预测美股日度收益,扫描网络架构(层数、宽度、dropout)寻找最佳组合。本节讲清四件事:前馈网络的「线性变换 + 激活」堆叠结构;反向传播与梯度下降的数学直觉;Keras 的
Sequential+Dense+Activation模型搭建套路;以及如何在金融数据上做过拟合防护(早停、dropout、批量归一化)与架构搜索。读完本节,你能搭出能跑的深度收益预测模型,并理解金融深度学习最容易翻车的几个点。
内容来源:原项目
17_deep_learning/01_build_and_train_feedforward_nn.ipynb、02_how_to_use_tensorflow.ipynb、04_optimizing_a_NN_architecture_for_trading.ipynb,汉化并套用体系化模板。
⚠️ 学习提示:深度网络在金融上的过拟合风险远超在图像/文本上——金融信噪比极低,网络容量稍大就会把噪声学成模式。务必用严格的早停 + 时序 CV + dropout,且永远保留一段「全程不碰」的 holdout。
阅读完本节,你应当能够:
一层前馈网络的数学很简单:
x 是输入向量,W 是权重矩阵,b 是偏置,\sigma 是非线性激活(ReLU、sigmoid、tanh 等)。把多层这样的变换堆起来,就得到一个深度网络:
为什么必须非线性激活?如果每层都是纯线性变换,多层堆叠等价于一个单层线性模型——非线性激活是网络能学复杂模式的根本。最常见的激活:
| 激活 | 形式 | 用途 |
|---|---|---|
| ReLU | \max(0, x) | 隐藏层默认 |
| sigmoid | 1/(1+e^{-x}) | 二分类输出 |
| softmax | 归一化指数 | 多分类输出 |
| tanh | \tanh(x) | 部分场景 |
💡 核心心法:深度网络学的是「层次化的特征表示」——第一层学简单模式(线性趋势),第二层把简单模式组合成复杂模式(动量 × 波动),层层抽象。这种「自动特征工程」是它相对线性模型的核心优势,但也是它在金融上易过拟合的根源——层次越多,可学的虚假模式越多。
notebook 01_build_and_train_feedforward_nn.ipynb 用纯 NumPy 手写一个单隐藏层网络,目标是直观展示反向传播。它在两个同心圆数据上做二分类(线性不可分,正好需要非线性):
# 数据参数 N = 50000; factor = 0.1; noise = 0.1 n_iterations = 50000; learning_rate = 0.0001; momentum_factor = .5 X, y = make_circles(n_samples=N, shuffle=True, factor=factor, noise=noise)
训练循环的核心是:
h = ReLU(W1 @ x),y_hat = softmax(W2 @ h);W -= learning_rate * gradient,可加动量(momentum)加速。链式法则的精髓:输出误差对深层权重的梯度,等于「误差对中间变量的梯度 × 中间变量对权重的梯度」一层层乘回去。手写一遍这个流程,你对深度学习就不再有黑盒感——它就是一组矩阵乘法 + 一个求导规则。
notebook 02_how_to_use_tensorflow.ipynb 用 Keras 把手写流程压缩成几行:
import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Activation model = Sequential([ Dense(units=16, input_dim=2), Activation('relu'), Dense(units=8), Activation('relu'), Dense(units=2), Activation('softmax') ]) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(X, Y, epochs=20, batch_size=256)
| 组件 | 作用 |
|---|---|
Sequential |
顺序堆叠层的容器 |
Dense(units=N) |
全连接层,N 是神经元数 |
Activation |
非线性激活 |
compile(optimizer, loss) |
选优化器与损失 |
fit(X, Y, epochs, batch_size) |
训练 |
Keras 还会自动检测 GPU:
gpu_devices = tf.config.experimental.list_physical_devices('GPU') if gpu_devices: tf.config.experimental.set_memory_growth(gpu_devices[0], True)
有 GPU 时按需分配显存(set_memory_growth),避免一次性占满。
notebook 04_optimizing_a_NN_architecture_for_trading.ipynb 把这套工具用到真正的金融任务上。数据是第 12 章构造的 model_data,~995 只美股 2010-2017 的日度收益:
data = pd.read_hdf('../12_gradient_boosting_machines/data.h5', 'model_data').dropna() lookahead = 1 outcome = f'r{lookahead:02}_fwd' X_cv = data.loc[idx[:, :'2017'], :].drop(outcomes, axis=1) y_cv = data.loc[idx[:, :'2017'], outcome]
特征包括波动、动量、滞后收益的横截面与行业排名——是第 12 章给 GBM 用过的同一套数据,方便横向对比。目标是用 FNN 预测 1 日前瞻收益。
金融深度学习的过拟合防护比一般任务更严:
from tensorflow.keras.layers import Dropout from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X_cv) model = Sequential([ Dense(64, input_dim=X_cv.shape[1], activation='relu'), Dropout(0.5), # 随机丢一半神经元 Dense(32, activation='relu'), Dropout(0.5), Dense(1) # 回归输出 ]) callbacks = [EarlyStopping(patience=10, restore_best_weights=True)] model.compile(optimizer='adam', loss='mse') model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=50, batch_size=128, callbacks=callbacks)
| 防护手段 | 作用 |
|---|---|
StandardScaler |
标准化特征,梯度稳定 |
Dropout |
训练时随机丢神经元,降模型有效容量 |
EarlyStopping |
验证集若干轮不改善即停,防过训练 |
BatchNormalization |
层间归一化,加速收敛 |
| 时序 CV + holdout | 严格按时间切,留一段全程不碰 |
notebook 用 itertools.product 遍历不同的(层数、宽度、dropout)组合,每个组合在 MultipleTimeSeriesCV 的每折上训练,记录样本外 Spearman IC:
for params in product(layer_configs, dropout_rates): for fold, (train_idx, test_idx) in enumerate(cv.split(X)): # 训练、评估 IC、记录
金融上的经验结论:
⚠️ 不要被训练损失欺骗:训练损失可以一直降,但金融信号弱,训练损失降到底往往意味着过拟合到底。唯一可信的指标是验证集 IC,且要看分布而非点估计。
Sequential + Dense + Activation + compile + fit,深度学习模板代码。下一节,我们看 LSTM 时序预测——用循环网络捕捉时间序列依赖,做股价和 SEC 文件收益预测。