在SVHN数据集中访问hdf5组的两种方式有什么区别?

时间:2019-04-08 05:41:00

标签: python dataset hdf5 h5py

我需要读取SVHN数据集,并试图读取第一个图像的文件名。

我在努力理解HDF5的结构方面,特别是在理解SVHN数据集的层次结构方面感到困难

这两种读取图像名称的方法有什么区别?

在此脚本中,我在getName()函数的定义内遇到了方法1:https://github.com/bdiesel/tensorflow-svhn/blob/master/digit_struct.py

我尝试了hdf5格式文件,并想出了方法2,同时尝试了显示相同结果的不同事物。

# Both these methods read the first character of the name of the 1st
# image in svhn dataset
f = h5py.File(path_to_svhn_dataset,'r')

# method 1 
f[f['digitStruct']['name'][0][0]].value

# method 2
f[f['digitStruct']['name'].value[0].item()].value[0][0]

第一个图像是文件名“ 1.png”的文件。上面提到的两种获取文件名第一个字符的方式都将使我们在int上等于ascii'1'-> 49

1 个答案:

答案 0 :(得分:1)

首先,两种方法的输出存在细微的差异。
方法1:返回(编码文件名的)完整数组
方法2:仅返回数组的第一个元素(字符)

让我们解构您的代码以了解您拥有的内容。
第一部分处理h5py数据对象。

f['digitStruct']->返回h5py 对象
f['digitStruct']['name']->返回h5py 数据集对象
f['digitStruct']['name'].name->返回数据集对象的名称(路径)

注意:
/digitStruct/name数据集包含“对象引用”。每个数组条目都是一个指向另一个h5py对象(在本例中为另一个数据集)的指针。 例如(用于描绘2个对象引用的空格):
f[ f['digitStruct']['name'][0][0] ]->返回在[0] [0]引用的对象
因此,外部f[ obj_ref ]的工作方式与其他对象引用一样。

对于f['digitStruct']['name'][0][0],这是一个指向数据集/#refs#/b的对象 换句话说,f['digitStruct']['name'][0][0]引用与以下对象相同的对象: f['#refs#']['b']f['/#refs#/b']

h5py对象引用太多了。
让我们继续使用方法1 从该对象引用中获取数据。

f[f['digitStruct']['name'][0][0]].value->以NumPy数组的形式返回整个/#refs#/b数据集。

但是,不建议使用dataset.value,而首选使用NumPy索引,如下所示: f[f['digitStruct']['name'][0][0]][:](获取整个数组)

注意:这两个都返回整个编码字符数组。 此时,获得的名称是Python和NumPy功能。 使用此命令以字符串形式返回文件名:
f[f['digitStruct']['name'][0][0]][:].tostring().decode('ascii')

现在,让我们解构用于方法2 的对象引用。

f['digitStruct']['name'].value ->以NumPy数组的形式返回整个/digitStruct/name数据集。 它有13,068行带有对象引用

f['digitStruct']['name'].value[0]->是第一行

f['digitStruct']['name'].value[0].item()->将数组元素复制到python标量

所有这些都指向同一个对象:
方法1:f['digitStruct']['name'][0][0]
方法2:f['digitStruct']['name'].value[0].item()
在本示例中,它们都与f['#refs#']['b']f['/#refs#/b']相同。

像方法1一样,获取字符串是Python和NumPy功能。

f[f['digitStruct']['name'].value[0].item()][:].tostring().decode('ascii')

是的,对象引用很复杂。...
我的建议:
使用NumPy索引而不是.value从对象中提取NumPy数组(如上面的修改方法1所示)。

完整示例代码。中间的打印语句用来显示正在发生的事情。

import h5py

# Both of these methods read the name of the 1st
# image in svhn dataset
f = h5py.File('test_digitStruct.mat','r')
print (f['digitStruct'])
print (f['digitStruct']['name'])
print (f['digitStruct']['name'].name)

# method 1
print('\ntest method 1')
print (f[f['digitStruct']['name'][0][0]])
print (f[f['digitStruct']['name'][0][0]].name)
#  both of these get the entire array / filename:
print (f[f['digitStruct']['name'][0][0]].value)
print (f[f['digitStruct']['name'][0][0]][:]) # same as .value above
print (f[f['digitStruct']['name'][0][0]][:].tostring().decode('ascii'))

# method 2
print('\ntest method 2')
print (f[f['digitStruct']['name'].value[0].item()]) 
print (f[f['digitStruct']['name'].value[0].item()].name) 

# this only gets the first array member / character:
print (f[f['digitStruct']['name'].value[0].item()].value[0][0])
print (f[f['digitStruct']['name'].value[0].item()].value[0][0].tostring().decode('ascii'))
#  this gets the entire array / filename:
print (f[f['digitStruct']['name'].value[0].item()][:])
print (f[f['digitStruct']['name'].value[0].item()][:].tostring().decode('ascii'))

每种方法的最后2条打印语句的输出相同:

[[ 49]
 [ 46]
 [112]
 [110]
 [103]]
1.png