Spaces:
Paused
Paused
Download src/research/stdp_pair_timing.py from ThomasHeisig/Brain-5D-Space: direct link, hf CLI and curl.
- Browser
- Download file 3 kB
-
https://huggingface.co/spaces/ThomasHeisig/Brain-5D-Space/resolve/main/src/research/stdp_pair_timing.py
- Command line
-
hf download hf://spaces/ThomasHeisig/Brain-5D-Space/src/research/stdp_pair_timing.py
-
curl -L -o stdp_pair_timing.py https://huggingface.co/spaces/ThomasHeisig/Brain-5D-Space/resolve/main/src/research/stdp_pair_timing.py
3 kB
| """Deterministic laboratory protocol for pair-based STDP timing curves.""" | |
| from __future__ import annotations | |
| from statistics import fmean | |
| from typing import Any | |
| from src.learning.stdp_plugin import STDPParameters, STDPSynapse | |
| PROTOCOL_ID = "stdp_pair_timing_v1" | |
| DELTA_T_MS = (-50, -20, -10, -5, -1, 0, 1, 5, 10, 20, 50) | |
| REPLICATIONS = 10 | |
| INITIAL_WEIGHT = 0.5 | |
| PARAMETERS = STDPParameters( | |
| a_plus=0.1, | |
| a_minus=0.12, | |
| tau_plus=20.0, | |
| tau_minus=20.0, | |
| ) | |
| def run_pair_timing_protocol() -> dict[str, Any]: | |
| """Measure the STDP timing curve with fixed, isolated conditions. | |
| The protocol does not access the Brain-5D runtime, filesystem, network, | |
| or any language model. Each replication receives a new synapse and the | |
| same pre/post timing, making the measurement deterministic and auditable. | |
| """ | |
| rows: list[dict[str, float | int]] = [] | |
| for delta_t in DELTA_T_MS: | |
| changes = [_measure_delta_weight(delta_t) for _ in range(REPLICATIONS)] | |
| rows.append( | |
| { | |
| "delta_t_ms": delta_t, | |
| "repeated_evaluations": REPLICATIONS, | |
| "independent_runs": 0, | |
| "mean_delta_weight": fmean(changes), | |
| "min_delta_weight": min(changes), | |
| "max_delta_weight": max(changes), | |
| } | |
| ) | |
| positive = [row["mean_delta_weight"] for row in rows if row["delta_t_ms"] > 0] | |
| negative = [row["mean_delta_weight"] for row in rows if row["delta_t_ms"] < 0] | |
| zero = next(row["mean_delta_weight"] for row in rows if row["delta_t_ms"] == 0) | |
| supported = ( | |
| all(change > 0 for change in positive) | |
| and all(change < 0 for change in negative) | |
| and zero == 0.0 | |
| ) | |
| return { | |
| "protocol": PROTOCOL_ID, | |
| "seed": 42, | |
| "conditions": { | |
| "initial_weight": INITIAL_WEIGHT, | |
| "parameters": PARAMETERS.to_dict(), | |
| "repeated_evaluations_per_condition": REPLICATIONS, | |
| "independent_runs_per_condition": 0, | |
| }, | |
| "measurements": rows, | |
| "summary": { | |
| "total_replications": len(DELTA_T_MS) * REPLICATIONS, | |
| "conditions": len(DELTA_T_MS), | |
| "repeated_evaluations": len(DELTA_T_MS) * REPLICATIONS, | |
| "independent_runs": 0, | |
| "mean_ltp": fmean(positive), | |
| "mean_ltd": fmean(negative), | |
| "zero_delta_weight": zero, | |
| "hypothesis_supported": supported, | |
| "deterministic_identity": all( | |
| row["min_delta_weight"] == row["max_delta_weight"] for row in rows | |
| ), | |
| }, | |
| } | |
| def _measure_delta_weight(delta_t_ms: int) -> float: | |
| synapse = STDPSynapse.from_parameters(INITIAL_WEIGHT, PARAMETERS) | |
| reference_tick = 100 | |
| if delta_t_ms < 0: | |
| synapse.post_spike(reference_tick + delta_t_ms) | |
| return synapse.pre_spike(reference_tick) | |
| synapse.pre_spike(reference_tick) | |
| return synapse.post_spike(reference_tick + delta_t_ms) | |