深度学习训练添加validation_data引发无限循环,需解决以查看验证指标
解决model.fit验证阶段无限循环问题
核心原因
你使用的自定义data_generator缺少终止机制,Keras无法判断验证集数据是否已全部生成,因此会持续循环调用生成器。
解决方案
1. 给生成器添加终止逻辑
修改data_generator函数,当所有验证样本处理完毕后抛出StopIteration异常,让Keras知晓验证阶段结束:
def data_generator(data, mapping, features, tokenizer, max_length, vocab_size, batch_size): total_samples = len(data) processed_count = 0 while True: # 原有生成单batch数据的逻辑 # ... processed_count += batch_size # 当处理完所有样本时终止生成 if processed_count >= total_samples: raise StopIteration yield batch_x, batch_y
2. 在model.fit中指定validation_steps参数
如果不想修改生成器代码,可以直接在model.fit中明确验证步数,步数为验证集样本数除以batch_size的向上取整值:
# 计算验证步数 val_steps = len(validation) // batch_size # 若样本数不能被batch_size整除,加1确保覆盖所有样本 if len(validation) % batch_size != 0: val_steps += 1 history = model.fit(train_generator, epochs=40, steps_per_epoch=steps, callbacks = callback, validation_data = val_generator, validation_steps=val_steps, # 添加此参数 verbose=1 )
3. 改用Keras内置Sequence类实现生成器(推荐)
自定义生成器容易出现终止逻辑遗漏的问题,继承keras.utils.Sequence类可以自动处理终止逻辑,无需手动抛出异常:
from keras.utils import Sequence import numpy as np class DataGenerator(Sequence): def __init__(self, data, mapping, features, tokenizer, max_length, vocab_size, batch_size): self.data = data self.mapping = mapping self.features = features self.tokenizer = tokenizer self.max_length = max_length self.vocab_size = vocab_size self.batch_size = batch_size self.indexes = np.arange(len(self.data)) def __len__(self): # 返回总步数,Keras会自动用这个值判断何时终止 return int(np.ceil(len(self.data) / self.batch_size)) def __getitem__(self, index): # 生成单个batch的数据 batch_idx = self.indexes[index*self.batch_size : (index+1)*self.batch_size] batch_data = [self.data[i] for i in batch_idx] # 替换成你原有的batch处理逻辑 batch_x, batch_y = self._process_batch(batch_data) return batch_x, batch_y def _process_batch(self, batch_data): # 这里写原来生成器里处理单个batch的代码 # ... return batch_x, batch_y
使用方式:
val_generator = DataGenerator(validation, mapping, features, tokenizer, max_length, vocab_size, batch_size) train_generator = DataGenerator(train, mapping, features, tokenizer, max_length, vocab_size, batch_size) # 无需手动指定steps_per_epoch和validation_steps,Keras会自动通过__len__获取 history = model.fit(train_generator, epochs=40, callbacks = callback, validation_data = val_generator, verbose=1 )
验证标准
修改后重新运行训练,观察每个epoch结束时是否正常输出val_loss和val_accuracy,且不会卡在验证阶段无限循环。
内容的提问来源于stack exchange,提问作者cybercalv
相关产品推荐
相关产品推荐

