torch_em.self_training.logger
1import os 2 3import torch_em 4import torch 5 6from torchvision.utils import make_grid 7from torch.utils.tensorboard import SummaryWriter 8 9 10class SelfTrainingTensorboardLogger(torch_em.trainer.logger_base.TorchEmLogger): 11 """Logger for self-training via `torch_em.self_training.FixMatch` or `torch_em.self_training.MeanTeacher`. 12 Also supports logging training with invertible augmentations. 13 14 Args: 15 trainer: The instantiated trainer class. 16 save_root: The root directory for saving the checkpoints and logs. 17 """ 18 @staticmethod 19 def _get_image_channel(x): 20 return x[0, 0:1] if x.shape[1] > 1 else x[0] 21 22 def __init__(self, trainer, save_root, **unused_kwargs): 23 super().__init__(trainer, save_root) 24 self.my_root = save_root 25 self.log_dir = f"./logs/{trainer.name}" if self.my_root is None else\ 26 os.path.join(self.my_root, "logs", trainer.name) 27 os.makedirs(self.log_dir, exist_ok=True) 28 29 self.tb = SummaryWriter(self.log_dir) 30 self.log_image_interval = trainer.log_image_interval 31 32 def _add_supervised_images(self, step, name, x, y, pred): 33 if x.ndim == 5: 34 assert y.ndim == pred.ndim == 5 35 zindex = x.shape[2] // 2 36 x, y, pred = x[:, :, zindex], y[:, :, zindex], pred[:, :, zindex] 37 38 num_channels = y.shape[1] 39 40 images = ( 41 [torch_em.transform.raw.normalize(self._get_image_channel(x))] * num_channels + 42 [y[0, c:c+1] for c in range(num_channels)] + 43 [pred[0, c:c+1] for c in range(num_channels)] 44 ) 45 grid = make_grid(images, nrow=num_channels, padding=8) 46 self.tb.add_image(tag=f"{name}/supervised/input-labels-prediction", img_tensor=grid, global_step=step) 47 48 def _add_unsupervised_images(self, step, name, x1, x2, pred, pseudo_labels, label_filter): 49 if x1.ndim == 5: 50 assert x2.ndim == pred.ndim == pseudo_labels.ndim == 5 51 zindex = x1.shape[2] // 2 52 x1, x2, pred = x1[:, :, zindex], x2[:, :, zindex], pred[:, :, zindex] 53 pseudo_labels = pseudo_labels[:, :, zindex] 54 if label_filter is not None: 55 assert label_filter.ndim == 5 56 label_filter = label_filter[:, :, zindex] 57 58 num_channels = pred.shape[1] 59 60 images = ( 61 [torch_em.transform.raw.normalize(self._get_image_channel(x1))] + 62 [torch_em.transform.raw.normalize(self._get_image_channel(x2))] + 63 [torch.zeros_like(self._get_image_channel(x1))] * (num_channels - 2) + 64 [pred[0, c:c+1] for c in range(num_channels)] + 65 [pseudo_labels[0, c:c+1] for c in range(num_channels)] 66 ) 67 im_name = f"{name}/unsupervised/image-prediction-pseudolabels" 68 # if trainer with invertible augmentations, untransformed images 69 # and inverted pred/labels are logged for better visual comparison, 70 # otherwise the transformed images are logged 71 if label_filter is not None: 72 images.extend([label_filter[0, c:c+1] for c in range(num_channels)]) 73 im_name += "-labelfilter" 74 grid = make_grid(images, nrow=num_channels, padding=8) 75 self.tb.add_image(tag=im_name, img_tensor=grid, global_step=step) 76 77 def log_combined_loss(self, step, loss): 78 """@private 79 """ 80 self.tb.add_scalar(tag="train/combined_loss", scalar_value=loss, global_step=step) 81 82 def log_lr(self, step, lr): 83 """@private 84 """ 85 self.tb.add_scalar(tag="train/learning_rate", scalar_value=lr, global_step=step) 86 87 def log_train_supervised(self, step, loss, x, y, pred): 88 """@private 89 """ 90 self.tb.add_scalar(tag="train/supervised/loss", scalar_value=loss, global_step=step) 91 if step % self.log_image_interval == 0: 92 self._add_supervised_images(step, "train", x, y, pred) 93 94 def log_validation_supervised(self, step, metric, loss, x, y, pred): 95 """@private 96 """ 97 self.tb.add_scalar(tag="validation/supervised/loss", scalar_value=loss, global_step=step) 98 self.tb.add_scalar(tag="validation/supervised/metric", scalar_value=metric, global_step=step) 99 self._add_supervised_images(step, "validation", x, y, pred) 100 101 def log_train_unsupervised(self, step, loss, x1, x2, pred, pseudo_labels, label_filter=None): 102 """@private 103 """ 104 self.tb.add_scalar(tag="train/unsupervised/loss", scalar_value=loss, global_step=step) 105 if step % self.log_image_interval == 0: 106 self._add_unsupervised_images(step, "train", x1, x2, pred, pseudo_labels, label_filter) 107 108 def log_validation_unsupervised(self, step, metric, loss, x1, x2, pred, pseudo_labels, label_filter=None): 109 """@private 110 """ 111 self.tb.add_scalar(tag="validation/unsupervised/loss", scalar_value=loss, global_step=step) 112 self.tb.add_scalar(tag="validation/unsupervised/metric", scalar_value=metric, global_step=step) 113 self._add_unsupervised_images(step, "validation", x1, x2, pred, pseudo_labels, label_filter) 114 115 def log_validation(self, step, metric, loss, gt_metric=None): 116 """@private 117 """ 118 self.tb.add_scalar(tag="validation/loss", scalar_value=loss, global_step=step) 119 self.tb.add_scalar(tag="validation/metric", scalar_value=metric, global_step=step) 120 if gt_metric is not None: 121 self.tb.add_scalar(tag="validation/gt_metric", scalar_value=gt_metric, global_step=step) 122 123 def log_ct(self, step, ct): 124 self.tb.add_scalar(tag="train/confidence_threshold", scalar_value=ct, global_step=step) 125 126 def _add_augmented_images(self, step, name, xu1, xu2, pseudo_labels, pred): 127 if xu1.ndim == 5: 128 assert xu2.ndim == pseudo_labels.ndim == pred.ndim == 5 129 zindex = xu1.shape[2] // 2 130 xu1 = xu1[:, :, zindex] 131 xu2 = xu2[:, :, zindex] 132 pred = pred[:, :, zindex] 133 pseudo_labels = pseudo_labels[:, :, zindex] 134 135 images = [ 136 torch_em.transform.raw.normalize(xu1[0]), 137 torch_em.transform.raw.normalize(xu2[0]), 138 pseudo_labels[0, 0:1], 139 pred[0, 0:1], 140 ] 141 grid = make_grid(images, nrow=2, padding=8) 142 self.tb.add_image(tag=f"{name}/unsupervised/aug1-aug2-pseudolabels-prediction", img_tensor=grid, global_step=step) 143 144 def log_train_augmentations(self, step, xu1, xu2, pseudo_labels, pred): 145 if step % self.log_image_interval == 0: 146 self._add_augmented_images(step, "train_augmentations", xu1, xu2, pseudo_labels, pred) 147 148 def log_validation_augmentations(self, step, xu1, xu2, pseudo_labels, pred): 149 if step % self.log_image_interval == 0: 150 self._add_augmented_images(step, "validation_augmentations", xu1, xu2, pseudo_labels, pred) 151 152 153class ProbabilisticUNetTrainerLogger(torch_em.trainer.logger_base.TorchEmLogger): 154 def __init__(self, trainer, save_root, **unused_kwargs): 155 super().__init__(trainer, save_root) 156 self.log_dir = f"./logs/{trainer.name}" if save_root is None else\ 157 os.path.join(save_root, "logs", trainer.name) 158 os.makedirs(self.log_dir, exist_ok=True) 159 160 self.tb = torch.utils.tensorboard.SummaryWriter(self.log_dir) 161 self.log_image_interval = trainer.log_image_interval 162 163 def add_image(self, x, y, samples, name, step): 164 # NOTE: we only show the first tensor per batch for all images 165 self.tb.add_image(tag=f"{name}/input", img_tensor=x[0], global_step=step) 166 target_grid = make_grid(list(y[0].float().split(1)), nrow=4, padding=4, normalize=True) 167 self.tb.add_image(tag=f"{name}/target", img_tensor=target_grid, global_step=step) 168 predictions = [ 169 sample.sigmoid() if sample.shape[1] == 1 else sample.argmax(dim=1, keepdim=True) for sample in samples 170 ] 171 sample_grid = make_grid([sample[0].float() for sample in predictions], nrow=4, padding=4, normalize=True) 172 self.tb.add_image(tag=f"{name}/samples", img_tensor=sample_grid, global_step=step) 173 174 def log_train(self, step, loss, lr, x, y, samples): 175 self.tb.add_scalar(tag="train/loss", scalar_value=loss, global_step=step) 176 self.tb.add_scalar(tag="train/learning_rate", scalar_value=lr, global_step=step) 177 if step % self.log_image_interval == 0: 178 self.add_image(x, y, samples, "train", step) 179 180 def log_validation(self, step, metric, loss, x, y, samples): 181 self.tb.add_scalar(tag="validation/loss", scalar_value=loss, global_step=step) 182 self.tb.add_scalar(tag="validation/metric", scalar_value=metric, global_step=step) 183 self.add_image(x, y, samples, "validation", step) 184 185 186class UniMatchv2TensorboardLogger(torch_em.trainer.logger_base.TorchEmLogger): 187 """Logger for self-training via `torch_em.self_training.UniMatchv2Trainer`. 188 189 Args: 190 trainer: The instantiated trainer class. 191 save_root: The root directory for saving the checkpoints and logs. 192 """ 193 194 def __init__(self, trainer, save_root, **unused_kwargs): 195 super().__init__(trainer, save_root) 196 self.my_root = save_root 197 self.log_dir = ( 198 f"./logs/{trainer.name}" 199 if self.my_root is None 200 else os.path.join(self.my_root, "logs", trainer.name) 201 ) 202 os.makedirs(self.log_dir, exist_ok=True) 203 204 self.tb = SummaryWriter(self.log_dir) 205 self.log_image_interval = trainer.log_image_interval 206 207 def _add_supervised_images(self, step, name, x, y, pred): 208 if x.ndim == 5: 209 assert y.ndim == pred.ndim == 5 210 zindex = x.shape[2] // 2 211 x, y, pred = x[:, :, zindex], y[:, :, zindex], pred[:, :, zindex] 212 213 num_channels = y.shape[1] 214 215 images = ( 216 [torch_em.transform.raw.normalize(x[0])] * num_channels + 217 [y[0, c:c+1] for c in range(num_channels)] + 218 [pred[0, c:c+1] for c in range(num_channels)] 219 ) 220 grid = make_grid(images, nrow=num_channels, padding=8) 221 self.tb.add_image( 222 tag=f"{name}/supervised/input-labels-prediction", 223 img_tensor=grid, 224 global_step=step, 225 ) 226 227 def _add_unsupervised_images( 228 self, step, name, x, pred_s1, pred_s2, pseudo_labels, label_filter 229 ): 230 if x.ndim == 5: 231 assert ( 232 pred_s1.ndim 233 == pred_s2.ndim 234 == pseudo_labels.ndim 235 == 5 236 ) 237 zindex = x.shape[2] // 2 238 x = x[:, :, zindex] 239 pred_s1, pred_s2 = pred_s1[:, :, zindex], pred_s2[:, :, zindex] 240 pseudo_labels = pseudo_labels[:, :, zindex] 241 if label_filter is not None: 242 assert label_filter.ndim == 5 243 label_filter = label_filter[:, :, zindex] 244 num_channels = pred_s1.shape[1] 245 246 images = ( 247 [torch_em.transform.raw.normalize(x[0])] * num_channels + 248 [pred_s1[0, c:c+1] for c in range(num_channels)] + 249 [pred_s2[0, c:c+1] for c in range(num_channels)] + 250 [pseudo_labels[0, c:c+1] for c in range(num_channels)] 251 ) 252 253 im_name = ( 254 f"{name}/unsupervised/image-pred_s1-pred_s2-pseudolabels" 255 ) 256 if label_filter is not None: 257 images.extend([label_filter[0, c:c+1] for c in range(num_channels)]) 258 im_name += "-labelfilter" 259 grid = make_grid(images, nrow=num_channels, padding=8) 260 self.tb.add_image(tag=im_name, img_tensor=grid, global_step=step) 261 262 def log_combined_loss(self, step, loss): 263 """@private""" 264 self.tb.add_scalar( 265 tag="train/combined_loss", scalar_value=loss, global_step=step 266 ) 267 268 def log_lr(self, step, lr): 269 """@private""" 270 self.tb.add_scalar(tag="train/learning_rate", scalar_value=lr, global_step=step) 271 272 def log_train_supervised(self, step, loss, x, y, pred): 273 """@private""" 274 self.tb.add_scalar( 275 tag="train/supervised/loss", scalar_value=loss, global_step=step 276 ) 277 if step % self.log_image_interval == 0: 278 self._add_supervised_images(step, "train", x, y, pred) 279 280 def log_validation_supervised(self, step, metric, loss, x, y, pred): 281 """@private""" 282 self.tb.add_scalar( 283 tag="validation/supervised/loss", scalar_value=loss, global_step=step 284 ) 285 self.tb.add_scalar( 286 tag="validation/supervised/metric", scalar_value=metric, global_step=step 287 ) 288 self._add_supervised_images(step, "validation", x, y, pred) 289 290 def log_train_unsupervised( 291 self, 292 step, 293 loss, 294 x, 295 pred_s1, 296 pred_s2, 297 pseudo_labels, 298 label_filter=None, 299 ): 300 """@private""" 301 self.tb.add_scalar( 302 tag="train/unsupervised/loss", scalar_value=loss, global_step=step 303 ) 304 if step % self.log_image_interval == 0: 305 self._add_unsupervised_images( 306 step, 307 "train", 308 x, 309 pred_s1, 310 pred_s2, 311 pseudo_labels, 312 label_filter, 313 ) 314 315 def log_validation_unsupervised( 316 self, 317 step, 318 metric, 319 loss, 320 x, 321 pred_s1, 322 pred_s2, 323 pseudo_labels, 324 label_filter=None, 325 ): 326 """@private""" 327 self.tb.add_scalar( 328 tag="validation/unsupervised/loss", scalar_value=loss, global_step=step 329 ) 330 self.tb.add_scalar( 331 tag="validation/unsupervised/metric", scalar_value=metric, global_step=step 332 ) 333 self._add_unsupervised_images( 334 step, 335 "validation", 336 x, 337 pred_s1, 338 pred_s2, 339 pseudo_labels, 340 label_filter, 341 ) 342 343 def log_ct(self, step, ct): 344 self.tb.add_scalar( 345 tag="train/confidence_threshold", scalar_value=ct, global_step=step 346 ) 347 348 # LOG AUGMENTATIONS FOR DEBUGGING ### 349 def _add_augmented_images( 350 self, step, name, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2 351 ): 352 if x_u_w.ndim == 5: 353 assert ( 354 x_u_s1.ndim 355 == x_u_s2.ndim 356 == pseudo_labels.ndim 357 == pred_s1.ndim 358 == pred_s2.ndim 359 == 5 360 ) 361 zindex = x_u_w.shape[2] // 2 362 x_u_w = x_u_w[:, :, zindex] 363 x_u_s1, x_u_s2 = x_u_s1[:, :, zindex], x_u_s2[:, :, zindex] 364 pred_s1, pred_s2 = pred_s1[:, :, zindex], pred_s2[:, :, zindex] 365 pseudo_labels = pseudo_labels[:, :, zindex] 366 367 images = [ 368 torch_em.transform.raw.normalize(x_u_w[0]), 369 torch_em.transform.raw.normalize(x_u_s1[0]), 370 torch_em.transform.raw.normalize(x_u_s2[0]), 371 pseudo_labels[0, 0:1], 372 pred_s1[0, 0:1], 373 pred_s2[0, 0:1], 374 ] 375 im_name = ( 376 f"{name}/unsupervised/aug_w-aug_s1-aug_s2-pseudolabels-pred_s1-pred_s2" 377 ) 378 grid = make_grid(images, nrow=3, padding=8) 379 self.tb.add_image(tag=im_name, img_tensor=grid, global_step=step) 380 381 def log_train_augmentations( 382 self, step, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2 383 ): 384 if step % self.log_image_interval == 0: 385 self._add_augmented_images( 386 step, 387 "train_augmentations", 388 x_u_w, 389 x_u_s1, 390 x_u_s2, 391 pseudo_labels, 392 pred_s1, 393 pred_s2, 394 ) 395 396 def log_validation_augmentations( 397 self, step, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2 398 ): 399 if step % self.log_image_interval == 0: 400 self._add_augmented_images( 401 step, 402 "validation_augmentations", 403 x_u_w, 404 x_u_s1, 405 x_u_s2, 406 pseudo_labels, 407 pred_s1, 408 pred_s2, 409 )
11class SelfTrainingTensorboardLogger(torch_em.trainer.logger_base.TorchEmLogger): 12 """Logger for self-training via `torch_em.self_training.FixMatch` or `torch_em.self_training.MeanTeacher`. 13 Also supports logging training with invertible augmentations. 14 15 Args: 16 trainer: The instantiated trainer class. 17 save_root: The root directory for saving the checkpoints and logs. 18 """ 19 @staticmethod 20 def _get_image_channel(x): 21 return x[0, 0:1] if x.shape[1] > 1 else x[0] 22 23 def __init__(self, trainer, save_root, **unused_kwargs): 24 super().__init__(trainer, save_root) 25 self.my_root = save_root 26 self.log_dir = f"./logs/{trainer.name}" if self.my_root is None else\ 27 os.path.join(self.my_root, "logs", trainer.name) 28 os.makedirs(self.log_dir, exist_ok=True) 29 30 self.tb = SummaryWriter(self.log_dir) 31 self.log_image_interval = trainer.log_image_interval 32 33 def _add_supervised_images(self, step, name, x, y, pred): 34 if x.ndim == 5: 35 assert y.ndim == pred.ndim == 5 36 zindex = x.shape[2] // 2 37 x, y, pred = x[:, :, zindex], y[:, :, zindex], pred[:, :, zindex] 38 39 num_channels = y.shape[1] 40 41 images = ( 42 [torch_em.transform.raw.normalize(self._get_image_channel(x))] * num_channels + 43 [y[0, c:c+1] for c in range(num_channels)] + 44 [pred[0, c:c+1] for c in range(num_channels)] 45 ) 46 grid = make_grid(images, nrow=num_channels, padding=8) 47 self.tb.add_image(tag=f"{name}/supervised/input-labels-prediction", img_tensor=grid, global_step=step) 48 49 def _add_unsupervised_images(self, step, name, x1, x2, pred, pseudo_labels, label_filter): 50 if x1.ndim == 5: 51 assert x2.ndim == pred.ndim == pseudo_labels.ndim == 5 52 zindex = x1.shape[2] // 2 53 x1, x2, pred = x1[:, :, zindex], x2[:, :, zindex], pred[:, :, zindex] 54 pseudo_labels = pseudo_labels[:, :, zindex] 55 if label_filter is not None: 56 assert label_filter.ndim == 5 57 label_filter = label_filter[:, :, zindex] 58 59 num_channels = pred.shape[1] 60 61 images = ( 62 [torch_em.transform.raw.normalize(self._get_image_channel(x1))] + 63 [torch_em.transform.raw.normalize(self._get_image_channel(x2))] + 64 [torch.zeros_like(self._get_image_channel(x1))] * (num_channels - 2) + 65 [pred[0, c:c+1] for c in range(num_channels)] + 66 [pseudo_labels[0, c:c+1] for c in range(num_channels)] 67 ) 68 im_name = f"{name}/unsupervised/image-prediction-pseudolabels" 69 # if trainer with invertible augmentations, untransformed images 70 # and inverted pred/labels are logged for better visual comparison, 71 # otherwise the transformed images are logged 72 if label_filter is not None: 73 images.extend([label_filter[0, c:c+1] for c in range(num_channels)]) 74 im_name += "-labelfilter" 75 grid = make_grid(images, nrow=num_channels, padding=8) 76 self.tb.add_image(tag=im_name, img_tensor=grid, global_step=step) 77 78 def log_combined_loss(self, step, loss): 79 """@private 80 """ 81 self.tb.add_scalar(tag="train/combined_loss", scalar_value=loss, global_step=step) 82 83 def log_lr(self, step, lr): 84 """@private 85 """ 86 self.tb.add_scalar(tag="train/learning_rate", scalar_value=lr, global_step=step) 87 88 def log_train_supervised(self, step, loss, x, y, pred): 89 """@private 90 """ 91 self.tb.add_scalar(tag="train/supervised/loss", scalar_value=loss, global_step=step) 92 if step % self.log_image_interval == 0: 93 self._add_supervised_images(step, "train", x, y, pred) 94 95 def log_validation_supervised(self, step, metric, loss, x, y, pred): 96 """@private 97 """ 98 self.tb.add_scalar(tag="validation/supervised/loss", scalar_value=loss, global_step=step) 99 self.tb.add_scalar(tag="validation/supervised/metric", scalar_value=metric, global_step=step) 100 self._add_supervised_images(step, "validation", x, y, pred) 101 102 def log_train_unsupervised(self, step, loss, x1, x2, pred, pseudo_labels, label_filter=None): 103 """@private 104 """ 105 self.tb.add_scalar(tag="train/unsupervised/loss", scalar_value=loss, global_step=step) 106 if step % self.log_image_interval == 0: 107 self._add_unsupervised_images(step, "train", x1, x2, pred, pseudo_labels, label_filter) 108 109 def log_validation_unsupervised(self, step, metric, loss, x1, x2, pred, pseudo_labels, label_filter=None): 110 """@private 111 """ 112 self.tb.add_scalar(tag="validation/unsupervised/loss", scalar_value=loss, global_step=step) 113 self.tb.add_scalar(tag="validation/unsupervised/metric", scalar_value=metric, global_step=step) 114 self._add_unsupervised_images(step, "validation", x1, x2, pred, pseudo_labels, label_filter) 115 116 def log_validation(self, step, metric, loss, gt_metric=None): 117 """@private 118 """ 119 self.tb.add_scalar(tag="validation/loss", scalar_value=loss, global_step=step) 120 self.tb.add_scalar(tag="validation/metric", scalar_value=metric, global_step=step) 121 if gt_metric is not None: 122 self.tb.add_scalar(tag="validation/gt_metric", scalar_value=gt_metric, global_step=step) 123 124 def log_ct(self, step, ct): 125 self.tb.add_scalar(tag="train/confidence_threshold", scalar_value=ct, global_step=step) 126 127 def _add_augmented_images(self, step, name, xu1, xu2, pseudo_labels, pred): 128 if xu1.ndim == 5: 129 assert xu2.ndim == pseudo_labels.ndim == pred.ndim == 5 130 zindex = xu1.shape[2] // 2 131 xu1 = xu1[:, :, zindex] 132 xu2 = xu2[:, :, zindex] 133 pred = pred[:, :, zindex] 134 pseudo_labels = pseudo_labels[:, :, zindex] 135 136 images = [ 137 torch_em.transform.raw.normalize(xu1[0]), 138 torch_em.transform.raw.normalize(xu2[0]), 139 pseudo_labels[0, 0:1], 140 pred[0, 0:1], 141 ] 142 grid = make_grid(images, nrow=2, padding=8) 143 self.tb.add_image(tag=f"{name}/unsupervised/aug1-aug2-pseudolabels-prediction", img_tensor=grid, global_step=step) 144 145 def log_train_augmentations(self, step, xu1, xu2, pseudo_labels, pred): 146 if step % self.log_image_interval == 0: 147 self._add_augmented_images(step, "train_augmentations", xu1, xu2, pseudo_labels, pred) 148 149 def log_validation_augmentations(self, step, xu1, xu2, pseudo_labels, pred): 150 if step % self.log_image_interval == 0: 151 self._add_augmented_images(step, "validation_augmentations", xu1, xu2, pseudo_labels, pred)
Logger for self-training via torch_em.self_training.FixMatch or torch_em.self_training.MeanTeacher.
Also supports logging training with invertible augmentations.
Arguments:
- trainer: The instantiated trainer class.
- save_root: The root directory for saving the checkpoints and logs.
SelfTrainingTensorboardLogger(trainer, save_root, **unused_kwargs)
23 def __init__(self, trainer, save_root, **unused_kwargs): 24 super().__init__(trainer, save_root) 25 self.my_root = save_root 26 self.log_dir = f"./logs/{trainer.name}" if self.my_root is None else\ 27 os.path.join(self.my_root, "logs", trainer.name) 28 os.makedirs(self.log_dir, exist_ok=True) 29 30 self.tb = SummaryWriter(self.log_dir) 31 self.log_image_interval = trainer.log_image_interval
Inherited Members
187class UniMatchv2TensorboardLogger(torch_em.trainer.logger_base.TorchEmLogger): 188 """Logger for self-training via `torch_em.self_training.UniMatchv2Trainer`. 189 190 Args: 191 trainer: The instantiated trainer class. 192 save_root: The root directory for saving the checkpoints and logs. 193 """ 194 195 def __init__(self, trainer, save_root, **unused_kwargs): 196 super().__init__(trainer, save_root) 197 self.my_root = save_root 198 self.log_dir = ( 199 f"./logs/{trainer.name}" 200 if self.my_root is None 201 else os.path.join(self.my_root, "logs", trainer.name) 202 ) 203 os.makedirs(self.log_dir, exist_ok=True) 204 205 self.tb = SummaryWriter(self.log_dir) 206 self.log_image_interval = trainer.log_image_interval 207 208 def _add_supervised_images(self, step, name, x, y, pred): 209 if x.ndim == 5: 210 assert y.ndim == pred.ndim == 5 211 zindex = x.shape[2] // 2 212 x, y, pred = x[:, :, zindex], y[:, :, zindex], pred[:, :, zindex] 213 214 num_channels = y.shape[1] 215 216 images = ( 217 [torch_em.transform.raw.normalize(x[0])] * num_channels + 218 [y[0, c:c+1] for c in range(num_channels)] + 219 [pred[0, c:c+1] for c in range(num_channels)] 220 ) 221 grid = make_grid(images, nrow=num_channels, padding=8) 222 self.tb.add_image( 223 tag=f"{name}/supervised/input-labels-prediction", 224 img_tensor=grid, 225 global_step=step, 226 ) 227 228 def _add_unsupervised_images( 229 self, step, name, x, pred_s1, pred_s2, pseudo_labels, label_filter 230 ): 231 if x.ndim == 5: 232 assert ( 233 pred_s1.ndim 234 == pred_s2.ndim 235 == pseudo_labels.ndim 236 == 5 237 ) 238 zindex = x.shape[2] // 2 239 x = x[:, :, zindex] 240 pred_s1, pred_s2 = pred_s1[:, :, zindex], pred_s2[:, :, zindex] 241 pseudo_labels = pseudo_labels[:, :, zindex] 242 if label_filter is not None: 243 assert label_filter.ndim == 5 244 label_filter = label_filter[:, :, zindex] 245 num_channels = pred_s1.shape[1] 246 247 images = ( 248 [torch_em.transform.raw.normalize(x[0])] * num_channels + 249 [pred_s1[0, c:c+1] for c in range(num_channels)] + 250 [pred_s2[0, c:c+1] for c in range(num_channels)] + 251 [pseudo_labels[0, c:c+1] for c in range(num_channels)] 252 ) 253 254 im_name = ( 255 f"{name}/unsupervised/image-pred_s1-pred_s2-pseudolabels" 256 ) 257 if label_filter is not None: 258 images.extend([label_filter[0, c:c+1] for c in range(num_channels)]) 259 im_name += "-labelfilter" 260 grid = make_grid(images, nrow=num_channels, padding=8) 261 self.tb.add_image(tag=im_name, img_tensor=grid, global_step=step) 262 263 def log_combined_loss(self, step, loss): 264 """@private""" 265 self.tb.add_scalar( 266 tag="train/combined_loss", scalar_value=loss, global_step=step 267 ) 268 269 def log_lr(self, step, lr): 270 """@private""" 271 self.tb.add_scalar(tag="train/learning_rate", scalar_value=lr, global_step=step) 272 273 def log_train_supervised(self, step, loss, x, y, pred): 274 """@private""" 275 self.tb.add_scalar( 276 tag="train/supervised/loss", scalar_value=loss, global_step=step 277 ) 278 if step % self.log_image_interval == 0: 279 self._add_supervised_images(step, "train", x, y, pred) 280 281 def log_validation_supervised(self, step, metric, loss, x, y, pred): 282 """@private""" 283 self.tb.add_scalar( 284 tag="validation/supervised/loss", scalar_value=loss, global_step=step 285 ) 286 self.tb.add_scalar( 287 tag="validation/supervised/metric", scalar_value=metric, global_step=step 288 ) 289 self._add_supervised_images(step, "validation", x, y, pred) 290 291 def log_train_unsupervised( 292 self, 293 step, 294 loss, 295 x, 296 pred_s1, 297 pred_s2, 298 pseudo_labels, 299 label_filter=None, 300 ): 301 """@private""" 302 self.tb.add_scalar( 303 tag="train/unsupervised/loss", scalar_value=loss, global_step=step 304 ) 305 if step % self.log_image_interval == 0: 306 self._add_unsupervised_images( 307 step, 308 "train", 309 x, 310 pred_s1, 311 pred_s2, 312 pseudo_labels, 313 label_filter, 314 ) 315 316 def log_validation_unsupervised( 317 self, 318 step, 319 metric, 320 loss, 321 x, 322 pred_s1, 323 pred_s2, 324 pseudo_labels, 325 label_filter=None, 326 ): 327 """@private""" 328 self.tb.add_scalar( 329 tag="validation/unsupervised/loss", scalar_value=loss, global_step=step 330 ) 331 self.tb.add_scalar( 332 tag="validation/unsupervised/metric", scalar_value=metric, global_step=step 333 ) 334 self._add_unsupervised_images( 335 step, 336 "validation", 337 x, 338 pred_s1, 339 pred_s2, 340 pseudo_labels, 341 label_filter, 342 ) 343 344 def log_ct(self, step, ct): 345 self.tb.add_scalar( 346 tag="train/confidence_threshold", scalar_value=ct, global_step=step 347 ) 348 349 # LOG AUGMENTATIONS FOR DEBUGGING ### 350 def _add_augmented_images( 351 self, step, name, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2 352 ): 353 if x_u_w.ndim == 5: 354 assert ( 355 x_u_s1.ndim 356 == x_u_s2.ndim 357 == pseudo_labels.ndim 358 == pred_s1.ndim 359 == pred_s2.ndim 360 == 5 361 ) 362 zindex = x_u_w.shape[2] // 2 363 x_u_w = x_u_w[:, :, zindex] 364 x_u_s1, x_u_s2 = x_u_s1[:, :, zindex], x_u_s2[:, :, zindex] 365 pred_s1, pred_s2 = pred_s1[:, :, zindex], pred_s2[:, :, zindex] 366 pseudo_labels = pseudo_labels[:, :, zindex] 367 368 images = [ 369 torch_em.transform.raw.normalize(x_u_w[0]), 370 torch_em.transform.raw.normalize(x_u_s1[0]), 371 torch_em.transform.raw.normalize(x_u_s2[0]), 372 pseudo_labels[0, 0:1], 373 pred_s1[0, 0:1], 374 pred_s2[0, 0:1], 375 ] 376 im_name = ( 377 f"{name}/unsupervised/aug_w-aug_s1-aug_s2-pseudolabels-pred_s1-pred_s2" 378 ) 379 grid = make_grid(images, nrow=3, padding=8) 380 self.tb.add_image(tag=im_name, img_tensor=grid, global_step=step) 381 382 def log_train_augmentations( 383 self, step, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2 384 ): 385 if step % self.log_image_interval == 0: 386 self._add_augmented_images( 387 step, 388 "train_augmentations", 389 x_u_w, 390 x_u_s1, 391 x_u_s2, 392 pseudo_labels, 393 pred_s1, 394 pred_s2, 395 ) 396 397 def log_validation_augmentations( 398 self, step, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2 399 ): 400 if step % self.log_image_interval == 0: 401 self._add_augmented_images( 402 step, 403 "validation_augmentations", 404 x_u_w, 405 x_u_s1, 406 x_u_s2, 407 pseudo_labels, 408 pred_s1, 409 pred_s2, 410 )
Logger for self-training via torch_em.self_training.UniMatchv2Trainer.
Arguments:
- trainer: The instantiated trainer class.
- save_root: The root directory for saving the checkpoints and logs.
UniMatchv2TensorboardLogger(trainer, save_root, **unused_kwargs)
195 def __init__(self, trainer, save_root, **unused_kwargs): 196 super().__init__(trainer, save_root) 197 self.my_root = save_root 198 self.log_dir = ( 199 f"./logs/{trainer.name}" 200 if self.my_root is None 201 else os.path.join(self.my_root, "logs", trainer.name) 202 ) 203 os.makedirs(self.log_dir, exist_ok=True) 204 205 self.tb = SummaryWriter(self.log_dir) 206 self.log_image_interval = trainer.log_image_interval
def
log_train_augmentations(self, step, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2):
382 def log_train_augmentations( 383 self, step, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2 384 ): 385 if step % self.log_image_interval == 0: 386 self._add_augmented_images( 387 step, 388 "train_augmentations", 389 x_u_w, 390 x_u_s1, 391 x_u_s2, 392 pseudo_labels, 393 pred_s1, 394 pred_s2, 395 )
def
log_validation_augmentations(self, step, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2):
397 def log_validation_augmentations( 398 self, step, x_u_w, x_u_s1, x_u_s2, pseudo_labels, pred_s1, pred_s2 399 ): 400 if step % self.log_image_interval == 0: 401 self._add_augmented_images( 402 step, 403 "validation_augmentations", 404 x_u_w, 405 x_u_s1, 406 x_u_s2, 407 pseudo_labels, 408 pred_s1, 409 pred_s2, 410 )