[Python] Tensorflow model training, List to numpy array conversion unevenly changes the shape...

Discussão em 'Python' iniciado por Stack, Fevereiro 20, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to predict LSDC from MRI images. For each study_id there are multiple images. Each study_id represents each patient. I want to predict 3 level of severity for 5 conditions on 5 levels.

    I am trying to create dataset using Custom data generator using Sequence class from tensorflow. Here is my Datagenerator class:

    class CustomDataGenerator(Sequence):
    def __init__(self, image_dict, num_img, labels_dict=None, batch_size=8, image_size=(224, 224), shuffle=True):
    self.image_dict = image_dict
    self.labels_dict = labels_dict
    self.batch_size = batch_size
    self.image_size = image_size
    self.shuffle = shuffle
    self.ids = list(image_dict.keys())
    self.num_img = num_img
    self.on_epoch_end()

    def __len__(self):
    return int(np.floor(len(self.ids) / self.batch_size))

    def __getitem__(self, index):
    start = index * self.batch_size
    end = min((index + 1) * self.batch_size, len(self.ids))
    batch_ids = self.ids[start:end]
    batch_images = []
    batch_labels = []

    for id_ in batch_ids:
    images = []

    for image_path in self.image_dict.get(id_, []):
    dicomdata = pydicom.dcmread(image_path)
    image = dicomdata.pixel_array
    image = cv2.resize(image, self.image_size)
    image = np.expand_dims(image, axis=-1)
    image = image.astype('float32') / np.max(image)
    image = np.repeat(image, 3, axis=-1)
    images.append(image)

    images = np.array(images)

    if len(images) < self.num_img:
    pad_amount = self.num_img - len(images)
    padding = [(0, pad_amount)] + [(0, 0)] * (len(images.shape) - 1)
    images = np.pad(images, padding, mode='constant')

    batch_images.append(images)

    if self.labels_dict:
    label = np.array(self.labels_dict.get(id_), dtype=np.float32)
    batch_labels.append(label)

    batch_images = np.stack(batch_images)
    if self.labels_dict:
    batch_labels = np.array(batch_labels, dtype=np.float32)
    return batch_images, batch_labels

    return batch_images

    def on_epoch_end(self):
    if self.shuffle:
    np.random.shuffle(self.ids)


    My labels dictionary is as follows:

    for i, sid in enumerate(train_df['study_id']):
    labels_dict[str(sid)] = []
    for con in conditions:
    if train_df.loc[i, con] == 'normal_mild':
    labels_dict[str(sid)].append([1, 0, 0])
    elif train_df.loc[i, con] == 'severe':
    labels_dict[str(sid)].append([0, 0, 1])
    else:
    labels_dict[str(sid)].append([0, 1, 0])

    labels_dict[str(sid)] = np.array(labels_dict[str(sid)], dtype=np.float32)


    I have tried various ways to convert labels_dict to numpy array. But either at the time of training it shows shape missmatch error. Or when trying to see the data it showed error.

    The error it showed is as follows:

    ----> 1 model.fit(train_generator, epochs=2) #, steps_per_epoch=len(train_generator)//8)

    /usr/local/lib/python3.10/dist-packages/keras/src/utils/traceback_utils.py in error_handler(*args, **kwargs)
    120 # To get the full stack trace, call:
    121 # `keras.config.disable_traceback_filtering()`
    --> 122 raise e.with_traceback(filtered_tb) from None
    123 finally:
    124 del filtered_tb

    <ipython-input-12-cf42609bddda> in __getitem__(self, index)
    47 batch_images = np.stack(batch_images)
    48 if self.labels_dict:
    ---> 49 batch_labels = np.array(batch_labels, dtype=np.float32)
    50 return batch_images, batch_labels
    51

    ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (8,) + inhomogeneous part.


    I tried using np.stack or batch_labels = batch_labels.reshape((batch_labels.shape[0], len(conditions), 3)), but it shows different error. My data does not have any nan and all labels_dict is of shape (batch_size, num_of_condition, severity_class). Even when I tried printing the data from generator. Generator data shape from data_x, data_y = next(iter(train_generator)) show desired shape of data for model input and output. I cannot figure out the problem.

    Continue reading...

Compartilhe esta Página