Ошибка широковещания HDF5: Не удается передать (3, 2048, 1, 1) -> (4, 2048, 1, 1) - PullRequest
0 голосов
/ 03 мая 2020

Я получил следующую ошибку:

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))

In (Нет, args.batch_size, 2048, 1, 1), значение None не указано из-за неизвестной природы размера набора данных. В этом случае args.batch_size равно 4, 2048, 1 и 1 - количество извлеченных объектов и их пространственные размеры.

форма определяется как:

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

Однако я не уверен, что я могу сделать с args.batch_size, который в данном случае равен 4. Я не могу оставить это None, поскольку возникает недопустимая ошибка:

ValueError: Недопустимое значение в кортеже фрагмента

РЕДАКТИРОВАТЬ: Да, вы абсолютно правы. Я пытаюсь постепенно записывать в набор данных hdf5. Я показал больше кода ниже. Я извлекаю функции и сохраняю их постепенно в наборе данных hdf5. Несмотря на размер пакета 4, было бы идеально сохранить каждый элемент из пакета, постепенно, как его собственный экземпляр / строку.

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()

1 Ответ

0 голосов
/ 04 мая 2020

Я думаю, вы не уверены в использовании параметра 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
...