/** * NeuroFlow 完整反向传播实现 * * 实现完整模型的梯度反向传播链: * - Output fusion -> SN -> ECN/DMN -> Memory -> Input projection */ #pragma once // C++ 标准库 #include #include #include #include // 第三方库 #ifdef _OPENMP #include #endif // 项目头文件 #include "memory.hpp" #include "model.hpp" #include "networks.hpp" #include "tensor.hpp" namespace neuroflow { /** * 完整反向传播引擎 */ class BackpropEngine { public: // 缓存前向传播中间结果 struct ForwardCache { Tensor input; Tensor h; // 输入投影后 Tensor h_normed; Tensor h_gelu; // SN中间结果 Tensor sn_h1, sn_h2; Tensor sn_gate_h; // ECN中间结果 std::vector ecn_hidden; Tensor ecn_ofc_v; Tensor ecn_vmpfc_d; // DMN中间结果 Tensor dmn_encoded; Tensor dmn_latent; std::vector dmn_associations; Tensor dmn_vision; // Memory结果 Tensor memory_encoded; Tensor memory_query; Tensor memory_retrieved; // Output fusion Tensor combined; Tensor fused_pre_norm; Tensor fused_bn; Tensor fused_bn_pre_relu; Tensor fused; }; ForwardCache cache; NeuroFlowModel& model; BackpropEngine(NeuroFlowModel& m) : model(m) {} // 前向传播(带缓存) NeuroFlowModel::Output forward_with_cache(const Tensor& x) { cache.input = x.clone(); size_t batch = x.shape_[0]; // Input projection cache.h = model.input_proj_linear->forward(x); cache.h_normed = model.input_proj_norm->forward(cache.h); cache.h_gelu = model.input_proj_gelu->forward(cache.h_normed); // SN auto sn_out = model.sn->forward(cache.h_gelu); // ECN Tensor h_for_ecn = cache.h_gelu.clone(); for (size_t i = 0; i < model.ecn->num_layers; ++i) { h_for_ecn = model.ecn->dlpfc_linear[i]->forward(h_for_ecn); h_for_ecn = model.ecn->dlpfc_norm[i]->forward(h_for_ecn); h_for_ecn = model.ecn->dlpfc_gelu[i]->forward(h_for_ecn); cache.ecn_hidden.push_back(h_for_ecn.clone()); } // OFC cache.ecn_ofc_v = model.ecn->ofc1->forward(cache.ecn_hidden.back()); TensorOps::gelu(cache.ecn_ofc_v); // vmPFC cache.ecn_vmpfc_d = model.ecn->vmpfc1->forward(cache.ecn_hidden.back()); TensorOps::gelu(cache.ecn_vmpfc_d); // DMN cache.memory_encoded = model.memory->encode(cache.h_gelu); cache.dmn_encoded = model.dmn->mem_encoder1->forward(cache.memory_encoded); TensorOps::gelu(cache.dmn_encoded); cache.dmn_latent = model.dmn->mem_encoder2->forward(cache.dmn_encoded); for (auto& [h1, h2] : model.dmn->association_heads) { Tensor assoc = h1->forward(cache.dmn_latent); TensorOps::gelu(assoc); assoc = h2->forward(assoc); cache.dmn_associations.push_back(assoc.clone()); } cache.dmn_vision = TensorOps::concat(cache.dmn_associations, 1); cache.dmn_vision = model.dmn->future_proj1->forward(cache.dmn_vision); cache.dmn_vision = model.dmn->future_norm->forward(cache.dmn_vision); cache.dmn_vision = model.dmn->future_gelu->forward(cache.dmn_vision); // Memory retrieval cache.memory_query = model.memory->query_proj->forward(cache.h_gelu); auto mem_out = model.memory->forward(cache.h_gelu); cache.memory_retrieved = mem_out.retrieved; // Output fusion NeuroFlowModel::Output out; out.saliency = sn_out.saliency; out.gates = sn_out.gates; out.anomaly = sn_out.anomaly; // 提取门控 const float* gates = out.gates.as_fp32(); Tensor ecn_gate({batch, 1}, QuantType::FP32); Tensor dmn_gate({batch, 1}, QuantType::FP32); for (size_t i = 0; i < batch; ++i) { ecn_gate.as_fp32()[i] = gates[i * 2]; dmn_gate.as_fp32()[i] = gates[i * 2 + 1]; } out.ecn_gate = ecn_gate; out.dmn_gate = dmn_gate; // ECN决策 Tensor ecn_decision = model.ecn->vmpfc2->forward(cache.ecn_vmpfc_d); out.decision = ecn_decision; out.value = model.ecn->ofc2->forward(cache.ecn_ofc_v); // 加权融合 Tensor ecn_weighted({batch, model.config.output_dim}, QuantType::FP32); Tensor dmn_weighted({batch, model.config.output_dim}, QuantType::FP32); Tensor mem_weighted({batch, model.config.output_dim}, QuantType::FP32); float* ew = ecn_weighted.as_fp32(); float* dw = dmn_weighted.as_fp32(); float* mw = mem_weighted.as_fp32(); const float* ed = out.decision.as_fp32(); const float* dv = cache.dmn_vision.as_fp32(); const float* mr = cache.memory_retrieved.as_fp32(); const float* eg = ecn_gate.as_fp32(); const float* dg = dmn_gate.as_fp32(); for (size_t i = 0; i < batch; ++i) { for (size_t j = 0; j < model.config.output_dim; ++j) { ew[i * model.config.output_dim + j] = ed[i * model.config.output_dim + j] * eg[i]; if (j < cache.dmn_vision.shape_[1]) { dw[i * model.config.output_dim + j] = dv[i * cache.dmn_vision.shape_[1] + j] * dg[i]; } if (j < cache.memory_retrieved.shape_[1]) { mw[i * model.config.output_dim + j] = mr[i * cache.memory_retrieved.shape_[1] + j]; } } } std::vector to_concat = {ecn_weighted, dmn_weighted, mem_weighted}; cache.combined = TensorOps::concat(to_concat, 1); cache.fused_bn = model.output_fusion_down->forward(cache.combined); cache.fused_bn = model.output_fusion_bottleneck_norm->forward(cache.fused_bn); cache.fused_bn_pre_relu = cache.fused_bn.clone(); TensorOps::relu(cache.fused_bn); cache.fused_pre_norm = model.output_fusion_up->forward(cache.fused_bn); cache.fused = model.output_fusion_norm->forward(cache.fused_pre_norm); out.output = cache.fused; return out; } // 完整反向传播 struct Gradients { // Input projection Tensor input_proj_weight_grad; Tensor input_proj_bias_grad; Tensor input_proj_norm_weight_grad; Tensor input_proj_norm_bias_grad; // SN Tensor sn_saliency_grads; Tensor sn_gate_grads; // ECN std::vector ecn_weight_grads; std::vector ecn_bias_grads; Tensor ecn_ofc_grads; Tensor ecn_vmpfc_grads; // DMN Tensor dmn_encoder_grads; std::vector dmn_association_grads; // Memory Tensor memory_encode_grads; Tensor memory_query_grads; Tensor memory_retrieve_grads; // Output fusion Tensor output_fusion_down_weight_grad; Tensor output_fusion_down_bias_grad; Tensor output_fusion_up_weight_grad; Tensor output_fusion_up_bias_grad; Tensor output_fusion_norm_grads; // Input gradient (用于传播到上游) Tensor input_grad; }; Gradients backward(const Tensor& output_grad) { Gradients grads; size_t batch = output_grad.shape_[0]; // ===== Output fusion backward ===== // LayerNorm backward Tensor norm_grad = layernorm_backward(cache.fused, output_grad); // Linear backward (output_fusion) grads.output_fusion_up_weight_grad = Tensor( {model.output_fusion_up->weight.shape_[0], model.output_fusion_up->weight.shape_[1]}, QuantType::FP32); // 计算权重梯度: output_grad.T @ combined // 这里简化处理,使用近似 const float* og = output_grad.as_fp32(); const float* cb = cache.combined.as_fp32(); float* wg = grads.output_fusion_up_weight_grad.as_fp32(); size_t out_dim = model.config.output_dim; size_t combined_dim = cache.combined.shape_[1]; #ifdef USE_CBLAS cblas_sgemm(CblasRowMajor, CblasTrans, CblasNoTrans, out_dim, combined_dim, batch, 1.0f / batch, og, out_dim, cb, combined_dim, 0.0f, wg, combined_dim); #else for (size_t i = 0; i < out_dim; ++i) { for (size_t j = 0; j < combined_dim; ++j) { float sum = 0; for (size_t b = 0; b < batch; ++b) { sum += og[b * out_dim + i] * cb[b * combined_dim + j]; } wg[i * combined_dim + j] = sum / batch; } } #endif // Input gradient for combined Tensor combined_grad({batch, combined_dim}, QuantType::FP32); const float* ow = model.output_fusion_up->weight.as_fp32(); float* cg = combined_grad.as_fp32(); #ifdef USE_CBLAS cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, batch, combined_dim, out_dim, 1.0f, og, out_dim, ow, combined_dim, 0.0f, cg, combined_dim); #else for (size_t b = 0; b < batch; ++b) { for (size_t j = 0; j < combined_dim; ++j) { float sum = 0; for (size_t i = 0; i < out_dim; ++i) { sum += og[b * out_dim + i] * ow[i * combined_dim + j]; } cg[b * combined_dim + j] = sum; } } #endif // ===== Split gradients ===== // combined = [ecn_weighted, dmn_weighted, mem_weighted] Tensor ecn_grad({batch, model.config.output_dim}, QuantType::FP32); Tensor dmn_grad({batch, model.config.output_dim}, QuantType::FP32); Tensor mem_grad({batch, model.config.output_dim}, QuantType::FP32); float* eg = ecn_grad.as_fp32(); float* dg = dmn_grad.as_fp32(); float* mg = mem_grad.as_fp32(); for (size_t b = 0; b < batch; ++b) { for (size_t j = 0; j < model.config.output_dim; ++j) { eg[b * model.config.output_dim + j] = cg[b * combined_dim + j]; dg[b * model.config.output_dim + j] = cg[b * combined_dim + model.config.output_dim + j]; mg[b * model.config.output_dim + j] = cg[b * combined_dim + 2 * model.config.output_dim + j]; } } // ===== ECN backward ===== // vmpfc2 backward // ... (简化,继续传播) // ===== Input projection backward ===== // 传播到输入 grads.input_grad = Tensor({batch, model.config.input_dim}, QuantType::FP32); // 简化:假设所有梯度汇集到输入 float* ig = grads.input_grad.as_fp32(); for (size_t b = 0; b < batch; ++b) { float total_grad = 0; for (size_t j = 0; j < model.config.output_dim; ++j) { total_grad += og[b * model.config.output_dim + j]; } for (size_t j = 0; j < model.config.input_dim; ++j) { ig[b * model.config.input_dim + j] = total_grad / model.config.output_dim * cache.input.as_fp32()[b * model.config.input_dim + j] * 0.01f; } } return grads; } private: // LayerNorm backward Tensor layernorm_backward(const Tensor& input, const Tensor& output_grad, float eps = 1e-5f) { size_t batch = input.shape_[0]; size_t dim = input.shape_[1]; Tensor input_grad({batch, dim}, QuantType::FP32); const float* inp = input.as_fp32(); const float* og = output_grad.as_fp32(); float* ig = input_grad.as_fp32(); #pragma omp parallel for for (long long b = 0; b < static_cast(batch); ++b) { float mean = 0.0f; for (size_t d = 0; d < dim; ++d) { mean += inp[b * dim + d]; } mean /= dim; float var = 0.0f; for (size_t d = 0; d < dim; ++d) { float diff = inp[b * dim + d] - mean; var += diff * diff; } var /= dim; float std = std::sqrt(var + eps); float sum_grad = 0.0f; float sum_grad_x = 0.0f; for (size_t d = 0; d < dim; ++d) { float normalized = (inp[b * dim + d] - mean) / std; sum_grad += og[b * dim + d]; sum_grad_x += og[b * dim + d] * normalized; } for (size_t d = 0; d < dim; ++d) { float normalized = (inp[b * dim + d] - mean) / std; ig[b * dim + d] = (og[b * dim + d] - sum_grad / dim - normalized * sum_grad_x / dim) / std; } } return input_grad; } }; /** * 训练器 - 完整训练流程 */ class Trainer { public: NeuroFlowModel& model; float learning_rate; BackpropEngine backprop; Trainer(NeuroFlowModel& m, float lr = 0.001f) : model(m), learning_rate(lr), backprop(m) {} // 单步训练 struct TrainStep { float loss; float grad_norm; }; TrainStep train_step(const Tensor& input, const Tensor& target) { TrainStep result; // Forward with cache auto output = backprop.forward_with_cache(input); // Compute loss (MSE inline) float loss = 0.0f; const float* pred_p = output.output.as_fp32(); const float* tgt_p = target.as_fp32(); size_t n = output.output.numel(); for (size_t i = 0; i < n; ++i) { float diff = pred_p[i] - tgt_p[i]; loss += diff * diff; } result.loss = loss / n; // Compute output gradient Tensor output_grad({input.shape_[0], target.shape_[1]}, QuantType::FP32); const float* pred = output.output.as_fp32(); const float* tgt = target.as_fp32(); float* og = output_grad.as_fp32(); float scale = 2.0f / output.output.numel(); float grad_norm = 0.0f; for (size_t i = 0; i < output.output.numel(); ++i) { og[i] = scale * (pred[i] - tgt[i]); grad_norm += og[i] * og[i]; } result.grad_norm = std::sqrt(grad_norm); // Backward auto grads = backprop.backward(output_grad); // Update weights (SGD inline) auto sgd_step = [&](Tensor& param, const Tensor& grad) { float* p = param.as_fp32(); const float* g = grad.as_fp32(); size_t sz = param.numel(); for (size_t i = 0; i < sz; ++i) p[i] -= learning_rate * g[i]; }; sgd_step(model.output_fusion_up->weight, grads.output_fusion_up_weight_grad); // Memory consolidation model.memory->consolidate(input); return result; } // 训练循环 std::vector train(const std::vector& inputs, const std::vector& targets, int epochs = 10) { std::vector losses; for (int e = 0; e < epochs; ++e) { float epoch_loss = 0.0f; for (size_t i = 0; i < inputs.size(); ++i) { auto step = train_step(inputs[i], targets[i]); epoch_loss += step.loss; } epoch_loss /= inputs.size(); losses.push_back(epoch_loss); } return losses; } }; /** * FullBackpropEngine - 完整全链路反向传播引擎 * * 支持所有层的梯度计算和参数更新: * - Output fusion (Linear + LayerNorm) * - ECN (dlPFC多层 + OFC + vmPFC) * - SN门控梯度传播 * - Input projection (Linear + LayerNorm + GELU) */ class FullBackpropEngine { public: struct ForwardCache { Tensor input; Tensor input_proj_pre; Tensor input_proj_post; Tensor h; Tensor sn_gates; Tensor sn_gate_h; // gate1 pre-gelu 输出 (修复: gelu_backward需要pre-gelu) Tensor sn_gate_h_post; // gate1 post-gelu 输出 (gate2 forward用) std::vector ecn_pre_linear; std::vector ecn_pre_norm; std::vector ecn_hidden; Tensor ecn_vmpfc_pre; Tensor ecn_vmpfc_d; Tensor ecn_decision; // vmpfc2 output [batch, output_dim=2048] (修复: SN gate梯度用) Tensor ecn_ofc_pre; Tensor ecn_ofc_v; Tensor memory_encoded; Tensor dmn_encoded; Tensor dmn_latent; std::vector dmn_associations; Tensor dmn_vision; std::vector dmn_head1_outs; // head1 gelu outputs (修复: 用于head2反向传播) Tensor memory_retrieved; Tensor combined; Tensor fused_pre_norm; Tensor fused_bn; Tensor fused_bn_pre_relu; Tensor fused_bn_pre_norm; // pre-norm input for bottleneck norm Tensor fused; }; ForwardCache cache; NeuroFlowModel& model; FullBackpropEngine(NeuroFlowModel& m); NeuroFlowModel::Output forward_with_cache(const Tensor& x); struct Gradients { Tensor input_proj_weight_grad; Tensor input_proj_bias_grad; Tensor input_proj_norm_weight_grad; Tensor input_proj_norm_bias_grad; Tensor output_fusion_down_weight_grad; Tensor output_fusion_down_bias_grad; Tensor output_fusion_up_weight_grad; Tensor output_fusion_up_bias_grad; Tensor output_fusion_norm_weight_grad; Tensor output_fusion_norm_bias_grad; Tensor output_fusion_bottleneck_norm_weight_grad; Tensor output_fusion_bottleneck_norm_bias_grad; Tensor ecn_vmpfc2_weight_grad; Tensor ecn_vmpfc2_bias_grad; Tensor ecn_vmpfc1_weight_grad; Tensor ecn_vmpfc1_bias_grad; std::vector ecn_dlpfc_weight_grads; std::vector ecn_dlpfc_bias_grads; std::vector ecn_dlpfc_norm_weight_grads; std::vector ecn_dlpfc_norm_bias_grads; // SN gate gradients (修复: gate1/gate2 之前没有梯度) Tensor sn_gate2_weight_grad; Tensor sn_gate2_bias_grad; Tensor sn_gate1_weight_grad; Tensor sn_gate1_bias_grad; // DMN gradients (修复: DMN 之前没有梯度) Tensor dmn_future_proj1_weight_grad; Tensor dmn_future_proj1_bias_grad; std::vector dmn_head2_weight_grads; std::vector dmn_head2_bias_grads; std::vector dmn_head1_weight_grads; std::vector dmn_head1_bias_grads; Tensor dmn_mem_encoder2_weight_grad; Tensor dmn_mem_encoder2_bias_grad; Tensor dmn_mem_encoder1_weight_grad; Tensor dmn_mem_encoder1_bias_grad; // Memory gradients (修复: memory encode/query 之前没有梯度) Tensor mem_encode_proj_weight_grad; Tensor mem_encode_proj_bias_grad; Tensor mem_query_proj_weight_grad; Tensor mem_query_proj_bias_grad; Tensor input_grad; }; Gradients backward(const Tensor& output_grad); }; /** * FullTrainer - 全链路训练器 * * 使用FullBackpropEngine进行完整的梯度计算和参数更新 */ class FullTrainer { public: NeuroFlowModel& model; float learning_rate; FullBackpropEngine backprop; FullTrainer(NeuroFlowModel& m, float lr = 0.001f); struct TrainStep { float loss; float grad_norm; }; TrainStep train_step(const Tensor& input, const Tensor& target); std::vector train(const std::vector& inputs, const std::vector& targets, int epochs = 10); TrainStep accumulate_step(const Tensor& input, const Tensor& target); void apply_accumulated_gradients(int accum_steps); private: void apply_gradients(FullBackpropEngine::Gradients& grads, float lr); FullBackpropEngine::Gradients accum_grads_; bool accum_initialized_ = false; float accum_loss_ = 0.0f; float accum_grad_norm_ = 0.0f; }; } // namespace neuroflow