Esempio n. 1
0
    def evaluate(self, data_dir, txt_file):
        # The format of txt should match file in the dataset folder
        # TXT should contain the label to have the evaluate accuracy

        # ----- SETTINGS: DATASET BUILDERS
        datasetVal = MyDatasetGenerator(data_dir, txt_file,
                                        self.TransformSequenceVal)
        dataLoaderVal = DataLoader(dataset=datasetVal,
                                   batch_size=8,
                                   shuffle=False,
                                   num_workers=8,
                                   pin_memory=True)

        outGT = torch.LongTensor().to(device)
        outPRED = torch.LongTensor().to(device)

        # ----- SETTINGS: LOSS FUNCTION
        loss = torch.nn.CrossEntropyLoss()
        lossVal = 0
        lossValNorm = 0
        #losstensorMean = 0

        with torch.no_grad():
            for i, (input, target) in enumerate(dataLoaderVal):

                # target = target.cuda(async=True)
                target = target.flatten()
                target = target.to(device)

                varInput = input.to(device)

                varOutput = self.model(varInput)
                varOutput_softmax = torch.nn.functional.log_softmax(varOutput,
                                                                    dim=1)
                varOutput_class = torch.max(varOutput_softmax, dim=1).indices

                losstensor = loss(varOutput, target)

                lossVal += losstensor.item()
                lossValNorm += 1

                outGT = torch.cat((outGT, target), 0)
                outPRED = torch.cat((outPRED, varOutput_class), 0)

        # print(f'GT shape: {outGT.shape} - PRED shape: {outPRED.shape}')
        outLoss = lossVal / lossValNorm
        accuracy = torch.sum(outGT == outPRED).item() / outGT.size()[0]
        # losstensorMean = losstensorMean / lossValNorm

        return outLoss, accuracy
Esempio n. 2
0
    def evaluate(self, data_df):
        # ----- SETTINGS: DATASET BUILDERS
        datasetVal = MyDatasetGenerator(df=data_df)
        dataLoaderVal = DataLoader(dataset=datasetVal,
                                   batch_size=4,
                                   shuffle=False,
                                   num_workers=8,
                                   pin_memory=True)

        outGT = torch.LongTensor().to(device)
        outPRED = torch.LongTensor().to(device)

        # ----- SETTINGS: LOSS FUNCTION
        loss = torch.nn.CrossEntropyLoss()
        lossVal = 0
        lossValNorm = 0
        #losstensorMean = 0

        # self.model.eval()
        with torch.no_grad():
            for i, (img, tab, target) in enumerate(dataLoaderVal):
                # target = target.cuda(async=True)
                target = target.flatten()
                target = target.to(device)

                varImgInput = img.to(device)
                varTabInput = tab.to(device)
                varOutput = self.model(varImgInput, varTabInput)

                varOutput_softmax = torch.nn.functional.log_softmax(varOutput,
                                                                    dim=1)
                varOutput_class = torch.max(varOutput_softmax, dim=1).indices

                losstensor = loss(varOutput, target)

                lossVal += losstensor.item()
                lossValNorm += 1

                outGT = torch.cat((outGT, target), 0)
                outPRED = torch.cat((outPRED, varOutput_class), 0)

        # print(f'GT shape: {outGT.shape} - PRED shape: {outPRED.shape}')
        outLoss = lossVal / lossValNorm
        accuracy = torch.sum(outGT == outPRED).item() / outGT.size()[0]
        # losstensorMean = losstensorMean / lossValNorm

        return outLoss, accuracy
Esempio n. 3
0
    def train(self):
        # ----- SETTINGS: LOAD PRETRAINED MODEL
        self.load_trained_model()

        # ----- SETTINGS: DATASET BUILDERS
        datasetTrain = MyDatasetGenerator(pathImageDirectory=self.data_dir,
                                          pathDatasetFile=self.train_txt,
                                          transform=self.TransformSequence)
        datasetVal = MyDatasetGenerator(pathImageDirectory=self.data_dir,
                                        pathDatasetFile=self.val_txt,
                                        transform=self.TransformSequenceVal)

        dataLoaderTrain = DataLoader(dataset=datasetTrain,
                                     batch_size=self.batch_size,
                                     shuffle=True,
                                     num_workers=8,
                                     pin_memory=True)
        dataLoaderVal = DataLoader(dataset=datasetVal,
                                   batch_size=8,
                                   shuffle=False,
                                   num_workers=8,
                                   pin_memory=True)

        # ----- SETTINGS: OPTIMIZER & SCHEDULER
        if self.optimizer.lower() == 'adam':
            optimizer = optim.Adam(self.model.parameters(),
                                   lr=self.learning_rate,
                                   betas=(0.9, 0.999),
                                   eps=1e-08,
                                   weight_decay=1e-5)
        if self.optimizer.lower() == 'sgd':
            optimizer = optim.SGD(self.model.parameters(),
                                  lr=self.learning_rate,
                                  momentum=0.9,
                                  weight_decay=1e-5)
        scheduler = ReduceLROnPlateau(optimizer,
                                      factor=0.2,
                                      patience=4,
                                      mode='min',
                                      verbose=True,
                                      min_lr=1e-5)

        # ----- SETTINGS: LOSS FUNCTION
        loss = torch.nn.CrossEntropyLoss()

        # ----- SETTINGS: REPORT
        timestampTime = time.strftime("%H%M%S")
        timestampDate = time.strftime("%d%m%Y")
        self.timestampLaunch = timestampDate + '-' + timestampTime
        f_log = open(
            f"{self.save_dir}/{self.model_name}-{self.timestampLaunch}-REPORT.log",
            "w")
        writer = SummaryWriter(
            f'{self.save_dir}/{self.model_name}-{self.timestampLaunch}/')
        self.extract_info()

        # ---- TRAIN THE NETWORK
        lossMIN = 100000
        accMax = 0
        flag = 0
        count_change_loss = 0

        for epochID in range(0, self.max_epoch):

            if epochID > int(self.max_epoch / 2) and flag == 0:
                flag = 1
                optimizer = optim.SGD(self.model.parameters(),
                                      lr=0.001,
                                      momentum=0.9,
                                      weight_decay=1e-5)
                scheduler = ReduceLROnPlateau(optimizer,
                                              factor=0.5,
                                              patience=3,
                                              mode='min',
                                              verbose=True,
                                              min_lr=1e-5)

            print(f"Training {epochID}/{self.max_epoch-1}")

            timestampTime = time.strftime("%H%M%S")
            timestampDate = time.strftime("%d%m%Y")
            timestampSTART = timestampDate + '-' + timestampTime

            lossTrain = self.epochTrain(dataLoaderTrain, optimizer, loss)
            lossVal, acc = self.epochVal(dataLoaderVal, loss)

            timestampTime = time.strftime("%H%M%S")
            timestampDate = time.strftime("%d%m%Y")
            timestampEND = timestampDate + '-' + timestampTime

            scheduler.step(lossVal + 2 * (1 - acc))

            if lossVal < lossMIN or acc > accMax:
                count_change_loss = 0
                if lossVal < lossMIN:
                    lossMIN = lossVal
                if acc > accMax:
                    accMax = acc
                torch.save(
                    {
                        'epoch': epochID + 1,
                        'state_dict': self.model.state_dict(),
                        'best_loss': lossMIN,
                        'best_acc': accMax
                    },
                    f"{self.save_dir}/{self.model_name}-{self.timestampLaunch}.pth.tar"
                )
                print('Epoch [' + str(epochID + 1) + '] [save] [' +
                      timestampEND + '] lossVal= ' + str(lossVal) +
                      ' --- ACC: ' + str(acc))
                f_log.write(
                    f"[{timestampEND} - {epochID+1} - SAVE]\nLoss_Train: {lossTrain}\nLoss_Val: {lossVal}\nACC_Val: {acc}\n"
                )
            else:
                count_change_loss += 1
                print('Epoch [' + str(epochID + 1) + '] [----] [' +
                      timestampEND + '] lossVal= ' + str(lossVal) +
                      ' --- ACC: ' + str(acc))
                f_log.write(
                    f"[{timestampEND} - {epochID+1}]\nLoss_Train: {lossTrain}\nLoss_Val: {lossVal}\nACC_Val: {acc}\n"
                )

            writer.add_scalars('Loss', {'train': lossTrain}, epochID)
            writer.add_scalars('Loss', {'val': lossVal}, epochID)
            writer.add_scalars('Loss', {'val-best': lossMIN}, epochID)

            writer.add_scalars('Accuracy', {'val': acc}, epochID)
            current_lr = optimizer.param_groups[0]['lr']
            writer.add_scalar('Learning Rate', current_lr, epochID)

            if count_change_loss >= 25:
                print(
                    f'Early stopping: {count_change_loss} epoch not decrease the loss'
                )
                break

        f_log.close()
        writer.close()
Esempio n. 4
0
    def train(self):
        # ----- SETTINGS: LOAD PRETRAINED MODEL
        self.load_trained_model()

        # ----- SETTINGS: DATASET BUILDERS
        datasetTrain = MyDatasetGenerator(pathImageDirectory=self.data_dir,
                                          pathDatasetFile=self.train_txt,
                                          transform=self.TransformSequence)
        datasetVal = MyDatasetGenerator(pathImageDirectory=self.data_dir,
                                        pathDatasetFile=self.val_txt,
                                        transform=self.TransformSequenceVal)

        # ----- SETTINGS: REPORT
        timestampTime = time.strftime("%H%M%S")
        timestampDate = time.strftime("%d%m%Y")
        self.timestampLaunch = timestampDate + '-' + timestampTime
        self.extract_info()
        writer = SummaryWriter(
            f'{self.save_dir}/{self.model_name}-{self.timestampLaunch}/')

        # ----- SETTINGS: CALLBACKS
        lrscheduler = LRScheduler(policy=ReduceLROnPlateau,
                                  factor=0.2,
                                  patience=4,
                                  mode='min',
                                  verbose=True,
                                  min_lr=1e-5,
                                  monitor='valid_loss')
        # auc = EpochScoring(scoring='roc_auc', lower_is_better=False)
        checkpoint = Checkpoint(
            f_params=
            f"{self.save_dir}/{self.model_name}-{self.timestampLaunch}.pth.tar",
            monitor='valid_acc_best',
            f_history=
            f"{self.save_dir}/{self.model_name}-{self.timestampLaunch}-REPORT.json"
        )
        earlystopping = EarlyStopping(monitor='valid_loss', patience=15)
        tensorboard = TensorBoard(writer)

        # ----- SETTINGS: DECLARE SKORCH
        if self.optimizer.lower() == 'adam':
            net = NeuralNetClassifier(
                self.model,
                criterion=torch.nn.CrossEntropyLoss,
                lr=self.learning_rate,
                batch_size=self.batch_size,
                max_epochs=self.max_epoch,
                optimizer=optim.Adam,
                #optimizer__params=self.model.parameters(),
                optimizer__betas=(0.9, 0.999),
                optimizer__eps=1e-8,
                optimizer__weight_decay=1e-5,
                iterator_train__shuffle=True,
                iterator_train__num_workers=8,
                iterator_valid__shuffle=True,
                iterator_valid__num_workers=8,
                train_split=predefined_split(datasetVal),
                callbacks=[
                    lrscheduler, checkpoint, earlystopping, tensorboard
                ],
                device='cuda'  # comment to train on cpu
            )
        if self.optimizer.lower() == 'sgd':
            net = NeuralNetClassifier(
                self.model,
                criterion=torch.nn.CrossEntropyLoss,
                lr=self.learning_rate,
                batch_size=self.batch_size,
                max_epochs=self.max_epoch,
                optimizer=optim.SGD,
                #optimizer__params=self.model.parameters(),
                optimizer__momentum=0.9,
                optimizer__weight_decay=1e-5,
                iterator_train__shuffle=True,
                iterator_train__num_workers=8,
                iterator_valid__shuffle=True,
                iterator_valid__num_workers=8,
                train_split=predefined_split(datasetVal),
                callbacks=[
                    lrscheduler, checkpoint, earlystopping, tensorboard
                ],
                device='cuda'  # comment to train on cpu
            )

        # y = np.array([y for _, y in iter(datasetTrain)])
        net.fit(datasetTrain, y=None)