import neurenix as nx
from neurenix.continual import EWC, ExperienceReplay
# Create model and training components
model = create_model()
optimizer = nx.optim.Adam(model.parameters(), lr=0.001)
criterion = nx.nn.CrossEntropyLoss()
# Initialize continual learning strategies
ewc = EWC(model, lambda_reg=5000.0, use_online=True)
replay = ExperienceReplay(
memory_size=5000,
strategy="reservoir",
per_class=True,
sample_size=64
)
# Train on sequence of tasks
task_loaders = [task1_loader, task2_loader, task3_loader, task4_loader]
test_loaders = [test1_loader, test2_loader, test3_loader, test4_loader]
for task_id, task_loader in enumerate(task_loaders):
print(f"\nTraining on Task {task_id + 1}")
for epoch in range(num_epochs):
for batch in task_loader:
optimizer.zero_grad()
# Current task loss
loss = criterion(model(batch.x), batch.y)
# Add EWC penalty (after first task)
if task_id > 0:
loss += ewc.penalty()
# Add replay loss (after first task)
if task_id > 0 and replay.get_memory_size() > 0:
replay_x, replay_y = replay.sample_memory(batch_size=32)
replay_loss = criterion(model(replay_x), replay_y)
loss += 0.5 * replay_loss
loss.backward()
optimizer.step()
# Update replay buffer
replay.update_memory(batch.x, batch.y, task_id=task_id)
# Register task with EWC
ewc.register_task(task_loader, criterion, optimizer, num_samples=1000)
# Evaluate on all tasks seen so far
print(f"\nEvaluation after Task {task_id + 1}:")
for eval_id in range(task_id + 1):
accuracy = evaluate(model, test_loaders[eval_id])
print(f" Task {eval_id + 1} accuracy: {accuracy:.2f}%")
# Final evaluation
print("\nFinal Results:")
for task_id, test_loader in enumerate(test_loaders):
accuracy = evaluate(model, test_loader)
print(f"Task {task_id + 1}: {accuracy:.2f}%")
avg_accuracy = sum(evaluate(model, loader) for loader in test_loaders) / len(test_loaders)
print(f"\nAverage accuracy: {avg_accuracy:.2f}%")