广播错误HDF5:不能广播(3,2048,1,1)->(4,2048,1,1)。

问题描述 投票:-1回答:1

我收到了以下错误。

TypeError: 不能广播 (3, 2048, 1, 1) -> (4, 2048, 1, 1)

我正在提取特征,并将它们放到一个hdf5数据集中,是这样的。

array_40 = hdf5_file.create_dataset(
                    f'{phase}_40x_arrays',  shape, maxshape=(None, args.batch_size, 2048, 1, 1))

在(None, args.batch_size, 2048, 1, 1)中,由于数据集大小未知,所以指定了None. args.batch_size在本例中是4,2048, 1和1是提取的特征数量和空间尺寸.

shape定义为。

shape = (dataset_length, args.batch_size, 2048, 1, 1)

然而,我不知道我可以用args.batch_size做什么,在这种情况下,它是4。 我不能让它为None,因为它会出现一个非法的错误。

ValueError: Illegal value in chunk tuple(块元组中的非法值)

EDIT: 是的,你是绝对正确的。我试图增量写入一个hdf5数据集。我在下面展示了更多的代码。我正在提取特征,并将它们增量地存储到一个hdf5数据集中。尽管批次大小为4,但理想的情况是将批次中的每个项目,以增量的方式保存为自己的instancerow。

shape = (dataset_length, 2048, 1, 1)
            all_shape = (dataset_length, 6144, 1, 1)
            labels_shape = (dataset_length)
            batch_shape = (1,)

            path = args.HDF5_dataset + f'{phase}.hdf5'

            #hdf5_file = h5py.File(path, mode='w')
            with h5py.File(path, mode='a') as hdf5_file:

                array_40 = hdf5_file.create_dataset(
                    f'{phase}_40x_arrays',  shape, maxshape=(None, 2048, 1, 1)
                )
                array_labels = hdf5_file.create_dataset(
                    f'{phase}_labels', labels_shape, maxshape=(None), dtype=string_type
                )
                array_batch_idx = hdf5_file.create_dataset(
                    f'{phase}_batch_idx', data=np.array([-1, ])
                )

                hdf5_file.close()

        # either new or checkpionted file exists
        # load file and create references to exisitng h5 datasets
        with h5py.File(path, mode='r+') as hdf5_file:
            array_40 = hdf5_file[f'{phase}_40x_arrays']
            array_labels = hdf5_file[f'{phase}_labels']
            array_batch_idx = hdf5_file[f'{phase}_batch_idx']

            batch_idx = int(array_batch_idx[0]+1)

            print("Batch ID is restarting from {}".format(batch_idx))

            dataloaders_dict = torch.utils.data.DataLoader(datasets_dict, batch_size=args.batch_size, sampler=SequentialSampler2(
                datasets_dict, batch_idx, args.batch_size),drop_last=True, num_workers=args.num_workers, shuffle=False)  # make sure shuffling is false for sampler to work and incase you restart


            for i, (inputs40x, paths40x, labels) in enumerate(dataloaders_dict):

                print(f'Batch ID: {batch_idx}')

                inputs40x = inputs40x.to(device)
                labels = labels.to(device)
                paths = paths40x

                x40 = resnet(inputs40x)

                # torch.Size([1, 2048, 1, 1]) batch, feats, 1l, 1l
                array_40[...] = x40.cpu()
                array_labels[batch_idx, ...] = labels[:].cpu()
                array_batch_idx[:,...] = batch_idx

                batch_idx +=1
                hdf5_file.flush()

python pytorch hdf5 h5py
1个回答
0
投票

我想你在使用 maxshape=() 参数,它设置了每个维度的最大数据集大小。它设置了每个维度的最大分配数据集大小。第一个数据集维度被设置为 dataset_length 创立之初,与 maxshape[0]=None 它允许无限制地增长大小。创建时第二个数据集维度的大小为 args.batch_size. 您指定了相同大小的 maxshape所以你不能增加这个维度。

我对你的例子有点困惑。听起来你是在尝试以行的形式向数据集增量写入数据,这些行的实例是 args.batch_size. 你的例子中有51行数据,你想分批写下这些数据。args.batch_size=4. 51行,你可以写出前48行(0-3,4-7...44-47),然后卡住剩下的3行。你能不能通过增加一个计数器来解决这个问题(把它叫做 nrows_left),并将批次大小参数改为 min(args.batch_size, rows_left)? 在我看来是最简单的解决方案。

没有更多的信息,我无法写出一个完整的例子。下面我将尝试展示我的意思。

# args.batch_size = 4
shape = (dataset_length, 2048, 1, 1)
array_40 = hdf5_file.create_dataset(
           f'{phase}_40x_arrays', shape, maxshape=(None, 2048, 1, 1))
nrows_left= dataset_length
rcnt = 0
loopcnt = dataset_length/args.batch_size
if dataset_length%args.batch_size != 0:
    loopcnt += 1 
for loop in range(loopcnt) :
    nload = min(nrows_left, args.batch_size)
    array_40[rcnt :row+nload] = img_data[rcnt:row+nload ]
    rcnt += nload 
    nrows_left -= nload
© www.soinside.com 2019 - 2024. All rights reserved.