Pythonでニューロンシミュレータを作ってみた

# 0. ニューロンシミュレータ
ニューロンシミュレータといえばYale大学が作っている[NEURON](https://neuron.yale.edu/neuron/)が有名です．
これはどちらかというと神経科学目線でのシミュレータですが，エンジニアリングな視点では[BRIAN](https://brian2.readthedocs.io/en/stable/)や[BindsNET](https://bindsnet-docs.readthedocs.io/)などがあります．

どのライブラリもPythonで動作し，とてもよくできていますが，**もっと手軽にニューロンをシミュレーションできるライブラリがあっても良いでのは？**と思っていました．

そこで！
作りました！！
(あまり需要は無いかもしれないけど！)

# 1. SPINE: Spiking Neuron Simulotor
![spine](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520839/17fcd24f-2639-1403-3137-617660d5e8ab.png)

必要なのは(今のところ)NumPyとMatplotlibだけ．
正直ライブラリと謳えるほど規模の大きい物ではありませんが，SPINEでは以下のモデルのシミュレーションが可能です．

1. IF: Integrate-and-Fireモデル
2. LIF: Leaky IFモデル
3. Hodgkin-Huxleyモデル
4. FitzHugh-Nagumoモデル
5. ポアソンスパイクの生成

またIF/LIFモデルでは，スパイク応答カーネルをsingle exponentialかdouble exponentialも選べます．

SPINEはエンジニアリング特化でも，サイエンス特化でもないです．
とにかく，神経科学やスパイキングニューロン初学者の，学び始めを手助けできれば，という想いで作っています．
ソースは記事末に掲載．

# 2. 動作例
まあ，とりあえず実際に動く様子を見てください．

## 2.1. LIFとPoissonSpike
**前ニューロン10個から入力を受け取るLIFニューロンの活動をシミュレーションする**，とします．
このとき，入力スパイク列 (前ニューロンの出力スパイク列) をポアソンスパイク列とすると，以下のようにコーディングします．

ref: [Pythonで実装しながら理解するPoisson Spike (ポアソンスパイク) - Qiita](https://qiita.com/arakiii/items/a47a6fe44abd64be6dc9)

```python
from spine import LIF, PoissonSpike
from spine.tools.plotting import plot_spike_scatter

import numpy as np
import matplotlib.pyplot as plt


if __name__ == '__main__':
    duration = 500  # [ms] 実験時間
    dt = 0.1        # [ms] time step

    time = int(duration / dt)

    # Input data from Poisson Spike Gen.
    # ランダムな数値から入力となるポアソンスパイク列を生成
    spikes = PoissonSpike(np.random.random(10),
                          time=duration,
                          dt=dt).spikes

    # 適当な重み
    weights = np.random.random(10) + 5.0

    # LIFニューロンを定義 (Double exp filter)
    neu = LIF(duration,
              dt,
              k='double',  # use double exponential filter
              )

    # 入力スパイク列と重みを渡して，膜電位を計算
    # 膜電位，出力スパイク，発火時刻を返す 
    v, s, f = neu.calc_v((spikes, weights))

    # Plot
    t = np.arange(0, duration, dt)

    plt.subplot(2, 1, 1)
    plot_spike_scatter(spikes, duration, dt, title='input spike trains', xlabel=None)

    plt.subplot(2, 1, 2)
    plt.plot(t, v)
    plt.plot(t, np.full_like(t, neu.th), linestyle='dashed')
    plt.ylabel('Membrane Voltage [mV]')
    plt.xlabel('time [ms]')
    plt.xlim(0, duration)

    plt.show()
```
![dlif.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520839/1e9746de-b982-1a04-4df0-2a4cc22e6660.png)

こんな感じです．

もちろん発火閾値などのハイパーパラメータはLIFを生成する際に，引数として渡せるので細かい実験設定も可能です．

## 2.2. とにかく全てのモデルを動かしてみたい人向け
そんな方には，Githubにサンプルコードをいくつか用意してあります．

```shell
$ python if_sample.py    # IFモデル
$ python lif_sample.py   # LIFモデル
$ python hh_sample.py    # Hodgkin-Huxleyモデル
$ python fhn_sample.py   # FitzHugh-Nagumoモデル
```

この中身の必要な箇所を変更してシミュレーションするのもアリだと思います．
実際に生成される画像はGithubに載せています．

# 3. あとがき
実はこのライブラリはもう少し前からあったのですが，コードを整理して結構使いやすくなったのでQiitaでも紹介しよう，となりました．

SPINEは僕が学習したものの副産物です．
なので本当にシンプルなニューロンシミュレータですが，最初に行ったように僕個人としてはこれで**ニューロサイエンスやSNN初学者の学びの手助けとなれば幸い**です．

これからも，ちょくちょくアップデートはしていく予定なので，「ええやん」と思ったらGithubのソースを是非覗いてください．
スターくれると喜びます．

:warning:
SPINEは大規模なSNN構築は想定していません．あくまで動作確認用の簡易ニューロンシミュレータです．
SNN構築して画像処理などをしたい人はBindsNETをお勧めします．

# 追記 (2020.07.02)
Webで動くSPINEを作ってみました．
[https://spine-web.hirlab.net/](https://spine-web.hirlab.net/)
適当に遊んでみてください！


## Source
[HiroshiARAKI/spine: SPINE is a simple Spiking Neuron simulator](https://github.com/HiroshiARAKI/spine)

## Documentation
[https://spine.hirlab.net/](https://spine.hirlab.net/)