4. Keras模型训练入门:全连接网络构建、激活函数选择、损失函数与优化器、训练与验证
好,咱们进入实战环节了。前面聊了那么多理论,现在该动手了。这一章,我会带你走一遍Keras模型训练的完整流程。说白了,就是教会你怎么用几行代码,搭出一个能跑的全连接网络。
我个人习惯,学新东西先跑通一个最小例子。有了手感,再深入细节。咱们就从最基础的全连接网络开始。
4.1 全连接网络构建:从零搭积木
全连接网络,也叫密集连接网络。每一层的每个神经元,都和上一层的所有神经元相连。你想想看,这就像公司里每个人都能直接给老板汇报——信息传递很充分,但层级多了就乱套。
在Keras里,构建全连接网络用 Dense 层。我一般这样写:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model = Sequential([
Dense(64, activation='relu', input_shape=(10,)),
Dense(32, activation='relu'),
Dense(1, activation='sigmoid')
])
这段代码干了三件事:
- 输入层:接收10个特征的数据
- 隐藏层:第一层64个神经元,第二层32个神经元
- 输出层:1个神经元,用sigmoid做二分类
嗯,这里要注意 input_shape 参数。它只在第一层指定,后面的层会自动推导输入维度。我曾经见过有人每层都写 input_shape,结果维度对不上,报错半天找不出原因。
4.2 激活函数选择:给网络注入非线性
激活函数,说白了就是给神经网络引入非线性能力。没有它,再多层也只是线性变换的堆叠,解决不了复杂问题。
常用的激活函数就这几个:
| 函数名 | 公式 | 输出范围 | 适用场景 |
|---|---|---|---|
| ReLU | max(0, x) | [0, +∞) | 隐藏层首选 |
| Sigmoid | 1/(1+e⁻ˣ) | (0, 1) | 二分类输出层 |
| Tanh | (eˣ-e⁻ˣ)/(eˣ+e⁻ˣ) | (-1, 1) | RNN、归一化数据 |
| Softmax | eˣⁱ/∑eˣʲ | (0,1) 和为1 | 多分类输出层 |
我个人习惯,隐藏层无脑用ReLU。为什么?计算简单,梯度不容易消失。但要注意——ReLU有个毛病叫「神经元死亡」。如果输入一直为负,梯度就是0,这个神经元就再也学不动了。
输出层的选择就明确多了:
- 二分类 →
sigmoid - 多分类 →
softmax - 回归问题 → 不用激活函数(linear)
4.3 损失函数与优化器:训练的「方向盘」和「油门」
损失函数告诉模型「你错得有多离谱」,优化器告诉模型「怎么调整才能更好」。两者缺一不可。
损失函数怎么选?
我总结了一个简单对照表:
| 问题类型 | 损失函数 | Keras名称 |
|---|---|---|
| 二分类 | 二元交叉熵 | binary_crossentropy |
| 多分类 | 分类交叉熵 | categorical_crossentropy |
| 回归 | 均方误差 | mse |
| 回归(鲁棒) | 平均绝对误差 | mae |
你想想看,如果分类问题用了MSE,梯度会很小,训练慢得像蜗牛。我刚开始学的时候犯过这个错,训练了100个epoch loss还在0.5以上,后来换成交叉熵,10个epoch就收敛了。
优化器怎么选?
优化器这块,我推荐新手直接上 Adam。它自适应学习率,大部分场景表现都不错。
from tensorflow.keras.optimizers import Adam
model.compile(
optimizer=Adam(learning_rate=0.001),
loss='binary_crossentropy',
metrics=['accuracy']
)
常用的优化器对比:
- SGD:经典但慢,需要精细调学习率
- Adam:自适应,收敛快,适合大多数场景
- RMSprop:适合RNN,对非平稳目标效果好
- Adagrad:适合稀疏数据,但学习率会衰减到0
4.4 训练与验证:看模型到底学得怎么样
模型搭好了,损失函数和优化器也选好了。接下来就是训练。Keras里训练就一行代码:
history = model.fit(
x_train, y_train,
epochs=50,
batch_size=32,
validation_split=0.2,
verbose=1
)
这里几个参数我说一下:
- epochs:遍历整个训练集的次数。不是越多越好,多了会过拟合。
- batch_size:每次更新参数用的样本数。32、64、128是常用值。
- validation_split:从训练集里划出20%做验证集。
- verbose:1显示进度条,0安静模式,2每个epoch一行。
训练完成后,history.history 里保存了每个epoch的loss和accuracy。我一般会画个图看看:
import matplotlib.pyplot as plt
plt.plot(history.history['loss'], label='train_loss')
plt.plot(history.history['val_loss'], label='val_loss')
plt.legend()
plt.show()
最后,用测试集做最终评估:
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f'测试集准确率: {test_acc:.4f}')
嗯,到这里,一个完整的Keras训练流程就走通了。从搭网络、选激活函数、定损失函数和优化器,再到训练和验证。你想想看,其实核心代码也就十几行。但每一行背后,都有很多经验和坑。
下一章,我们会把这些知识用到STM32的嵌入式场景里。到时候你会发现,模型训练只是第一步,怎么把它塞进单片机跑起来,才是真正的挑战。