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

神经网络训练数据生成器报NoneType与float除法不支持的TypeError

报错原因与修复方案

直接触发报错的原因:cv2.imread() 读取文件失败时会返回None,无效的None值被添加到批次列表后,转换得到的numpy数组为object类型,无法直接与浮点数做除法运算,因此触发TypeError。

引发图片读取失败的常见原因及对应修复点:

  • 过滤非图片文件:os.listdir()会返回目录下所有子项,包括文件夹、非图片格式文件、隐藏文件,需要先筛选后缀为jpg、png等合法图片格式的文件再参与后续逻辑
  • 校验输入输出文件配对关系:i_list和o_list是分别调用os.listdir()得到的,两个列表的排序规则默认不一定完全一致,直接用相同下标m取值会出现配对错误,建议先对两个列表按文件名排序,或者校验输入输出文件名完全一致后再配对
  • 增加读取有效性校验:读取图片后先判断是否为None,过滤无效数据,示例逻辑如下:
    input_image = cv2.imread(path_to_in_img)
    output_image = cv2.imread(path_to_out_img)
    if input_image is None or output_image is None:
        print(f"读取失败,跳过文件:{path_to_in_img} | {path_to_out_img}")
        continue
    
  • 修复拼写错误:代码中outputput_val2image_array多输入了一个t,会导致后续返回时变量未定义
  • 调整归一化逻辑位置:当前归一化逻辑写在for循环内部,每添加一张图片就重复做一次归一化,属于冗余操作,可以移到for循环外部,整个批次组装完成后再统一处理
yield生成器内部数据查看方法

使用yield实现的生成器可以查看内部数据,常用两种方案:

  • 迭代取值:生成器是可迭代对象,可以用next()函数单次获取一个批次,或者用for循环遍历所有批次,拿到返回的批次数据后即可直接查看内容,比如打印数组形状、可视化图片等
  • 嵌入调试日志:在yield语句之前添加打印逻辑,输出当前的文件路径、批次大小、数组形状等中间信息,不需要修改生成器核心逻辑就能获取内部运行状态

修改后的yield版本生成器示例:

import os
import numpy as np
import cv2

def generator(idir, odir, batch_size, shuffle):
    # 先筛选并配对输入输出文件
    i_list = sorted([f for f in os.listdir(idir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))])
    o_list = sorted([f for f in os.listdir(odir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))])
    # 校验文件数量一致
    assert len(i_list) == len(o_list), "输入输出目录文件数量不匹配"
    sample_count = len(i_list)
    batch_index = 0
    
    while True: # 训练用生成器需要循环生成批次
        input_image_batch = []
        output_image_batch = []
        for i in range(batch_index * batch_size, (batch_index + 1) * batch_size):
            j = i % sample_count
            if shuffle:
                m = np.random.randint(low=0, high=sample_count)
            else:
                m = j
            path_to_in_img = os.path.join(idir, i_list[m])
            path_to_out_img = os.path.join(odir, o_list[m])
            # 校验文件名一致(可选)
            assert os.path.basename(path_to_in_img) == os.path.basename(path_to_out_img), "文件配对错误"
            
            input_image = cv2.imread(path_to_in_img)
            output_image = cv2.imread(path_to_out_img)
            if input_image is None or output_image is None:
                print(f"跳过无效文件:{path_to_in_img}")
                continue
            
            input_image = cv2.resize(input_image, (3200, 3200))
            output_image = cv2.resize(output_image, (3200, 3200))
            input_image_batch.append(input_image)
            output_image_batch.append(output_image)
        
        # 批次组装完成后统一处理
        input_val1image_array = np.array(input_image_batch) / 255.0
        output_val2image_array = np.array(output_image_batch) / 255.0
        batch_index += 1
        yield input_val1image_array, output_val2image_array

# 查看生成器数据示例
idir = r"D:\\validation"
odir = r"D:\\UAV\\validation"
train_gen = generator(idir, odir, 5, True)
# 取第一个批次查看
batch_x, batch_y = next(train_gen)
print(batch_x.shape, batch_y.shape)

内容的提问来源于stack exchange,提问作者user123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:27:02