# malecns-asteroids **초파리 뇌 지도 166,700 뉴런 전체를 실시간으로 돌려 Atari Asteroids를 플레이한다.**
같은 뇌 안의 **도피 회로**와 **추적 회로**를 각각 핸들에 걸어보고,
보는 사람이 버튼으로 **뉴런 2개**를 끄면 그 자리에서 행동이 무너지는 걸 본다. [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/) [![CUDA](https://img.shields.io/badge/CUDA-Triton-76B900.svg)](https://triton-lang.org/) [![Realtime 7.3x](https://img.shields.io/badge/realtime-7.3%C3%97-brightgreen.svg)](#성능) [![Double dissociation](https://img.shields.io/badge/double_dissociation-0%25_vs_−100%25-ff6b5e.svg)](#-같은-뉴런을-꺼도-모드에-따라-0-와-100--이중-해리) [English](README.en.md) · [빠른 시작](#빠른-시작) · [증거](#증거) · [한계](#정직한-한계)
--- ## 한 줄 요약 구글·Janelia가 공개한 **MaleCNS v1.0 커넥톰**(뉴런 166,700 / 시냅스 10,520,431)을 통째로 LIF 스파이킹 모델로 돌린다. 화면의 운석 위치를 **LC4 시신경 투사뉴런**에 시각 자극으로 넣고, **하행뉴런(DNp02 / DNp11)의 하류 운동 집단 507세포**에서 회피 방향을 읽어 조종한다. 전부 **실시간 60 fps** 안에서 돈다. 같은 뇌에 **모드가 둘** 있다. 두 모드 모두 166,700개를 전부 돌린다 — 모드는 *어느 판독을 핸들에 거느냐*지 뉴런을 끄는 게 아니다. | 모드 | 회로 | 행동 | |---|---|---| | **도망** | `LC4 → DNp02/DNp11 → VNC 하류 507세포` | 위협의 **반대쪽**으로 돈다 | | **쫓기** | `LC10a → AOTU019/025 → DNa02·13·15 → 하류 1,076세포` | 표적 **쪽으로** 돈다 | 쫓기 모드의 조향 부호는 우리가 정하지 않았다 — **AOTU025 동측 흥분 / AOTU019 대측 억제** 라는 배선에서 그대로 나온다. ## 왜 이 프로젝트인가 커넥톰으로 뭔가를 돌린 프로젝트는 많다. 대부분 *"그냥 `if` 문으로 하는 거랑 뭐가 다른데?"* 에 답하지 못한다. 16만 뉴런을 돌려서 나온 게 "적이 왼쪽이면 오른쪽으로"라면 그건 세 줄짜리 규칙이다. > **답은 제목이 아니라 토글 버튼이다. 규칙 기반 프로그램에는 끌 뉴런이 없다.** 그래서 이 저장소는 **"잘 돈다"가 아니라 "지목한 회로가 원인이다"** 를 증명하는 데 무게를 둔다. --- ## 증거 ### ① 뉴런 2개를 끄면 행동의 절반이 바뀐다 — 무작위 2,000개를 꺼도 안 바뀐다 온전한 뇌가 본 자극 시퀀스를 **테이프로 떠서 모든 조건에 문자 그대로 똑같이** 먹인다 (짝지은 재생). 궤적 발산이 섞이지 않는다. | 조작 | 세포 | 액션 일치율 | 추진 | 전후 채널 | |---|---:|---:|---:|---:| | 온전 | — | 100.0 % | 29.1 % | −0.146 | | **무작위 2세포** (시드 5개) | 2 | **100.00 ± 0.00 %** | 29.1 % | −0.146 | | 무작위 200세포 | 200 | 90.6 ± 4.7 % | 29.0 % | −0.146 | | **DNp11** | **2** | **56.9 %** | **0.0 %** | **+0.692** ← 부호 반전 | | **DNp02** | **2** | **69.7 %** | 52.2 % | −0.792 | | DNp04 / DNp01 (GF) | 2 | 83.1 % / 87.4 % | 31.0 % / 26.2 % | 거의 무변화 | 용량 반응은 단조(LC4 0/25/50/75/100 % → 100 → 83.3 → 77.4 → 66.0 → 0 %), 컨트롤러 파라미터 3조합에서 전부 유지. 테이프 2,108결정. ### ② 세포를 하나도 안 끄고 **배선만 섞어도** 무너진다 차수·부호·가중치를 **전부 보존**한 채 연결 상대만 치환한다. 무정보선은 90도. | 조건 | 회피 방위 오차 | 무정보까지의 거리 중 소실 | |---|---:|---:| | 온전 | **60.7°** | — | | LC4 투사 전체 섞기 | 99.2° | **131.3 %** | | LC4 → DN 만 | 81.9° | 72.4 % | | LC4 → DNp02/11 만 | 71.8° | 38.0 % | | **같은 규모를 다른 곳에서 섞기** | 60.3° | **−1.3 %** | | 시냅스 총량까지 맞춘 대조 / LPLC2→DN | 61.2° / 60.7° | **+1.7 % / 0 %** | ### ③ 같은 시작점에서 갈라지는 영상 ALE 시스템 상태 + OCAtari 내부 버퍼 6개 + RNG + 뇌 텐서 16개를 전부 복원해 **완전히 같은 지점**에서 다시 달린다. `온전` 두 번 주행이 **바이트 단위로 동일**하다. | 분기 | 추진 | 갈라지는 시점 | |---|---:|---:| | 온전 / **무작위 2세포** | 26.7 % | **끝까지 동일** | | **DNp11 2세포 끔** | **0.0 %** | 25프레임 (0.42초) | | DNp02 2세포 끔 | 50.4 % | 5프레임 | | **LC4 배선만 섞기** (세포는 전부 살아 있다) | 23.7 % | 9프레임 | ### ④ "파라미터가 많아서 되는 것 아니냐" — 아니다 같은 입력, 같은 파라미터 수의 MLP를 **무작위로 초기화**하면 무정보선에 붙는다. | | 평균 오차 | ±45° 안 | |---|---:|---:| | 무작위 MLP (은닉 11 / 96 / 256) | 88.5 / **81.9** / 88.0° | 26~28 % | | **초파리 뇌** | **47.6°** | **61.3 %** | > 정답을 주고 **지도학습**시킨 MLP는 같은 검증셋에서 43.6°로 초파리(56.2°)보다 낫다. > 이건 반박이 아니다 — **초파리는 정답을 한 번도 안 봤다.** 그대로 기록한다. ### ⑤ 같은 뉴런을 꺼도 모드에 따라 0 %와 −100 % — 이중 해리 한 방향 해리(끄면 망가진다)는 *"아무거나 꺼도 망가지는 것 아니냐"* 를 못 막는다. **같은 275세포를 껐는데 모드에 따라 결과가 갈리면** 그게 막힌다. | | 조준 (각폭 안) | 회피 (목숨당 생존) | |---|---:|---:| | **도망** 모드에서 LC10a 끄기 | **+0.0 %** (소수점까지 동일) | **+0.0 %** | | 도망 모드에서 DNp11 끄기 | +86.5 % | **−68.1 %** | | **쫓기** 모드에서 LC10a 끄기 | **−100.0 %** | +0.0 % | | 쫓기 모드에서 DNp11 끄기 | −38.0 % | +0.0 % | > ⚠️ 회피 열은 조건당 3판 × 3,000프레임이고 판당 죽음이 1~2회라 **해상도가 낮다.** 쫓기 모드 두 줄의 > +0.0 %는 '차이 없음'이라기보다 **'이 규모로는 못 가른다'** 에 가깝다. 도망 모드 LC10a 줄은 게임이 소수점까지 동일하게 진행돼서 0 %다. 조준도 실제로 돈다 — 가장 가까운 운석의 각거리가 **118.4° → 55.7°**. 음성 대조로 **같은 수(275)의 무작위 세포**를 끄면 조준이 거의 안 떨어진다 (8.3 ± 0.8 % vs 온전 9.6 %, 시드 5개). 그 275세포가 LC10a일 때만 **0 %** 가 된다. **그리고 세포를 하나도 안 끄고 배선만 섞어도 방향이 사라진다.** `LC10a → AOTU019/025` **335개 엣지**(전체의 0.0032 %)만 치환한다. 시드 10개: | 치환 비율 | 10 % | 25 % | 50 % | 75 % | 90 % | **100 %** | |---|---:|---:|---:|---:|---:|---:| | 방향 소실 | 1.5 % | 4.2 % | 12.5 % | 27.4 % | 32.0 % | **60.1 %** | | 신호 크기 유지 | 106 % | 98 % | 87 % | 72 % | 67 % | **51.9 %** | | 대조 (100 %, 시드 10개) | 방향 소실 | |---|---:| | 같은 개수의 **LC10a 다른 출력** | 1.5 % | | **도피 회로**(LC4→DN) 섞기 | 0.0 % | | 크기 맞춘 무작위 흥분성 엣지 | −0.1 % | **lesion은 신호가 0 %였다** — 그래서 "입력을 끊었을 뿐"이라는 반박이 가능했다. rewire는 **신호가 나오는데 방향이 없다.** 실제 게임에서도(시드 6개): | | 온전 | 배선 섞기 | 다른 출력 대조 (4시드) | |---|---:|---:|---:| | 각폭 안 | 9.6 % | **5.3 ± 0.5 %** (−44.6 %) | 8.6 ± 1.8 % (−9.7 %) | | 최근접 운석 각거리 | 55.7° | **80.2 ± 3.2°** | 66.8 ± 1.5° | | 신호 있는 결정 | 100 % | **100 %** | 100 % | > 🔴 이 결과는 **랩 주기에 극도로 민감하다.** y 주기를 1 px 틀리게(177) 잡았을 때는 > 같은 측정이 +11.2 %로 **효과가 사라졌다.** 폐루프라서 그렇다 — 자세한 것은 이슈 #56/#60. --- ## 성능 | 구성 | 프레임(66.7 ms)당 계산 | 실시간 대비 | |---|---:|---:| | post-major sparse CSR, dt=0.1 | 498 ms | 0.13× | | dt=0.2 + int32 + CUDA Graph 언롤 | 118.5 ms | 0.56× | | **pre-major 이벤트 구동 Triton + CUDA Graph** | **9.2 ms** | **7.3×** | | ↑ 게임·페이싱·송출까지 얹은 실전 루프 | 11~26 ms | 2.6~5.9× | 병목은 커널 런치가 아니라 **메모리 대역폭**이었다. post-major CSR은 누가 발화했든 매 스텝 전체 nnz를 읽는다(실측 236 GB/s = 사양의 82%). pre-major scatter는 **발화한 뉴런의 출력 엣지만** 읽는다 — 84.2 MB → 약 1 MB, 같은 GPU에서 13배. **30분 무중단 시험 통과**: fps 평균 60.0 / 뇌 평균 23.5 ms / VRAM +66 MB / 병변 동기 100 %. --- ## 빠른 시작 ### 요구 사항 - NVIDIA GPU (개발·측정은 RTX 4060 Ti 8 GB), CUDA - Python 3.11 - `ffmpeg` (분기 영상 합성에만 필요) - MaleCNS v1.0 커넥톰 데이터 — 별도 준비 (`graph/` 참조) ### 설치 ```bash pip install triton-windows websockets psutil numpy torch pandas pyarrow pip install "gymnasium[atari]" # gymnasium 1.3.0 + ale-py 0.12.1 pip install setuptools==69.5.1 # ocatari 설치 전에 먼저 pip install --no-build-isolation ocatari # 2.2.1 ``` ### 실행 ```bash python src/server.py # 대시보드 (http://localhost:8766/index.html) python src/sanity.py 3000 # 자동 점검 9개 — 큰 변경 뒤에 반드시 python src/regate2.py # 게임 실력 비교 python src/gate2_assay.py # 게이트 2 (lesion 인과성) python src/gate3_replay.py # 게이트 3 (rewire) ``` --- ## 대시보드 브라우저에서 열고, **뉴런을 직접 꺼본다.** ``` ┌─ 헤더 ─────────────────────────────────────────────────┐ │ fps │ ms/결정 │ step │ 발화 뉴런 │ score │ ├────────────────────────┬───────────────────────────────┤ │ Asteroids │ 전체 뇌 실시간 발화 (139,662점) │ │ + 초파리 오버레이 │ 꺼진 세포만 죽은 색 │ ├──────────┬──────────┬──┴────────┬──────────────────────┤ │ LC4 looming │ 스파이크 래스터 │ 집단 벡터 │ 디코더 4채널 │ ├────────────────────────────────────────────────────────┤ │ [도망|쫓기] │ 모드별 병변 버튼 · 배선 섞기 · 복구 · 새 게임 │ └────────────────────────────────────────────────────────┘ ``` - 3D 뇌: 소마 좌표 **139,662개**를 three.js `Points`로. 스파이크는 셰이더로 감쇠 - 토글은 **결정 경계에서** 적용된다 (CUDA Graph는 포인터를 굽기 때문에 재캡처 불필요, 29.5 µs) - 꺼진 세포는 **그룹이 아니라 세포 단위**로 죽은 색이 된다 (2개 끄면 정확히 2개) - 하단 `분기 영상` 버튼에서 위 ③의 영상 3편을 바로 본다 - **`도망 / 쫓기` 토글** — 두 뇌를 동시에 올리고 판독만 갈아끼운다 (fps 60.0 유지). 버튼·래스터 밴드·집단 벡터·디코더 바가 전부 모드별로 바뀐다 - 도망: `DNp11` `DNp02` `Giant Fiber` `LC4 절반` `LC4 배선 섞기` - 쫓기: `LC10a` `LC10a 배선 섞기` `DNp11` - 병변은 **두 뇌에 똑같이** 걸린다 — 모드를 바꿔도 상태가 안 어긋난다 --- ## 구조 ``` 화면 ──▶ Vision ──▶ LC4Map ──▶ [ 166,700 뉴런 LIF ] ──▶ Decoder ──▶ 액션 운석 방위각 육각 좌표 Triton scatter VNC 하류 ·각크기 기반 자극 + CUDA Graph 333스텝 507세포 ``` | 조각 | 무엇 | 핵심 | |---|---|---| | `lif_rt.py` | 전뇌 LIF 시뮬레이터 | 이벤트 구동 Triton 커널, packed int32 엣지, 333스텝 언롤 CUDA Graph | | `vision.py` | 화면 → 자극 | 방위각·각크기·팽창률 **전부 기하학. 부과 상수 0개** | | `decode.py` | 발화 → 액션 | VNC 하류 507세포에서 판독 (DN 직접 판독은 동어반복이라 폐기) | | `lc10a_position.py` | LC10a 위치 | 육각 좌표 **2단 전파** — LC10a 입력은 0.9 %만 좌표를 가진다 | | `pursuit_targets.py` | 추적 판독 집단 | 좌 550 / 우 526 VNC 세포. 교차 투사 0.1 % 미만 | | `play.py` | 게임 루프 | 60 Hz 페이싱, 4프레임마다 결정. `BrainPolicy`(도망) / `PursuitPolicy`(쫓기) | | `server.py` | 대시보드 서버 | 60 Hz 시뮬 스레드 + 단일 슬롯 메일박스 + WebSocket | | `sanity.py` | 자동 점검 | **12개 항목** + 자가시험 (감싸기 보정 단위 점검 포함) | ### 왜 비트 단위로 재현되는가 가중치가 **정수**(시냅스 수 × 부호)라 부분합이 전부 fp32 정확 표현 범위 (|합| ≤ 12만 ≪ 2²⁴) 안에 들어온다. 덧셈 순서와 무관하게 결과가 같다. 그래서 `int32` 원자 누산으로도 **레퍼런스 구현과 스파이크 하나까지 일치**한다 (누적 51,644 / 51,644, 갈라지는 스텝 없음). 이게 있어야 ③의 "같은 시작점" 주장이 성립한다. --- ## 정직한 한계 이 저장소는 **안 되는 것도 적는다.** 그게 증거의 일부다. | | 상태 | |---|---| | DNp02 발화율이 문헌(subthreshold)보다 높다 | ❌ 전뇌 LIF의 원리적 한계. **발표에서 절대 Hz를 인용하지 말 것** | | GF 방위각 의존성이 문헌과 반대 | ❌ 같은 한계. GF를 방향에 쓰지 않으므로 설계 영향 없음 | | 좌회전 편향 +27.0 % | ⏸ 원인 규명됨 — LC4 개수가 아니라 **세포당 시냅스 세기(우 10 % 강)** 와 **DN→판독 동측/대측 비 어긋남(39 %)**. 부과 상수를 안 늘리려고 **고치지 않기로 결정**. *같은 기하를 쓰는 규칙 기반은 반대 방향(−15.7 %)이다.* ⚠️ **부호 구조는 안정적이지만 크기는 폐루프라 불안정하다** — 크기를 인용할 때 설정을 붙일 것 | | ~~y 랩 주기의 정확도~~ | ✅ **178 확정.** 운석의 감싸기 사건을 개루프로 잡아 **86개 전부 178, 표준편차 0.0** (`probe_wrap12.py`). 측정 방법 5개가 실패한 뒤에 나왔다 — 특히 **폐루프 행동 스캔은 원리적으로 불가능**하다 | | `목숨당 생존` 지표 | ✅ **교체됨.** '배가 보이는 구간'은 화면 판정에 흔들린다 → `life_per_death`(= 프레임 / (죽은 횟수+1))를 쓴다. 옛 지표도 참고용으로 남긴다 | | ~~회피 방향 오차 82.8°~~ | 🔴 **지표 철회** (이슈 #65). '가려는 방향 vs 실제 이동 방향'은 **무작위로 움직이는 배에서도 같은 값**이 나온다 (중앙값: 규칙 128.7° / 무작위 128.8°). 회피 방위가 팽창률 가중이라 배가 향해 가는 쪽 운석이 크게 잡히고, 그래서 움직이기만 해도 이동 반대쪽으로 쏠린다 — **제어가 아니라 기하를 잰다.** 이 지표로 낸 결론('관성 보정 92.9 → 82.8°', '목표 변동성이 구조적 한계')은 거둔다. 게이트 3의 방위 오차(짝지은 재생, 기하 정답 대비)는 다른 지표라 영향 없다 | | 관성 보정이 **생존**에 도움이 되나 | ⚠️ **모른다.** 옛 지표(배 보이는 구간)로는 +25 %였는데 `life_per_death`로 다시 재니 **오히려 절반**이다 (뇌 2,542 → 1,213, 규칙 3,000 → 1,264프레임). 점수는 오른다(뇌 +13 %, 규칙 +24 %). 8판·판당 죽음 0~3회라 거칠다 — **생존 효과는 주장하지 않는다** (이슈 #63) | | 지도학습 MLP가 더 낫다 | ⏸ 43.6° vs 56.2°. 반박은 아니지만 "커넥톰이 최적"이라고 말하지 않는다 | | 전후 축의 **부호** | ⚠️ 부과값. 행동으로 간접 확인됨(위협을 피한다) | | **쫓기 모드에 각성 게이팅이 없다** | ⚠️ 문헌은 각성 없이는 LC10a가 *"almost no response"*. 우리 모델엔 P1도 내부 상태도 없어 **항상 각성**을 가정한다. 게이트 4 에서 가장 무거운 부과값 | | LC10a는 **구애 추적** 회로지 사격 회로가 아니다 | ⚠️ 도피 회로로 운석을 피하는 것과 같은 급의 유비지만 **더 세다.** 문헌에 "LC10a가 조준한다"는 말은 없다 | | AOTU019의 medial/lateral **이름표** | ❓ 문헌은 AOTU019 ← 중심 시야라는데 우리 좌표로는 정반대다. *부분집합 분리*는 두 반구에서 재현되지만(p = 0.0034) **어느 쪽이 중심인지는 주장하지 않는다** | | rewire 100 %의 **시드 변동** | ⚠️ r = −0.381 ± 0.374 (시드 10개 중 5개가 r > −0.5). 용량 반응은 단조지만 100 %에서 변동이 크다. *처음 시드 3개로 재서 소실 85.8 %로 **과대평가**했다 — 10개로 늘려 60.1 %로 정정* | | 쫓기 모드는 **추진을 안 한다** | ⏸ 조향만. 추진을 넣으려면 새 판독 채널과 새 정렬 기준이 필요하고 둘 다 새 선택이 된다 | > **점수** (8에피소드, 6,000프레임 상한, 무작위 no-op 시작): > 전체 뇌 **1,461 ± 329** · 규칙 기반 1,813 ± 774 · 가만히 있기 399 ± 298. > 점수는 **1σ 안 동등**이다. 죽음당 생존(`life_per_death`)은 뇌 1,528 · 규칙 1,312 · 가만히 1,011프레임. > ⚠️ 이 점수는 랩·배 좌표 수정 때마다 흔들렸다(#56 전 2,332 vs 2,480 → #56 후 1,702 vs 1,405 → #63 후 지금). **뇌 대 규칙의 우열은 주장하지 않는다.** ### 🔴 같은 계열 함정에 네 번 걸렸다 전부 **"결정당 4프레임"과 아타리의 프레임 단위가 어긋나서** 생겼고, 전부 **에러 없이 그럴듯한 숫자를 냈다.** | # | 무엇 | 어떻게 드러났나 | |---|---|---| | 1 | 운석 `dx/dy`가 절반의 프레임에서 정확히 0 | 팽창률이 전부 0 | | 2 | 배가 평균 265프레임 덩어리로 20 % 안 보인다 | 3D 뇌가 얼어붙음 | | 3 | 스프라이트가 프레임마다 번갈아 그려진다 | 운석이 빈 사각형으로 보임 | | 4 | **발사는 2프레임 이상 누르고 떼야 나간다** | **한 발도 안 나가고 있었다** | 그리고 **화면을 본 사람이 네 번 더 잡았다** — 발사 0발, 관성 무시, 조준 안 함, 그리고 **화면 랩어라운드**(이슈 #56). | # | 무엇 | 크기 | |---|---|---| | 5a | **방위각 계산에 감싸기 보정이 없었다** (배 속도·운석 추적에는 있었다) | x축만 봐도 쌍의 21.8 %, **가장 가까운 운석의 정체가 바뀌는 결정 14.4 %** | | 5b | y 랩 주기로 **화면 높이 210**을 썼다 (실제 **178**) | 확정까지 측정 방법 **5개가 실패**했다 | | 5c | 배가 위로 나가는 순간 `Player.y`가 **520~528**로 보고되는데 그걸 배로 썼다 | 전체 뇌 정책에서 **프레임의 18.9 %** | | 5d | ↑ 그걸 **'배 없음'으로 버린 것도 틀렸다** (이슈 #63). OCAtari가 `ram[74]`를 **부호 없는 바이트**로 계산한 것이고, 부호를 살리면 y = 8~16 — 배는 화면 윗줄·아랫줄에 나뉘어 **실제로 그려져 있다** | 버리면 초파리가 눈을 감고 NOOP → 배가 감속해 그 띠에 **멈춘다** (규칙 정책 한 시드에서 띠 구간 평균 437프레임) | 게이트는 전부 다시 내서 전부 통과했다. *(5c만 고쳤을 때는 뇌가 규칙 기반을 이겼는데, 5d까지 고치니 다시 1σ 안으로 돌아왔다 — 아래 점수)* `sanity.py` 에 **보정이 실제로 걸리는지 보는 단위 점검 3개**를 넣었다 (9 → 14개) — 값이 그럴듯한지가 아니라 동작이 일어나는지를 본다. **앞의 셋은 측정하다 걸렸고, 넷째는 화면을 본 사람이 물어서 걸렸다.** 그래서 `sanity.py`를 만들었다 — 결과가 좋은지가 아니라 **작동이 실제로 일어나는지**를 본다. > `FIRE_PRESS`(결정 4프레임 중 앞 몇 프레임을 누를지)는 **2만 작동한다.** > 1이면 위상에 따라 전 시드에서 0발, 3 이상이면 떼는 구간이 모자라 재발사가 안 된다. > 위아래가 다 막혀 있다 — **이 값은 바꾸지 말 것.** --- ## 저장소 구조 ``` src/ lif_rt.py 전뇌 LIF + Triton 커널 + CUDA Graph vision.py 화면 -> 방위각·각크기·팽창률, LC4Map decode.py VNC 하류 판독 -> 회피 벡터 -> 액션 play.py 게임 루프, 정책(뇌/규칙/무작위) server.py 대시보드 서버 (WebSocket + 정적 서버) static_server.py Range(206) 지원 정적 서버 sanity.py 자동 점검 12개 + 자가시험 gate_1a/b/c.py 게이트 1 — 방향 단조성·편측성·상쇄 gate2_assay.py 게이트 2 — lesion 인과성 assay gate3_*.py 게이트 3 — 차수·부호 보존 rewire gate4_sweep.py 게이트 4 — 추적 회로 방위각 스윕 gate4_dissoc.py 게이트 4 — 이중 해리 (모드 2 x 병변 3) gate4_control.py 게이트 4 — 무작위 275세포 음성 대조 gate4_rewire*.py 게이트 4 — LC10a->AOTU rewire (스윕 / 실제 게임) lc10a_position.py LC10a 위치 2단 전파 pursuit_targets.py 추적 판독 집단 (연결성 특이도) fire_aim.py 조준 측정 (무작위 방향 대조군 포함) fire_ceiling.py 발사 상한 + 완벽 조준 천장 branch_record.py 분기 녹화 (바이트 단위 동일 검증 포함) mlp_control.py 크기 맞춘 MLP 대조군 verify.py 침묵 사다리 + 레퍼런스 등가성 web/ 대시보드 (three.js, 단일 HTML) graph/ 전처리된 커넥톰 (packed int32 엣지) out/ 측정 결과 JSON ``` ## 참고 문헌 - Dombrovski et al. 2023, *Nature* — [Synaptic gradients transform object location to action](https://www.nature.com/articles/s41586-022-05562-8) ← 핵심 인용 - Dombrovski et al. 2025, *Nature* — [LC4 vs LPLC2](https://www.nature.com/articles/s41586-025-09037-4) - Jang & von Reyn 2023, *JEB* — [GF 방위각 불변성](https://journals.biologists.com/jeb/article/226/8/jeb244790/307120) - Shiu et al. 2024, *Nature* — [전뇌 LIF 모델](https://www.nature.com/articles/s41586-024-07763-9) - Nern et al. 2025, *Nature* — [시각계 커넥톰 인벤토리](https://www.nature.com/articles/s41586-025-08746-0) - Wilson Lab 2026, *Neuron* — [시각 표적 추적의 병렬 경로](https://www.cell.com/neuron/fulltext/S0896-6273(26)00001-2) ← 쫓기 모드의 핵심 인용 - Hindmarsh Sten et al. 2021, *Nature* — [각성이 LC10a 시각처리를 게이팅한다](https://www.nature.com/articles/s41586-021-03714-w) - Ribeiro et al. 2018, *Cell* — [구애 방향을 정하는 시각투사뉴런](https://www.cell.com/cell/fulltext/S0092-8674(18)30788-8) - 도구: [OC_Atari](https://github.com/k4ntz/OC_Atari) · [ALE](https://ale.farama.org/environments/asteroids/) · [Triton](https://triton-lang.org/) · [three.js](https://threejs.org/) ## 라이선스 [MIT](LICENSE)