{"record":{"id":"084fd271c7b327d7","repo":"ruvnet/RuView","slug":"both-teacher-and-student-features-must-be-extracte","errorCode":null,"errorMessage":"Both teacher and student features must be extracted first","messagePattern":"Both teacher and student features must be extracted first","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"references/script_7.py","lineNumber":65,"sourceCode":"        features['P4'] = np.random.rand(1, 256, 45, 80)\n        features['P5'] = np.random.rand(1, 256, 23, 40)\n        \n        self.student_features = features\n        return features\n    \n    def compute_mse_loss(self, teacher_feature, student_feature):\n        \"\"\"\n        Compute Mean Squared Error between teacher and student features\n        \"\"\"\n        return np.mean((teacher_feature - student_feature) ** 2)\n    \n    def compute_transfer_loss(self):\n        \"\"\"\n        Compute transfer learning loss as sum of MSE at different levels\n        L_tr = MSE(P2, P2*) + MSE(P3, P3*) + MSE(P4, P4*) + MSE(P5, P5*)\n        \"\"\"\n        if not self.teacher_features or not self.student_features:\n            raise ValueError(\"Both teacher and student features must be extracted first\")\n        \n        total_loss = 0.0\n        feature_losses = {}\n        \n        for level in ['P2', 'P3', 'P4', 'P5']:\n            teacher_feat = self.teacher_features[level]\n            student_feat = self.student_features[level]\n            \n            level_loss = self.compute_mse_loss(teacher_feat, student_feat)\n            feature_losses[level] = level_loss\n            total_loss += level_loss\n        \n        return total_loss, feature_losses\n    \n    def adapt_features(self, student_features, learning_rate=0.001):\n        \"\"\"\n        Adapt student features to be more similar to teacher features\n        \"\"\"","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/references/script_7.py#L47-L83","documentation":"TransferLearningSystem.compute_transfer_loss() sums MSE over FPN levels P2–P5 using self.teacher_features and self.student_features, which start as empty dicts in __init__ and are populated only by extract_teacher_features(image_input) and extract_student_features(wifi_features). If either dict is still empty the method raises ValueError before touching level keys.","triggerScenarios":"Calling compute_transfer_loss() (directly or via TrainingPipeline.train_step) before both extract_teacher_features() and extract_student_features() ran — e.g. a reordered training loop, hooks never firing, or an empty first batch.","commonSituations":"Refactoring the train step and dropping the extractor calls; conditional code paths that skip extraction on the first iteration; adapting the reference script into a real pipeline.","solutions":["Call tl.extract_teacher_features(image_data) and tl.extract_student_features(wifi_data) before compute_transfer_loss()","Guard the call site: only compute the loss when both dicts are non-empty","Verify dicts contain P2–P5 keys — extraction populates all four levels"],"exampleFix":"# before\ntl = TransferLearningSystem()\ntotal, per_level = tl.compute_transfer_loss()  # ValueError\n\n# after\ntl = TransferLearningSystem()\ntl.extract_teacher_features(image_data)\ntl.extract_student_features(wifi_data)\ntotal, per_level = tl.compute_transfer_loss()","handlingStrategy":"validation","validationCode":"FEATURE_LEVELS = {\"P2\", \"P3\", \"P4\", \"P5\"}\n\ndef transfer_loss_ready(tl) -> bool:\n    return (\n        bool(tl.teacher_features)\n        and bool(tl.student_features)\n        and FEATURE_LEVELS <= set(tl.teacher_features)\n        and FEATURE_LEVELS <= set(tl.student_features)\n    )\n\nassert transfer_loss_ready(tl), \"extract teacher and student features first\"","typeGuard":null,"tryCatchPattern":"try:\n    total, per_level = tl.compute_transfer_loss()\nexcept ValueError as e:\n    raise RuntimeError(\n        \"run extract_teacher_features() and extract_student_features() \"\n        \"before compute_transfer_loss()\"\n    ) from e","preventionTips":["Encapsulate extract → loss ordering in a single train_step function","Assert the P2–P5 keys exist in both feature dicts before computing loss","Fail fast on empty batches before reaching the loss computation"],"tags":["python","machine-learning","distillation","state","training-loop","validation"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}