合并孪生神经网络训练的多个.h5文件报错求解决方案
问题
我有多个由孪生(Siamese)神经网络训练得到的植物数据集.h5文件,希望将它们合并为一个文件用于模型评估。单个.h5文件的评估工作基本正常,但参考方法编写代码运行后出现报错,求不影响数据shape的合并方法。
原代码
import h5py import glob with h5py.File('table_merge.h5',mode='w') as h5fw: row1 = 0 for h5name in glob.glob('*.h5'): h5fr = h5py.File(h5name,'r') dset1 = list(h5fr.keys())[0] arr_data = h5fr[dset1][:] dslen = arr_data.shape[0] cols = arr_data.shape[1] if row1 == 0: h5fw.create_dataset('alldata', dtype="f", shape=(dslen,cols), maxshape=(None, cols) ) if row1+dslen <= len(h5fw['alldata']) : h5fw['alldata'][row1:row1+dslen,:] = arr_data[:] else : h5fw['alldata'].resize( (row1+dslen, cols) ) h5fw['alldata'][row1:row1+dslen,:] = arr_data[:] row1 += dslen
报错信息
Traceback (most recent call last): File "C:\Users\J.A.X\Desktop\model\model consept 2\h5 merge.py", line 9, in <module> arr_data = h5fr[dset1][:] File "h5py\_objects.pyx", line 54, in h5py._objects.with_phil.wrapper File "h5py\_objects.pyx", line 55, in h5py._objects.with_phil.wrapper File "C:\Users\J.A.X\AppData\Local\Programs\Python\Python36\lib\site-packages\h5py\_hl\group.py", line 288, in __getitem__ oid = h5o.open(self.id, self._e(name), lapl=self._lapl) File "C:\Users\J.A.X\AppData\Local\Programs\Python\Python36\lib\site-packages\h5py\_hl\base.py", line 200, in _e name = name.encode('ascii') AttributeError: 'slice' object has no attribute 'encode'
解决方案
问题原因
报错核心是:list(h5fr.keys())[0] 获取的可能不是数据集,而是组(Group)。对组对象使用切片[:]会触发错误——组的索引只接受字符串名称,不支持切片操作。
另外原代码还有两个潜在问题:
- 假设所有.h5文件的第一个键都是数据集,这个假设不成立,可能遇到组嵌套的情况
- 未关闭打开的源文件句柄,可能导致资源泄漏
修复后的代码
以下是确保正确合并、保留原数据shape的代码:
import h5py import glob def get_all_datasets(h5_group, path=""): """递归遍历HDF5文件,获取所有数据集的路径和对象""" datasets = [] for name, obj in h5_group.items(): current_path = f"{path}/{name}" if path else name if isinstance(obj, h5py.Dataset): datasets.append((current_path, obj)) elif isinstance(obj, h5py.Group): datasets.extend(get_all_datasets(obj, current_path)) return datasets with h5py.File('table_merge.h5', mode='w') as h5fw: total_rows = 0 all_datasets = [] # 先遍历所有文件,统计总数据量并收集数据 for h5name in glob.glob('*.h5'): with h5py.File(h5name, 'r') as h5fr: datasets = get_all_datasets(h5fr) # 取第一个数据集的列数作为基准(确保所有数据集结构一致) if not all_datasets: ref_dset = datasets[0][1] cols = ref_dset.shape[1] if len(ref_dset.shape) >=2 else 1 for _, dset in datasets: all_datasets.append((dset[:], dset.dtype)) total_rows += dset.shape[0] # 创建合并后的数据集 merged_dset = h5fw.create_dataset( 'alldata', dtype=all_datasets[0][1], shape=(total_rows, cols), maxshape=(None, cols) ) # 写入所有数据 current_row = 0 for data, _ in all_datasets: data_rows = data.shape[0] merged_dset[current_row:current_row+data_rows, :] = data current_row += data_rows
关键改进点
- 递归遍历HDF5文件,确保找到所有真实的数据集,避免把组当成数据集处理
- 使用
with语句管理源文件句柄,自动关闭文件,避免资源泄漏 - 先统计总数据量,一次性创建合适大小的数据集,减少resize操作(也可保留原逻辑动态resize)
- 自动匹配原数据集的数据类型,避免强制转换
dtype="f"导致的数据丢失
注意事项
- 确保所有待合并的.h5文件中的数据集shape一致(列数相同),否则合并会失败
- 如果孪生网络数据集有多个输入分支(比如两个输入张量),需要按数据集名称分组分别合并
内容的提问来源于stack exchange,提问作者unknown name
相关产品推荐
相关产品推荐

