-
-
Notifications
You must be signed in to change notification settings - Fork 7
Description
User Story
As a researcher, I want to train a model using the Reptile meta-learning algorithm so that I can establish a performance baseline to compare against more complex algorithms like MAML and SEAL.
Dependencies
- [Episodic Data Abstractions for Meta-Learning (N-way K-shot) #290: Episodic Data Abstractions]: This issue depends on the creation of an
EpisodicDataLoaderthat can sample tasks in an N-way, K-shot format.
Phase 1: ReptileTrainer Implementation
Goal: Create the main trainer class and implement the core Reptile meta-learning algorithm.
AC 1.1: Scaffolding ReptileTrainer<T> (3 points)
Requirement: Create the main class structure for the trainer.
- Create a new folder:
src/Models/Meta/ - Create a new file:
src/Models/Meta/ReptileTrainer.cs. - Define a
public class ReptileTrainer<T>. - The constructor must accept:
IModel<T> metaModel: The initial model to be meta-trained.IOptimizer<T> metaOptimizer: The optimizer for the outer loop meta-updates.ILossFunction<T> lossFunction: The loss function to be used for the inner loop training.int innerLoopSteps: The number of training steps to perform on each task.T innerLoopStepSize: The learning rate for the inner loop optimizer.
AC 1.2: Implement the Train Method (8 points)
Requirement: Implement the main training method containing the Reptile algorithm's nested loop structure.
- Define a public method:
public void Train(EpisodicDataLoader<T> dataLoader, int metaIterations). - Outer Loop: Implement the meta-training loop:
for (int i = 0; i < metaIterations; i++)
- Inside the Outer Loop:
- 1. Task Sampling: Get a new task from the data loader:
var task = dataLoader.GetNextTask();This task should contain a support set and a query set. - 2. Clone Model: Create a deep copy of the
metaModel's weights. ThistaskModelwill be trained on the sampled task. Ensure the weights are completely independent. - 3. Inner Loop Optimizer: Instantiate a new optimizer for the inner loop (e.g., a new
Adamoptimizer) using thetaskModel's parameters and theinnerLoopStepSize. - 4. Inner Loop Training: Implement the inner loop:
for (int j = 0; j < innerLoopSteps; j++)- Inside this loop, perform a standard training step on the
taskModelusing a batch from the task's support set.
- 5. Meta-Update:
- Get the final weights from the
taskModelafter the inner loop is complete. - Get the original weights from the
metaModel. - Calculate the weight difference:
weight_delta = task_model_weights - meta_model_weights. - Use the
metaOptimizerto update themetaModel's weights based on this delta. The conceptual update ismeta_weights += meta_learning_rate * weight_delta.
- Get the final weights from the
- 1. Task Sampling: Get a new task from the data loader:
Phase 2: Validation and Testing
Goal: Verify that the Reptile implementation is correct and improves model performance on few-shot tasks.
AC 2.1: Unit Tests (5 points)
Requirement: Create unit tests to verify the core algorithm logic.
- Create a new test file:
tests/UnitTests/Meta/ReptileTrainerTests.cs. - Create a test that initializes the
ReptileTrainerwith a simple mock model. - Run the
Trainmethod for a single meta-iteration (metaIterations = 1). - Assert that the
metaModel's weights after the iteration are no longer equal to their initial values but have moved in the direction of thetaskModel's weights.
AC 2.2: Integration Test (8 points)
Requirement: Create an integration test on a synthetic problem to prove meta-learning is occurring.
- Synthetic Data: Create a synthetic data problem, such as few-shot sine wave regression, where each task is to fit a sine wave with a different amplitude and phase.
- Test Setup:
- Instantiate a simple neural network as the
metaModel. - Instantiate the
ReptileTrainer. - Create an
EpisodicDataLoaderfor the synthetic sine wave problem.
- Instantiate a simple neural network as the
- Test Logic:
- Step 1 (Pre-Meta-Training): Evaluate the initial
metaModelon a set of unseen test tasks. Store the average loss. - Step 2 (Meta-Training): Run the
ReptileTrainer.Train()method for a significant number of meta-iterations (e.g., 50). - Step 3 (Post-Meta-Training): Evaluate the now-trained
metaModelon the same set of unseen test tasks. - Assert that the average loss after meta-training is significantly lower than the average loss before meta-training.
- Step 1 (Pre-Meta-Training): Evaluate the initial
Definition of Done
- All checklist items are complete.
- The
ReptileTraineris implemented and integrated with the episodic data loader. - Unit tests verify the weight update logic.
- The integration test demonstrates that the trainer can successfully meta-learn a solution to a synthetic few-shot problem.
- All new code meets the project's >= 90% test coverage requirement.
⚠️ CRITICAL ARCHITECTURAL REQUIREMENTS
Before implementing this user story, you MUST review:
- 📋 Full Requirements:
.github/USER_STORY_ARCHITECTURAL_REQUIREMENTS.md - 📐 Project Rules:
.github/PROJECT_RULES.md
Mandatory Implementation Checklist
1. INumericOperations Usage (CRITICAL)
- Include
protected static readonly INumericOperations<T> NumOps = MathHelper.GetNumericOperations<T>();in base class - NEVER hardcode
double,float, or specific numeric types - use genericT - NEVER use
default(T)- useNumOps.Zeroinstead - Use
NumOps.Zero,NumOps.One,NumOps.FromDouble()for values - Use
NumOps.Add(),NumOps.Multiply(), etc. for arithmetic - Use
NumOps.LessThan(),NumOps.GreaterThan(), etc. for comparisons
2. Inheritance Pattern (REQUIRED)
- Create
I{FeatureName}.csinsrc/Interfaces/(root level, NOT subfolders) - Create
{FeatureName}Base.csinsrc/{FeatureArea}/inheriting from interface - Create concrete classes inheriting from Base class (NOT directly from interface)
3. PredictionModelBuilder Integration (REQUIRED)
- Add private field:
private I{FeatureName}<T>? _{featureName};toPredictionModelBuilder.cs - Add Configure method taking ONLY interface (no parameters):
public IPredictionModelBuilder<T, TInput, TOutput> Configure{FeatureName}(I{FeatureName}<T> {featureName}) { _{featureName} = {featureName}; return this; }
- Use feature in
Build()with default:var {featureName} = _{featureName} ?? new Default{FeatureName}<T>(); - Verify feature is ACTUALLY USED in execution flow
4. Beginner-Friendly Defaults (REQUIRED)
- Constructor parameters with defaults from research/industry standards
- Document WHY each default was chosen (cite papers/standards)
- Validate parameters and throw
ArgumentExceptionfor invalid values
5. Property Initialization (CRITICAL)
- NEVER use
default!operator - String properties:
= string.Empty; - Collections:
= new List<T>();or= new Vector<T>(0); - Numeric properties: appropriate default or
NumOps.Zero
6. Class Organization (REQUIRED)
- One class/enum/interface per file
- ALL interfaces in
src/Interfaces/(root level) - Namespace mirrors folder structure (e.g.,
src/Regularization/→namespace AiDotNet.Regularization)
7. Documentation (REQUIRED)
- XML documentation for all public members
-
<b>For Beginners:</b>sections with analogies and examples - Document all
<param>,<returns>,<exception>tags - Explain default value choices
8. Testing (REQUIRED)
- Minimum 80% code coverage
- Test with multiple numeric types (double, float)
- Test default values are applied correctly
- Test edge cases and exceptions
- Integration tests for PredictionModelBuilder usage
See full details: .github/USER_STORY_ARCHITECTURAL_REQUIREMENTS.md