for循环遍历不同batch size训练模型时验证损失异常如何解决
错误根因
- 你的模型初始化、定义逻辑写在了for循环遍历batch size的外部,第一次用batch size=32训练完成后,模型权重、Adam优化器的一阶/二阶矩状态都被保留,第二次及之后的训练都是基于前一次训练完的状态继续迭代,并非从零开始,极易出现梯度爆炸,最终导致验证损失数值溢出到异常高的量级。
- 该实现没有控制变量,不同batch size的训练起点不一致,得到的训练效果数据不具备可比性,无法准确反应batch size的真实影响。
正确实现方案
把模型初始化逻辑移到for循环内部即可,若要实验结果更严谨,可以增加随机种子固定初始化权重,保证每个batch size的训练起点完全一致。
import numpy as np import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense print ('train_X', train_X.shape) print ('test_X', test_X.shape) print ('train_Y', train_Y.shape) print ('test_Y', test_Y.shape) batch_sizes = [32,64,128,256,512] # 可选:存储每个batch size对应的训练结果方便后续对比 train_history = {} for batch_size in batch_sizes: # 固定随机种子,保证每个batch size对应的模型初始化权重完全一致 np.random.seed(42) tf.random.set_seed(42) # 每个batch size训练前都重新初始化新的模型 model = Sequential() model.add(Dense(64, input_dim=size, activation='relu')) model.add(Dense(7)) model.compile(optimizer="adam", loss="mean_squared_error") history = model.fit(train_X, train_Y, epochs=3, validation_data=(test_X, test_Y), batch_size=batch_size, verbose=2) # 存储训练历史 train_history[batch_size] = history.history
如果需要进一步避免梯度爆炸的潜在问题,可以给Dense层加kernel正则项,或者对输入数据做标准化处理,提升训练稳定性。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

