From 4a179c0c6fa3b40658e8f972ef5cdd6a503dfefa Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 11:16:58 +0800 Subject: [PATCH 01/11] Make Standard Scaler fit on segments only --- tests/model_tests/chestnut_dec_may/train.py | 34 +++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/tests/model_tests/chestnut_dec_may/train.py b/tests/model_tests/chestnut_dec_may/train.py index 6d347e09..7475821a 100644 --- a/tests/model_tests/chestnut_dec_may/train.py +++ b/tests/model_tests/chestnut_dec_may/train.py @@ -35,6 +35,23 @@ # os.environ["WANDB_MODE"] = "offline" +def get_y_encoder(targets): + oe = OrdinalEncoder( + handle_unknown="use_encoded_value", + unknown_value=np.nan, + ) + oe.fit(np.array(targets).reshape(-1, 1)) + return oe + + +def get_x_scaler(segments): + ss = StandardScaler() + ss.fit( + np.concatenate([segm.reshape(-1, segm.shape[-1]) for segm in segments]) + ) + return ss + + def main( batch_size=32, epochs=10, @@ -47,17 +64,7 @@ def main( train_unl_ds = ds.chestnut_20201218.unlabelled( transform=train_unl_preprocess(2) ) - val_ds = ds.chestnut_20210510_43m(transform=preprocess) - - oe = OrdinalEncoder( - handle_unknown="use_encoded_value", - unknown_value=np.nan, - ) - oe.fit(np.array(train_lab_ds.targets).reshape(-1, 1)) - n_classes = len(oe.categories_[0]) - - ss = StandardScaler() - ss.fit(train_lab_ds.ar.reshape(-1, train_lab_ds.ar.shape[-1])) + val_ds = ds.chestnut_20210510_43m(transform=val_preprocess) # Prepare the datamodule and trainer dm = FRDCDataModule( @@ -90,9 +97,12 @@ def main( ), ) + oe = get_y_encoder(train_lab_ds.targets) + ss = get_x_scaler(train_lab_ds.ar_segments) + m = InceptionV3MixMatchModule( in_channels=train_lab_ds.ar.shape[-1], - n_classes=n_classes, + n_classes=len(oe.categories_[0]), lr=lr, x_scaler=ss, y_encoder=oe, From 2765a596eb70249725ccceeaeaa146697252910c Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 11:47:31 +0800 Subject: [PATCH 02/11] Expose ImageNet Scaling option --- src/frdc/models/inceptionv3.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/frdc/models/inceptionv3.py b/src/frdc/models/inceptionv3.py index 4ee47ed6..3d3b3e49 100644 --- a/src/frdc/models/inceptionv3.py +++ b/src/frdc/models/inceptionv3.py @@ -25,11 +25,18 @@ def __init__( x_scaler: StandardScaler, y_encoder: OrdinalEncoder, ema_lr: float = 0.001, + imagenet_scaling: bool = False, ): """Initialize the InceptionV3 model. Args: - n_classes: The number of output classes + in_channels: The number of input channels. + n_classes: The number of classes. + lr: The learning rate. + x_scaler: The X input StandardScaler. + y_encoder: The Y input OrdinalEncoder. + ema_lr: The learning rate for the EMA model. + imagenet_scaling: Whether to use the adapted ImageNet scaling. Notes: - Min input size: 299 x 299. @@ -129,7 +136,7 @@ def adapt_inception_multi_channel( return inception @staticmethod - def transform_input(x: torch.Tensor) -> torch.Tensor: + def imagenet_scaling(x: torch.Tensor) -> torch.Tensor: """Perform adapted ImageNet normalization on the input tensor. See Also: @@ -181,7 +188,9 @@ def forward(self, x: torch.Tensor): f"Got: {x.shape[2]} x {x.shape[3]}." ) - x = self.transform_input(x) + if self.imagenet_scaling: + x = self.imagenet_scaling(x) + # During training, the auxiliary outputs are used for auxiliary loss, # but during testing, only the main output is used. if self.training: From b5783da3ba9796f40c79056a5ae6a37d092b49b6 Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:00:57 +0800 Subject: [PATCH 03/11] Format variable names --- tests/model_tests/chestnut_dec_may/train.py | 35 ++++++---- tests/model_tests/utils.py | 77 ++++++++++----------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/tests/model_tests/chestnut_dec_may/train.py b/tests/model_tests/chestnut_dec_may/train.py index 7475821a..4ffbd786 100644 --- a/tests/model_tests/chestnut_dec_may/train.py +++ b/tests/model_tests/chestnut_dec_may/train.py @@ -3,11 +3,11 @@ This test is done by training a model on the 20201218 dataset, then testing on the 20210510 dataset. """ -import os from pathlib import Path import lightning as pl import numpy as np +import torch import wandb from lightning.pytorch.callbacks import ( LearningRateMonitor, @@ -22,16 +22,16 @@ from frdc.train.frdc_datamodule import FRDCDataModule from frdc.utils.training import predict, plot_confusion_matrix from model_tests.utils import ( - train_preprocess, + train_preprocess_augment, train_unl_preprocess, - preprocess, + val_preprocess, FRDCDatasetFlipped, ) # Uncomment this to run the W&B monitoring locally # import os -# from frdc.utils.training import predict, plot_confusion_matrix +# # os.environ["WANDB_MODE"] = "offline" @@ -58,9 +58,11 @@ def main( train_iters=25, val_iters=15, lr=1e-3, + wandb_name="chestnut_dec_may", + wandb_project="frdc", ): # Prepare the dataset - train_lab_ds = ds.chestnut_20201218(transform=train_preprocess) + train_lab_ds = ds.chestnut_20201218(transform=train_preprocess_augment) train_unl_ds = ds.chestnut_20201218.unlabelled( transform=train_unl_preprocess(2) ) @@ -73,7 +75,6 @@ def main( val_ds=val_ds, batch_size=batch_size, train_iters=train_iters, - val_iters=val_iters, sampling_strategy="random", ) @@ -84,16 +85,19 @@ def main( log_every_n_steps=4, callbacks=[ # Stop training if the validation loss doesn't improve for 4 epochs - EarlyStopping(monitor="val_loss", patience=4, mode="min"), + EarlyStopping(monitor="val/ce_loss", patience=4, mode="min"), # Log the learning rate on TensorBoard LearningRateMonitor(logging_interval="epoch"), # Save the best model ckpt := ModelCheckpoint( - monitor="val_loss", mode="min", save_top_k=1 + monitor="val/ce_loss", mode="min", save_top_k=1 ), ], logger=( - logger := WandbLogger(name="chestnut_dec_may", project="frdc") + logger := WandbLogger( + name=wandb_name, + project=wandb_project, + ) ), ) @@ -106,8 +110,8 @@ def main( lr=lr, x_scaler=ss, y_encoder=oe, + imagenet_scaling=True, ) - logger.watch(m) trainer.fit(m, datamodule=dm) @@ -122,7 +126,7 @@ def main( "chestnut_nature_park", "20210510", "90deg43m85pct255deg", - transform=preprocess, + transform=val_preprocess, ), model_cls=InceptionV3MixMatchModule, ckpt_pth=Path(ckpt.best_model_path), @@ -131,8 +135,8 @@ def main( acc = np.sum(y_true == y_pred) / len(y_true) ax.set_title(f"Accuracy: {acc:.2%}") - wandb.log({"confusion_matrix": wandb.Image(fig)}) - wandb.log({"eval_accuracy": acc}) + wandb.log({"eval/confusion_matrix": wandb.Image(fig)}) + wandb.log({"eval/eval_accuracy": acc}) wandb.finish() @@ -144,12 +148,13 @@ def main( VAL_ITERS = 15 LR = 1e-3 - wandb.login(key=os.environ["WANDB_API_KEY"]) - + torch.set_float32_matmul_precision("high") main( batch_size=BATCH_SIZE, epochs=EPOCHS, train_iters=TRAIN_ITERS, val_iters=VAL_ITERS, lr=LR, + wandb_name="Try with Inception Unfrozen & Random Erasing", + wandb_project="frdc-dev", ) diff --git a/tests/model_tests/utils.py b/tests/model_tests/utils.py index b3a0d6a8..aa067f3c 100644 --- a/tests/model_tests/utils.py +++ b/tests/model_tests/utils.py @@ -14,6 +14,7 @@ RandomRotation, RandomApply, Resize, + RandomErasing, ) from torchvision.transforms.v2 import RandomHorizontalFlip @@ -48,51 +49,49 @@ def __getitem__(self, idx): return RandomHorizontalFlip(p=1)(RandomVerticalFlip(p=1)(x)), y -def preprocess(x): - return torch.nan_to_num( - Compose( - [ - ToImage(), - ToDtype(torch.float32, scale=True), - CenterCrop( - [ - InceptionV3MixMatchModule.MIN_SIZE, - InceptionV3MixMatchModule.MIN_SIZE, - ], - ), - ] - )(x) - ) - - -def train_preprocess(x): - return torch.nan_to_num( - Compose( - [ - ToImage(), - ToDtype(torch.float32, scale=True), - RandomCrop( - [ - InceptionV3MixMatchModule.MIN_SIZE, - InceptionV3MixMatchModule.MIN_SIZE, - ], - pad_if_needed=True, - padding_mode="constant", - fill=0, - ), - RandomHorizontalFlip(), - RandomVerticalFlip(), - RandomApply([RandomRotation((90, 90))], p=0.5), - ] - )(x) - ) +def val_preprocess(x): + return Compose( + [ + ToImage(), + ToDtype(torch.float32, scale=True), + Resize( + InceptionV3MixMatchModule.MIN_SIZE, + antialias=True, + ), + CenterCrop( + InceptionV3MixMatchModule.MIN_SIZE, + ), + ] + )(x) + + +def train_preprocess_augment(x): + return Compose( + [ + ToImage(), + ToDtype(torch.float32, scale=True), + Resize( + InceptionV3MixMatchModule.MIN_SIZE, + antialias=True, + ), + RandomCrop( + InceptionV3MixMatchModule.MIN_SIZE, + pad_if_needed=False, + ), + RandomHorizontalFlip(), + RandomVerticalFlip(), + RandomApply([RandomRotation((90, 90))], p=0.5), + ] + )(x) def train_unl_preprocess(n_aug: int = 2): def f(x): # This simulates the n_aug of MixMatch return ( - [train_preprocess(x) for _ in range(n_aug)] if n_aug > 0 else None + [train_preprocess_augment(x) for _ in range(n_aug)] + if n_aug > 0 + else None ) return f From 594f2a947d490eb82afa3cfe08e5eb9682cb09a8 Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:01:08 +0800 Subject: [PATCH 04/11] Deprecate verbose wandb helper class --- src/frdc/train/mixmatch_module.py | 126 +++++++++++------------------- 1 file changed, 45 insertions(+), 81 deletions(-) diff --git a/src/frdc/train/mixmatch_module.py b/src/frdc/train/mixmatch_module.py index eafa132a..79e81c6b 100644 --- a/src/frdc/train/mixmatch_module.py +++ b/src/frdc/train/mixmatch_module.py @@ -51,7 +51,6 @@ def __init__( self.sharpen_temp = sharpen_temp self.mix_beta_alpha = mix_beta_alpha self.save_hyperparameters() - self.lbl_logger = WandBLabelLogger() @property @abstractmethod @@ -151,14 +150,13 @@ def progress(self): def training_step(self, batch, batch_idx): (x_lbl, y_lbl), x_unls = batch - self.lbl_logger( - self.logger.experiment, - "Input Y Label", - y_lbl, - flush_every=10, - num_bins=self.n_classes, - ) + self.log("train/x_lbl_mean", x_lbl.mean()) + self.log("train/x_lbl_stdev", x_lbl.std()) + self.log("train/x0_unl_mean", x_unls[0].mean()) + self.log("train/x0_unl_stdev", x_unls[0].std()) + + wandb.log({"train/x_lbl": self.wandb_hist(y_lbl, self.n_classes)}) y_lbl_ohe = one_hot(y_lbl.long(), num_classes=self.n_classes) # If x_unls is Truthy, then we are using MixMatch. @@ -183,34 +181,34 @@ def training_step(self, batch, batch_idx): y_mix_unl = y_mix[batch_size:] loss_lbl = self.loss_lbl(y_mix_lbl_pred, y_mix_lbl) - self.lbl_logger( - self.logger.experiment, - "Labelled Y Pred", - torch.argmax(y_mix_lbl_pred, dim=1), - flush_every=10, - num_bins=self.n_classes, - ) loss_unl = self.loss_unl(y_mix_unl_pred, y_mix_unl) - self.lbl_logger( - self.logger.experiment, - "Unlabelled Y Pred", - torch.argmax(y_mix_unl_pred, dim=1), - flush_every=10, - num_bins=self.n_classes, + wandb.log( + { + "train/y_lbl_pred": self.wandb_hist( + torch.argmax(y_mix_lbl_pred, dim=1), self.n_classes + ) + } + ) + wandb.log( + { + "train/y_unl_pred": self.wandb_hist( + torch.argmax(y_mix_unl_pred, dim=1), self.n_classes + ) + } ) loss_unl_scale = self.loss_unl_scaler(progress=self.progress) loss = loss_lbl + loss_unl * loss_unl_scale - self.log("loss_unl_scale", loss_unl_scale, prog_bar=True) - self.log("train_loss_lbl", loss_lbl) - self.log("train_loss_unl", loss_unl) + self.log("train/loss_unl_scale", loss_unl_scale, prog_bar=True) + self.log("train/ce_loss_lbl", loss_lbl) + self.log("train/mse_loss_unl", loss_unl) else: # This route implies that we are just using supervised learning y_pred = self(x_lbl) loss = self.loss_lbl(y_pred, y_lbl_ohe.float()) - self.log("train_loss", loss) + self.log("train/loss", loss) # Evaluate train accuracy with torch.no_grad(): @@ -218,7 +216,7 @@ def training_step(self, batch, batch_idx): acc = accuracy( y_pred, y_lbl, task="multiclass", num_classes=y_pred.shape[1] ) - self.log("train_acc", acc, prog_bar=True) + self.log("train/acc", acc, prog_bar=True) return loss # PyTorch Lightning doesn't automatically no_grads the EMA step. @@ -227,30 +225,31 @@ def training_step(self, batch, batch_idx): def on_after_backward(self) -> None: self.update_ema() + @staticmethod + def wandb_hist(x: torch.Tensor, num_bins: int) -> wandb.Histogram: + return wandb.Histogram( + torch.flatten(x).detach().cpu().tolist(), + num_bins=num_bins, + ) + def validation_step(self, batch, batch_idx): x, y = batch - self.lbl_logger( - self.logger.experiment, - "Val Input Y Label", - y, - flush_every=1, - num_bins=self.n_classes, - ) + wandb.log({"val/y_lbl": self.wandb_hist(y, self.n_classes)}) y_pred = self.ema_model(x) - self.lbl_logger( - self.logger.experiment, - "Val Pred Y Label", - torch.argmax(y_pred, dim=1), - flush_every=1, - num_bins=self.n_classes, + wandb.log( + { + "val/y_lbl_pred": self.wandb_hist( + torch.argmax(y_pred, dim=1), self.n_classes + ) + } ) loss = F.cross_entropy(y_pred, y.long()) acc = accuracy( y_pred, y, task="multiclass", num_classes=y_pred.shape[1] ) - self.log("val_loss", loss) - self.log("val_acc", acc, prog_bar=True) + self.log("val/ce_loss", loss) + self.log("val/acc", acc, prog_bar=True) return loss def test_step(self, batch, batch_idx): @@ -261,8 +260,8 @@ def test_step(self, batch, batch_idx): acc = accuracy( y_pred, y, task="multiclass", num_classes=y_pred.shape[1] ) - self.log("test_loss", loss) - self.log("test_acc", acc, prog_bar=True) + self.log("test/ce_loss", loss) + self.log("test/acc", acc, prog_bar=True) return loss def predict_step(self, batch, *args, **kwargs) -> Any: @@ -305,7 +304,7 @@ def x_trans_fn(x): # Move Channel back to the second dimension # B x H x W x C -> B x C x H x W - return ( + return torch.nan_to_num( torch.from_numpy(x_ss.reshape(b, h, w, c)) .permute(0, 3, 1, 2) .float() @@ -335,46 +334,11 @@ def y_trans_fn(y): nan = ~torch.isnan(y_trans) x_lab_trans = x_lab_trans[nan] x_unl_trans = [x[nan] for x in x_unl_trans] + x_lab_trans = torch.nan_to_num(x_lab_trans) + x_unl_trans = [torch.nan_to_num(x) for x in x_unl_trans] y_trans = y_trans[nan] if self.training: return (x_lab_trans, y_trans.long()), x_unl_trans else: return x_lab_trans, y_trans.long() - - -class WandBLabelLogger(dict): - """Logger to log y labels to WandB""" - - def __call__( - self, - logger: wandb.sdk.wandb_run.Run, - key: str, - value: torch.Tensor, - num_bins: int, - flush_every: int = 10, - ): - """Log the labels to WandB - - Args: - logger: The W&B logger. Accessible through `self.logger.experiment` - key: The key to log the labels under. - value: The labels to log. - flush_every: How often to flush the labels to WandB. - - """ - if key not in self.keys(): - self[key] = [value] - else: - self[key].append(value) - - if len(self[key]) % flush_every == 0: - logger.log( - { - key: wandb.Histogram( - torch.flatten(value).detach().cpu().tolist(), - num_bins=num_bins, - ) - } - ) - self[key] = [] From 33286c0c0f56bac6164a3d6cd7c8a7cec22c6547 Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:01:15 +0800 Subject: [PATCH 05/11] Remove unused val_iters arg --- src/frdc/train/frdc_datamodule.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/frdc/train/frdc_datamodule.py b/src/frdc/train/frdc_datamodule.py index 3b8db5f4..7b3120a7 100644 --- a/src/frdc/train/frdc_datamodule.py +++ b/src/frdc/train/frdc_datamodule.py @@ -53,7 +53,6 @@ class FRDCDataModule(LightningDataModule): batch_size: The batch size to use for the dataloaders. train_iters: The number of iterations to run for the labelled training dataset. - val_iters: The number of iterations to run for the validation dataset. """ @@ -62,7 +61,6 @@ class FRDCDataModule(LightningDataModule): train_unl_ds: FRDCDataset | FRDCUnlabelledDataset | None = None batch_size: int = 4 train_iters: int = 100 - val_iters: int = 100 sampling_strategy: Literal["stratified", "random"] = "stratified" def __post_init__(self): From 0afe80c42516b5a941b1308254c72e58f5184bcf Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:01:36 +0800 Subject: [PATCH 06/11] Remove unused val iters args --- tests/model_tests/chestnut_dec_may/train.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/model_tests/chestnut_dec_may/train.py b/tests/model_tests/chestnut_dec_may/train.py index 4ffbd786..847ef656 100644 --- a/tests/model_tests/chestnut_dec_may/train.py +++ b/tests/model_tests/chestnut_dec_may/train.py @@ -56,7 +56,6 @@ def main( batch_size=32, epochs=10, train_iters=25, - val_iters=15, lr=1e-3, wandb_name="chestnut_dec_may", wandb_project="frdc", @@ -145,7 +144,6 @@ def main( BATCH_SIZE = 32 EPOCHS = 50 TRAIN_ITERS = 25 - VAL_ITERS = 15 LR = 1e-3 torch.set_float32_matmul_precision("high") @@ -153,7 +151,6 @@ def main( batch_size=BATCH_SIZE, epochs=EPOCHS, train_iters=TRAIN_ITERS, - val_iters=VAL_ITERS, lr=LR, wandb_name="Try with Inception Unfrozen & Random Erasing", wandb_project="frdc-dev", From a5a008be7335a6d4d54ba439fc9ade76ab8d6951 Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:01:44 +0800 Subject: [PATCH 07/11] Unfreeze inception for better performance --- src/frdc/models/inceptionv3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frdc/models/inceptionv3.py b/src/frdc/models/inceptionv3.py index 3d3b3e49..f1a3209a 100644 --- a/src/frdc/models/inceptionv3.py +++ b/src/frdc/models/inceptionv3.py @@ -81,8 +81,8 @@ def __init__( # The problem is that the deep copy runs even before the module is # initialized, which means ema_model is empty. ema_model = deepcopy(self) - for param in ema_model.parameters(): - param.detach_() + # for param in ema_model.parameters(): + # param.detach_() self._ema_model = ema_model self.ema_updater = EMA(model=self, ema_model=self.ema_model) From 6d4ba32176f048e799a3cb2d8a37c78adf3b9619 Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:13:41 +0800 Subject: [PATCH 08/11] Disable wandb during tests --- tests/conftest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index b7bf6357..26687c52 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,9 +1,12 @@ import numpy as np import pytest +import wandb from frdc.load.dataset import FRDCDataset from frdc.load.preset import FRDCDatasetPreset +wandb.init(mode="disabled") + @pytest.fixture(scope="session") def ds() -> FRDCDataset: From 33b91086dc7b0748bedab5ba7e5b0d479adc1a32 Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:13:50 +0800 Subject: [PATCH 09/11] Fix incorrect loss name index --- tests/integration_tests/test_pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration_tests/test_pipeline.py b/tests/integration_tests/test_pipeline.py index a15fba6e..befe509c 100644 --- a/tests/integration_tests/test_pipeline.py +++ b/tests/integration_tests/test_pipeline.py @@ -42,5 +42,5 @@ def test_manual_segmentation_pipeline(ds): trainer = pl.Trainer(fast_dev_run=True) trainer.fit(m, datamodule=dm) - val_loss = trainer.validate(m, datamodule=dm)[0]["val_loss"] + val_loss = trainer.validate(m, datamodule=dm)[0]["val/ce_loss"] logging.debug(f"Validation score: {val_loss:.2%}") From b74c4069ec4bcb17c0a75f50b7de4e058094d648 Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:14:02 +0800 Subject: [PATCH 10/11] Fix uninitialized unl for supervised learning --- src/frdc/train/mixmatch_module.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frdc/train/mixmatch_module.py b/src/frdc/train/mixmatch_module.py index 79e81c6b..643ce1d3 100644 --- a/src/frdc/train/mixmatch_module.py +++ b/src/frdc/train/mixmatch_module.py @@ -153,8 +153,6 @@ def training_step(self, batch, batch_idx): self.log("train/x_lbl_mean", x_lbl.mean()) self.log("train/x_lbl_stdev", x_lbl.std()) - self.log("train/x0_unl_mean", x_unls[0].mean()) - self.log("train/x0_unl_stdev", x_unls[0].std()) wandb.log({"train/x_lbl": self.wandb_hist(y_lbl, self.n_classes)}) y_lbl_ohe = one_hot(y_lbl.long(), num_classes=self.n_classes) @@ -163,6 +161,8 @@ def training_step(self, batch, batch_idx): # Otherwise, we are just using supervised learning. if x_unls: # This route implies that we are using SSL + self.log("train/x0_unl_mean", x_unls[0].mean()) + self.log("train/x0_unl_stdev", x_unls[0].std()) with torch.no_grad(): y_unl = self.guess_labels(x_unls=x_unls) y_unl = self.sharpen(y_unl, self.sharpen_temp) From 9d959480a457c2e350af5d9c55d3853f470e04f7 Mon Sep 17 00:00:00 2001 From: Evening Date: Wed, 21 Feb 2024 13:17:02 +0800 Subject: [PATCH 11/11] Fix imagenet_scaling not used --- src/frdc/models/inceptionv3.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frdc/models/inceptionv3.py b/src/frdc/models/inceptionv3.py index f1a3209a..29ad6ed1 100644 --- a/src/frdc/models/inceptionv3.py +++ b/src/frdc/models/inceptionv3.py @@ -53,6 +53,7 @@ def __init__( sharpen_temp=0.5, mix_beta_alpha=0.75, ) + self.imagenet_scaling = imagenet_scaling self.inception = inception_v3( weights=Inception_V3_Weights.IMAGENET1K_V1, @@ -136,7 +137,7 @@ def adapt_inception_multi_channel( return inception @staticmethod - def imagenet_scaling(x: torch.Tensor) -> torch.Tensor: + def _imagenet_scaling(x: torch.Tensor) -> torch.Tensor: """Perform adapted ImageNet normalization on the input tensor. See Also: @@ -189,7 +190,7 @@ def forward(self, x: torch.Tensor): ) if self.imagenet_scaling: - x = self.imagenet_scaling(x) + x = self._imagenet_scaling(x) # During training, the auxiliary outputs are used for auxiliary loss, # but during testing, only the main output is used.