cope.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. ################################################################################
  2. # Copyright (c) 2021 ContinualAI. #
  3. # Copyrights licensed under the MIT License. #
  4. # See the accompanying LICENSE file for terms. #
  5. # #
  6. # Date: 20-04-2020 #
  7. # Author(s): Matthias De Lange #
  8. # E-mail: contact@continualai.org #
  9. # Website: avalanche.continualai.org #
  10. ################################################################################
  11. """
  12. This is a simple example on how to use the CoPE plugin.
  13. It's an example in the online data incremental setting, where both learning and
  14. evaluation is completely task-agnostic.
  15. Original implementation:
  16. https://github.com/Mattdl/ContinualPrototypeEvolution
  17. Reference:
  18. De Lange, Matthias, et al. "Continual prototype evolution: Learning online from
  19. non-stationary data streams." ICCV. 2021.
  20. """
  21. from __future__ import absolute_import
  22. from __future__ import division
  23. from __future__ import print_function
  24. import argparse
  25. import torch
  26. import torch.optim.lr_scheduler
  27. from avalanche.benchmarks import SplitMNIST
  28. from avalanche.models import SimpleMLP
  29. from avalanche.training.strategies import Naive
  30. from avalanche.training.plugins import CoPEPlugin
  31. from avalanche.evaluation.metrics import StreamForgetting, \
  32. accuracy_metrics, loss_metrics
  33. from avalanche.logging import TextLogger
  34. from avalanche.training.plugins import EvaluationPlugin
  35. from avalanche.benchmarks.generators.benchmark_generators import \
  36. data_incremental_benchmark
  37. def main(args):
  38. """
  39. Last Avalanche version reference performance (online = 1 epoch):
  40. Class-incremental (online):
  41. Top1_Acc_Stream/eval_phase/test_stream = 0.9421
  42. Data-incremental (online:
  43. Top1_Acc_Stream/eval_phase/test_stream = 0.9309
  44. These are reference results for a single run.
  45. """
  46. # --- DEFAULT PARAMS ONLINE DATA INCREMENTAL LEARNING
  47. nb_tasks = 5 # Can still design the data stream based on tasks
  48. batch_size = 10 # Learning agent only has small amount of data available
  49. epochs = 1 # How many times to process each mini-batch
  50. return_task_id = False # Data incremental (task-agnostic/task-free)
  51. # --- CONFIG
  52. device = torch.device(
  53. f"cuda:{args.cuda}" if torch.cuda.is_available() and args.cuda >= 0
  54. else "cpu")
  55. # ---------
  56. # --- SCENARIO CREATION
  57. n_classes = 10
  58. task_scenario = SplitMNIST(nb_tasks, return_task_id=return_task_id,
  59. fixed_class_order=[i for i in range(n_classes)])
  60. # Make data incremental (one batch = one experience)
  61. scenario = data_incremental_benchmark(task_scenario,
  62. experience_size=batch_size)
  63. print(f"{scenario.n_experiences} batches in online data incremental setup.")
  64. # 6002 batches for SplitMNIST with batch size 10
  65. # ---------
  66. # MODEL CREATION
  67. model = SimpleMLP(num_classes=args.featsize,
  68. hidden_size=400, hidden_layers=2, drop_rate=0)
  69. # choose some metrics and evaluation method
  70. logger = TextLogger()
  71. eval_plugin = EvaluationPlugin(
  72. accuracy_metrics(experience=True, stream=True),
  73. loss_metrics(experience=False, stream=True),
  74. StreamForgetting(),
  75. loggers=[logger],
  76. benchmark=scenario)
  77. # CoPE PLUGIN
  78. cope = CoPEPlugin(mem_size=2000, alpha=0.99,
  79. p_size=args.featsize, n_classes=n_classes)
  80. # CREATE THE STRATEGY INSTANCE (NAIVE) WITH CoPE PLUGIN
  81. cl_strategy = Naive(model, torch.optim.SGD(model.parameters(), lr=0.01),
  82. cope.ppp_loss, # CoPE PPP-Loss
  83. train_mb_size=batch_size, train_epochs=epochs,
  84. eval_mb_size=100, device=device,
  85. plugins=[cope],
  86. evaluator=eval_plugin
  87. )
  88. # TRAINING LOOP
  89. print('Starting experiment...')
  90. results = []
  91. cl_strategy.train(scenario.train_stream)
  92. print('Computing accuracy on the whole test set')
  93. results.append(cl_strategy.eval(scenario.test_stream))
  94. if __name__ == '__main__':
  95. parser = argparse.ArgumentParser()
  96. parser.add_argument('--cuda', type=int, default=0,
  97. help='Select zero-indexed cuda device. -1 to use CPU.')
  98. parser.add_argument('--featsize', type=int, default=32,
  99. help='Feature size for the embedding.')
  100. args = parser.parse_args()
  101. main(args)