LSTM DANN¶
import rul_adapt
import rul_datasets
import pytorch_lightning as pl
import omegaconf
Reproduce original configurations¶
You can reproduce the original experiments of daCosta et al. by using the get_lstm_dann constructor function.
Known differences to the original are:
- a bigger validation split (20% instead of 10% of training data).
In this example, we re-create configuration for adaption CMAPSS FD003 to FD001.
Additional kwargs for the trainer, e.g. accelerator="gpu" for training on a GPU, can be passed to this function, too.
pl.seed_everything(42, workers=True) # make reproducible
dm, dann, trainer = rul_adapt.construct.get_lstm_dann(3, 1, max_epochs=1)
Global seed set to 42 GPU available: False, used: False TPU available: False, using: 0 TPU cores IPU available: False, using: 0 IPUs HPU available: False, using: 0 HPUs
The networks, feature_extractor, regressor, domain_disc, can be accessed as properties of the dann object.
dann.feature_extractor
LstmExtractor(
(_lstm_layers): _Rnn(
(_layers): ModuleList(
(0): LSTM(24, 64)
(1): LSTM(64, 32)
)
)
(_fc_layer): Sequential(
(0): Dropout(p=0.3, inplace=False)
(1): Linear(in_features=32, out_features=128, bias=True)
(2): ReLU()
)
)
Training is done in the PyTorch Lightning fashion.
We used the trainer_kwargs to train only one epoch for demonstration purposes.
trainer.fit(dann, dm)
trainer.test(ckpt_path="best", datamodule=dm) # loads the best model checkpoint
| Name | Type | Params ------------------------------------------------------------- 0 | train_source_loss | MeanAbsoluteError | 0 1 | evaluator | AdaptionEvaluator | 0 2 | _feature_extractor | LstmExtractor | 39.8 K 3 | _regressor | FullyConnectedHead | 5.2 K 4 | dann_loss | DomainAdversarialLoss | 5.2 K ------------------------------------------------------------- 50.2 K Trainable params 0 Non-trainable params 50.2 K Total params 0.201 Total estimated model params size (MB)
Sanity Checking: 0it [00:00, ?it/s]
Training: 0it [00:00, ?it/s]
Validation: 0it [00:00, ?it/s]
`Trainer.fit` stopped: `max_epochs=1` reached. Restoring states from the checkpoint path at /home/tilman/Programming/rul-adapt/docs/examples/lightning_logs/version_32/checkpoints/epoch=0-step=69.ckpt Loaded model weights from checkpoint at /home/tilman/Programming/rul-adapt/docs/examples/lightning_logs/version_32/checkpoints/epoch=0-step=69.ckpt
Testing: 0it [00:00, ?it/s]
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Test metric DataLoader 0 DataLoader 1
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
test/source/rmse 20.155813217163086
test/source/score 1689.973876953125
test/target/rmse 32.33406448364258
test/target/score 12900.6259765625
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[{'test/source/rmse/dataloader_idx_0': 20.155813217163086,
'test/source/score/dataloader_idx_0': 1689.973876953125},
{'test/target/rmse/dataloader_idx_1': 32.33406448364258,
'test/target/score/dataloader_idx_1': 12900.6259765625}]
If you only want to see the hyperparameters, you can use the get_lstm_dann_config function.
This returns an omegeconf.DictConfig which you can modify.
three2one_config = rul_adapt.construct.get_lstm_dann_config(3, 1)
print(omegaconf.OmegaConf.to_yaml(three2one_config, resolve=True))
dm:
source:
_target_: rul_datasets.CmapssReader
fd: 3
feature_select:
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
target:
fd: 1
percent_broken: 1.0
batch_size: 256
feature_extractor:
_convert_: all
_target_: rul_adapt.model.LstmExtractor
input_channels: 24
units:
- 64
- 32
fc_units: 128
dropout: 0.3
fc_dropout: 0.3
regressor:
_convert_: all
_target_: rul_adapt.model.FullyConnectedHead
input_channels: 128
act_func_on_last_layer: false
units:
- 32
- 32
- 1
dropout: 0.1
domain_disc:
_convert_: all
_target_: rul_adapt.model.FullyConnectedHead
input_channels: 128
act_func_on_last_layer: false
units:
- 32
- 32
- 1
dropout: 0.1
dann:
_target_: rul_adapt.approach.DannApproach
scheduler_type: step
scheduler_gamma: 0.1
scheduler_step_size: 100
dann_factor: 2.0
lr: 0.01
optim_weight_decay: 0.01
trainer:
_target_: pytorch_lightning.Trainer
max_epochs: 200
gradient_clip_val: 1.0
callbacks:
- _target_: pytorch_lightning.callbacks.EarlyStopping
monitor: val/target/rmse/dataloader_idx_1
patience: 20
- _target_: pytorch_lightning.callbacks.ModelCheckpoint
save_top_k: 1
monitor: val/target/rmse/dataloader_idx_1
mode: min
Run your own experiments¶
You can use the LSTM DANN implementation to run your own experiments with different hyperparameters or on different datasets. Here we build a smaller LSTM DANN version for CMAPSS.
source = rul_datasets.CmapssReader(3)
target = source.get_compatible(1, percent_broken=0.8)
dm = rul_datasets.DomainAdaptionDataModule(
rul_datasets.RulDataModule(source, batch_size=32),
rul_datasets.RulDataModule(target, batch_size=32),
)
feature_extractor = rul_adapt.model.LstmExtractor(
input_channels=14,
units=[16],
fc_units=8,
)
regressor = rul_adapt.model.FullyConnectedHead(
input_channels=8,
units=[8, 1],
act_func_on_last_layer=False,
)
domain_disc = rul_adapt.model.FullyConnectedHead(
input_channels=8,
units=[8, 1],
act_func_on_last_layer=False,
)
dann = rul_adapt.approach.DannApproach(dann_factor=1.0, lr=0.001)
dann.set_model(feature_extractor, regressor, domain_disc)
trainer = pl.Trainer(max_epochs=1)
trainer.fit(dann, dm)
trainer.test(dann, dm)
GPU available: False, used: False TPU available: False, using: 0 TPU cores IPU available: False, using: 0 IPUs HPU available: False, using: 0 HPUs | Name | Type | Params ------------------------------------------------------------- 0 | train_source_loss | MeanAbsoluteError | 0 1 | evaluator | AdaptionEvaluator | 0 2 | _feature_extractor | LstmExtractor | 2.2 K 3 | _regressor | FullyConnectedHead | 81 4 | dann_loss | DomainAdversarialLoss | 81 ------------------------------------------------------------- 2.3 K Trainable params 0 Non-trainable params 2.3 K Total params 0.009 Total estimated model params size (MB)
Sanity Checking: 0it [00:00, ?it/s]
Training: 0it [00:00, ?it/s]
Validation: 0it [00:00, ?it/s]
`Trainer.fit` stopped: `max_epochs=1` reached.
Testing: 0it [00:00, ?it/s]
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Test metric DataLoader 0 DataLoader 1
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
test/source/rmse 20.648313522338867
test/source/score 876.435546875
test/target/rmse 21.399911880493164
test/target/score 1010.3373413085938
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[{'test/source/rmse/dataloader_idx_0': 20.648313522338867,
'test/source/score/dataloader_idx_0': 876.435546875},
{'test/target/rmse/dataloader_idx_1': 21.399911880493164,
'test/target/score/dataloader_idx_1': 1010.3373413085938}]