Обучение сети Unet для brainsegmentation

#machine-learning #deep-learning #conv-neural-network #medical-imaging

#машинное обучение #глубокое обучение #conv-нейронная сеть #медицинская визуализация

Вопрос:

У меня есть два вопроса:

Q1: Мне было интересно, каков наилучший способ подачи данных обучения в сеть unet:

  1. Отправка по одному пациенту за раз, где каждый объем составляет 160x3x192x192
  2. Отправка случайных фрагментов от k пациентов

Q2: На данный момент я выполнил первый вариант, но не получил никаких хороших результатов. Я получаю колеблющуюся оценку кубиков. Например, проигрыш в кости начинается с 0,99, снижается до 0,8, а его всплески достигают 8, и шаблон повторяется. У кого-нибудь есть ответ на вопрос, почему это происходит?

код:

 class main:
def __init__(self, args):
    self.args = args
    self.train_loader = None
    self.in_channel = None
    self.out_channel = None



def _config_dataloader(self):
    print("Starting configuration of the dataset")
    print("Collecting validation and training set")


    validation_mode = "val/"
    training_mode = "train/"

    collect = Get_mean_std(self.args.path   training_mode)
    mean,std = collect(self.args.k)
     
    mean_flair = mean["FLAIR"]
    mean_t1 = mean["T1"]

    std_flair = std["FLAIR"]
    std_t1 = std["T1"]


    train_dataset = MSdataset(self.args.path   training_mode, composed_transforms = [
                        normalize(z_norm = True, mean = mean_flair, std = std_flair),
                        normalize(z_norm = True, mean = mean_t1, std = std_t1),
                        add_channel(depth = self.args.depth), 
                        ToTensor()]
                        )
    
    validation_dataset = MSdataset(self.args.path   validation_mode, composed_transforms = [
                        normalize(z_norm = True, mean = mean_flair, std = std_flair),
                        normalize(z_norm = True, mean = mean_t1, std = std_t1),
                        add_channel(depth = self.args.depth), 
                        ToTensor()]
                        )
    

    
    train_loader = DataLoader(train_dataset, 
                              self.args.batch_size, 
                              self.args.shuffle)
    
    validation_loader = DataLoader(validation_dataset, 
                              self.args.batch_size-1, 
                              self.args.shuffle)
    
    print("Data collected. Returning dataloaders for training and validation set")
    return train_loader, validation_loader

def __call__(self, is_train = False):
    train_loader, validation_loader = self._config_dataloader()
    
    complete_data = {"train": train_loader, "validation":validation_loader }

    device = torch.device("cpu" if not torch.cuda.is_available() else self.args.device)

    unet = UNet(in_channels=3, out_channels=1, init_features=32)
    unet.to(device)
    
    optimizer = optim.Adam(unet.parameters(), lr=self.args.lr)
    dsc_loss = DiceLoss()

    loss_train = []
    loss_valid = []

    print("Starting training process. Please wait..")
    sub_batch_size = 14 
    for current_epoch in tqdm(range(self.args.epoch),total= self.args.epoch):

        for phase in ["train", "validation"]:

            if phase == "train":
                unet.train()
            
            if phase == "validation":
                unet.eval()

            for i, data_set_batch in enumerate(complete_data[phase]):
                data_dict = data_set_batch
                X, mask = data_dict["volume"], data_dict["mask"]
                X, mask = (X.to(device)).float(), mask.to(device)
                B,D,C,H,W = X.shape #
             
                mask =mask.reshape((B*D,H,W)) 
                X = X.reshape((B*D,C,H,W)) 
  
                loss_depths = 0 # Nulle ut depth loss
                with torch.set_grad_enabled(is_train):

                    for sub_batches in tqdm(range(0,X.shape[0]-sub_batch_size)): 
                
                  
                        predicted = unet(X[sub_batches: sub_batches   sub_batch_size,:,:,:])
                        loss = dsc_loss(predicted.squeeze(1), mask[sub_batches: sub_batches   sub_batch_size,:,:])
                      
                        if phase == "train":
                       
                            loss_depths = loss_depths   loss
                        if phase == "validation":
                            continue
                if phase == "train":
              
                    loss_train.append(loss_depths)
                    loss_depths.backward()
                    optimizer.step()
                    optimizer.zero_grad()
                 

    print("Training and validation is done. Exiting program and returning loss")  
    return loss_train
 

Обратите внимание, что я не полностью реализовал раздел для проверки, я просто хотел сначала посмотреть, как сеть обучается.
Спасибо!

Комментарии:

1. Ваш счет в кубиках вырос до 8? Оно никогда не должно превышать 1. На данный момент этот вопрос не по теме, поскольку он не содержит кода. Если вы добавите свой код, пользователи здесь смогут лучше помочь вам.

2. Да, это странная вещь. Я помещу код в сообщение (не делал этого, потому что я пишу об этом диссертацию)