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

运行Keras图像识别教程代码遇双重报错及H5文件写入异常

解决Keras图像识别代码的KeyError和ValueError问题

看起来你遇到的问题主要出在路径解析和标签处理上,咱们一步步拆解解决:

问题根源分析

  1. KeyError: 'imgs':这其实是第一次运行代码时的正常现象——因为X.h5文件还没生成,里面自然没有imgs数据集,所以代码会进入异常处理流程去处理原始图片,这个本身不是bug,但后面的ValueError才是阻碍数据生成的关键。
  2. ValueError: 无法将'Final_Training'转为整数:你的get_class函数用img_path.split('/')[-2]取分类文件夹名,但由于路径分隔符适配问题(比如Windows下是\而不是/),或者路径结构解析错误,导致你取到的不是分类文件夹的数字名称,而是Final_Training这个字符串,转int自然失败。
  3. 移除int转换后X.h5仍无法正确写入:因为标签变成了字符串,而np.eye(NUM_CLASSES)[labels]要求索引必须是整数,这会导致one-hot编码失败,最终无法生成有效的Y数组,写入h5自然出问题。

修复方案

1. 修复分类标签获取函数

用Python标准库的os.path工具来解析路径,它会自动适配Windows/macOS/Linux的路径分隔符,确保正确获取分类文件夹名:

def get_class(img_path):
    # 先获取图片的父文件夹路径
    parent_dir = os.path.dirname(img_path)
    # 再提取父文件夹的名称(也就是分类标签的字符串形式)
    class_str = os.path.basename(parent_dir)
    try:
        return int(class_str)
    except ValueError:
        print(f"警告:路径{img_path}中的分类名称{class_str}不是整数,跳过该图片")
        return None  # 返回None方便后续过滤

2. 完善数据处理流程,添加校验

在循环处理图片时,增加对图片形状、标签有效性的校验,避免生成无效数据:

import os
import glob
import numpy as np
import h5py
from skimage import io

# 请根据你的数据集实际分类数量修改这个值
NUM_CLASSES = 43

def preprocess_img(img):
    # 示例预处理:调整为32x32尺寸,归一化到0-1范围
    from skimage.transform import resize
    img = resize(img, (32, 32))
    return img

def get_class(img_path):
    parent_dir = os.path.dirname(img_path)
    class_str = os.path.basename(parent_dir)
    try:
        return int(class_str)
    except ValueError:
        print(f"无效分类名:{class_str},路径:{img_path}")
        return None

try:
    with h5py.File('X.h5', 'r') as hf:
        X, Y = hf['imgs'][:], hf['labels'][:]
    print("✅ 成功从X.h5加载数据")
except (IOError, OSError, KeyError) as e:
    print(f"⚠️ 加载X.h5失败:{e},开始处理原始图片...")
    root_dir = 'Data/Final_Training/Images/'
    imgs = []
    labels = []
    # 用os.path.join拼接路径,避免分隔符问题
    all_img_paths = glob.glob(os.path.join(root_dir, '*', '*.ppm'))
    print(f"🔍 找到{len(all_img_paths)}张图片")
    np.random.shuffle(all_img_paths)

    for idx, img_path in enumerate(all_img_paths):
        # 每处理1000张打印进度
        if idx % 1000 == 0:
            print(f"⏳ 已处理{idx}/{len(all_img_paths)}张图片")
        try:
            img = io.imread(img_path)
            img = preprocess_img(img)
            # 确保所有图片预处理后形状一致(比如32x32x3)
            if img.shape != (32, 32, 3):
                print(f"❌ 图片{img_path}形状异常:{img.shape},跳过")
                continue
            label = get_class(img_path)
            # 过滤无效标签
            if label is None or label < 0 or label >= NUM_CLASSES:
                print(f"❌ 标签无效:{label},路径:{img_path},跳过")
                continue
            imgs.append(img)
            labels.append(label)
        except (IOError, OSError) as e:
            print(f"❌ 处理图片失败:{img_path},错误:{e}")
            pass

    print(f"🎉 处理完成,共收集{len(imgs)}张有效图片")
    # 转换为numpy数组
    X = np.array(imgs, dtype='float32')
    # 生成one-hot编码标签
    Y = np.eye(NUM_CLASSES, dtype='uint8')[labels]
    print(f"📊 数据形状:X={X.shape}, Y={Y.shape}")

    # 写入h5文件
    with h5py.File('X.h5', 'w') as hf:
        hf.create_dataset('imgs', data=X)
        hf.create_dataset('labels', data=Y)
    print("✅ 数据已成功写入X.h5")

3. 额外检查点

  • 确认你的数据集路径结构:Data/Final_Training/Images/下的子文件夹必须是整数命名的分类文件夹(比如0、1、2...),每个文件夹下存放对应类别的ppm图片。
  • 确认NUM_CLASSES的值和实际分类数量一致,否则one-hot编码会失败。
  • 检查preprocess_img函数:确保它能将所有图片处理成相同的形状(比如统一的宽高和通道数),否则np.array(imgs)会生成不规则数组,无法写入h5文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:10:58