minseok
π Implement 3 Frontier Theories: Karl Friston FEP Predictive Coding, Astrocyte Tripartite Glia, Ryu-Takayanagi Wormhole Calibration Filter
1bfe9c1 | // π [BioPhys 6.0] Karl Friston μμ μλμ§ μ리 λ° μμΈ‘ λΆνΈν μμ§ (src/free_energy_engine.rs) | |
| // μμ ν(Backpropagation) μμ΄ λ³λΆ μμ μλμ§(Variational Free Energy)λ₯Ό κ΅μμ μΌλ‘ μ΅μννμ¬ μ€μ°¨ μ€νμ΄ν¬λ§μ μ ννλ μ κ²½λ§ μμ§ | |
| use std::time::Instant; | |
| /// π¬ μμ μλμ§ μμ§ μ€μ νλΌλ―Έν° (Config) | |
| pub struct FreeEnergyConfig { | |
| pub num_layers: usize, | |
| pub hidden_dim: usize, | |
| pub prediction_precision: f32, // κ°κ° μ λ°λ (Precision Weight, κΈ°λ³Έ: 1.25) | |
| pub learning_rate: f32, // κ΅μ μ μλ₯ (κΈ°λ³Έ: 0.05) | |
| pub complexity_penalty: f32, // 볡μ‘λ νλν° (KL Divergence κ³μ, κΈ°λ³Έ: 0.01) | |
| } | |
| impl Default for FreeEnergyConfig { | |
| fn default() -> Self { | |
| Self { | |
| num_layers: 4, | |
| hidden_dim: 256, | |
| prediction_precision: 1.25, | |
| learning_rate: 0.05, | |
| complexity_penalty: 0.01, | |
| } | |
| } | |
| } | |
| /// π§ μμΈ‘ λΆνΈν κ³μΈ΅ (Predictive Coding Layer) | |
| pub struct PredictiveCodingLayer { | |
| pub layer_id: usize, | |
| pub representation_mu: Vec<f32>, // λ΄λΆ μν νμ (Internal States) | |
| pub prediction_error: Vec<f32>, // μμΈ‘ μ€μ°¨ μ€νμ΄ν¬ (Epsilon = Input - Mu) | |
| pub generative_weights: Vec<f32>, // νν₯μ μμΈ‘ μμ± κ°μ€μΉ | |
| } | |
| impl PredictiveCodingLayer { | |
| pub fn new(layer_id: usize, dim: usize) -> Self { | |
| Self { | |
| layer_id, | |
| representation_mu: vec![0.0f32; dim], | |
| prediction_error: vec![0.0f32; dim], | |
| generative_weights: (0..dim).map(|i| (i as f32 * 0.1).cos() * 0.5).collect(), | |
| } | |
| } | |
| } | |
| /// ποΈ μμ μλμ§ λ₯λμ μΆλ‘ μμ§ (Main Engine Struct) | |
| pub struct FreeEnergyEngine { | |
| pub config: FreeEnergyConfig, | |
| pub layers: Vec<PredictiveCodingLayer>, | |
| pub current_free_energy: f32, | |
| pub total_surprises_resolved: usize, | |
| } | |
| impl FreeEnergyEngine { | |
| pub fn new(config: FreeEnergyConfig) -> Self { | |
| let layers = (0..config.num_layers) | |
| .map(|i| PredictiveCodingLayer::new(i, config.hidden_dim)) | |
| .collect(); | |
| Self { | |
| config, | |
| layers, | |
| current_free_energy: 0.0, | |
| total_surprises_resolved: 0, | |
| } | |
| } | |
| /// [μμ μλμ§ μ΅μν μΆλ‘ ]: μ λ ₯ μ νΈμ λν΄ μν₯μ μ€μ°¨μ νν₯μ μμΈ‘μ λ°λ³΅ μ λ ¬ | |
| pub fn infer_and_minimize(&mut self, sensory_input: &[f32]) -> (f32, u128) { | |
| let t_start = Instant::now(); | |
| let dim = self.config.hidden_dim.min(sensory_input.len()); | |
| let mut total_accuracy_error = 0.0f32; | |
| let mut total_complexity_cost = 0.0f32; | |
| // 1. μ΅νμ κ°κ° κ³μΈ΅ (Layer 0) μ€μ°¨ κ³μ° | |
| for i in 0..dim { | |
| let pred = self.layers[0].representation_mu[i] * self.layers[0].generative_weights[i]; | |
| let error = sensory_input[i] - pred; | |
| self.layers[0].prediction_error[i] = error; | |
| total_accuracy_error += self.config.prediction_precision * error * error; | |
| // κ΅μμ μν κ°±μ : dMu = eta * (Precision * Error - Complexity) | |
| let d_mu = self.config.learning_rate * (self.config.prediction_precision * error - self.config.complexity_penalty * self.layers[0].representation_mu[i]); | |
| self.layers[0].representation_mu[i] += d_mu; | |
| total_complexity_cost += self.config.complexity_penalty * self.layers[0].representation_mu[i].powi(2); | |
| } | |
| // 2. κ³μΈ΅μ μμ κ³μΈ΅ μ ν (Hierarchical Predictive Propagation) | |
| for l in 1..self.config.num_layers { | |
| let prev_mu = self.layers[l - 1].representation_mu.clone(); | |
| for i in 0..dim { | |
| let top_pred = self.layers[l].representation_mu[i] * self.layers[l].generative_weights[i]; | |
| let error = prev_mu[i] - top_pred; | |
| self.layers[l].prediction_error[i] = error; | |
| total_accuracy_error += self.config.prediction_precision * error * error; | |
| let d_mu = self.config.learning_rate * (self.config.prediction_precision * error - self.config.complexity_penalty * self.layers[l].representation_mu[i]); | |
| self.layers[l].representation_mu[i] += d_mu; | |
| total_complexity_cost += self.config.complexity_penalty * self.layers[l].representation_mu[i].powi(2); | |
| } | |
| } | |
| // 3. λ³λΆ μμ μλμ§ F = Accuracy Error + Complexity Cost | |
| self.current_free_energy = total_accuracy_error + total_complexity_cost; | |
| self.total_surprises_resolved += 1; | |
| let latency_us = t_start.elapsed().as_micros(); | |
| (self.current_free_energy, latency_us) | |
| } | |
| /// [μ΅μμ μμΈ‘ νμ λ²‘ν° λ°ν] | |
| pub fn get_top_representation(&self) -> &[f32] { | |
| &self.layers[self.config.num_layers - 1].representation_mu | |
| } | |
| /// [μμ μλμ§ μν μμ½] | |
| pub fn telemetry_summary(&self) -> String { | |
| format!( | |
| "π§ [μμ μλμ§ FEP]: κ³μΈ΅ {}κ° | νμ¬ μμ μλμ§ F = {:.4} | ν΄κ²°λ λλ(Surprise) νμ: {}ν", | |
| self.config.num_layers, self.current_free_energy, self.total_surprises_resolved | |
| ) | |
| } | |
| } | |