You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

深度学习训练添加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:55:03