Nengo를 이용해 spiking neuron을 만들어보자!
1) 필요한 library import
1 2 3 4 5 | import numpy as np import matplotlib.pyplot as plt %matplotlib inline import nengo | cs |
2) network 설계
Nengo에서는 Networt() 객체 안에 필요한 모든 network를 설계한다.
tensorflow에서 graph와 비슷하다고 해야하나..
network의 선언은 다음과 같이 한다.
1 2 | model = nengo.Network() with model: | cs |
1 2 3 4 5 6 7 8 9 10 | with nengo.Network() as net: inp = nengo.Node(output=np.sin) ens = nengo.Ensemble(1, 1, neuron_type=nengo.LIF(), intercepts=[0]) nengo.Connection(inp, ens, synapse=0.1) p = nengo.Probe(ens) inp_p = nengo.Probe(inp) spike_p = nengo.Probe(ens.neurons) voltage_p = nengo.Probe(ens.neurons, 'voltage') | cs |
코드가 조금 긴데, 하나하나 차근차근 살펴보자
여기서는 sin wave를 입력으로 주기 위해, inp라는 nengo.Node를 선언하고, input function을 numpy의 sin으로 적용하였다.
그 다음 nengo.Ensemble을 이용해 neuron 집단을 하나 만든다.
여기서 첫 번쨰 parameter는 전체 neuron의 개수를, 두 번째 parameter는 neuron group의 dimension을 말한다.
세 번째로는 neuron의 type을 결정하고, intercepts는 neuron의 initialized response를 shift하는건데, 다음 예제를 통해 설명하겠다.
여기서의 neuron type은 Leaky-integrate and fire model (LIF)로 설정하였다.
이렇게 input인 nengo.Node와 neuron인 nengo.Ensemble이 완성되었다.
그럼 이 둘을 연결해야 하는데, 이 때는 nengo.Connection 함수를 사용한다.
Nengo에서는 'Probe'라는 object을 사용하는데, 이건 network 외부에서 network의 요소를 관찰하기 위해 사용된다.
그러니까, nengo.Probe(inp)를 보면, output으로는 np.sin의 출력값이 나올 것이다.
한 가지 재밌는 것은 nengo.Probe(ens)다.
ens 그 자체를 관찰하겠다고 선언하면, 해당 값에는 Ensemble neuron 집단의 발화를 '디코드' 해서 보여준다.
예를 들어 input value가 10일 때 발화하는 neuron이 있다고 가정해보자.
거꾸로 말해 해당 neuron이 발화를 시작한다는 것은, input value가 10이라는 것이다.
이렇게 '디코딩'이 가능해진다.
그럼 Ensemble의 neuron 집단이 가지는 활성 자체를 관찰하고 싶다면?
ens.neurons를 관찰하겠다고 선언하면 된다.
이렇게 선언하면 Ensemble에 속해있는 neuron의 spike timing 정보를 획득할 수 있다.
Neuron들의 voltage 변화를 관찰하고 싶다면, 뒤에 'voltage' parameter를 추가하면 된다.
결과적으로, sine 입력을 받는 1차원의 neuron 1개 선언이 아주 손쉽게 끝났다 ^^
그럼 이제 궁금한 것이, 대체 어떤 neuron이 만들어진 것인가?
3) 만들어진 neuron 확인
Nengo에서의 simulator는 tensorflow에서 session 개념과 유사하게 사용된다.
한 가지 다른 점은, simulation이 run을 몇 초 동안 도는지 시간의 개념이 적용된다.
세포의 발화를 simulation하는 것이니까.
simulation 동안, neuron 집단의 tuning curve를 관찰하려면, 아래와 같이 입력하면 된다.
1 2 3 4 5 6 7 | with nengo.Simulator(net) as sim: # this is the only line that changes plt.figure() plt.plot(*nengo.utils.ensemble.tuning_curves(ens, sim)) plt.xlabel("input value") plt.ylabel("firing rate") plt.title(str(nengo.LIF())) sim.run(5.0) | cs |
굉장히 재밌는 neuron이 만들어졌다.
neuron의 활성 graph는 조절이 가능한데, default로 neuron을 생성하면 위와 같이 나타난다.
그럼 여기서 intercepts를 0.5를 주면?
이렇게 활성 graph가 0.5 shift 된 neuron이 만들어지게 된다.
input value에 따른 firing rate의 조절이 이렇게 간편하다니, 참 잘 만든 library다.
4) Simulation!
설명은 이만하면 됐고, 진짜로 sine 입력을 받는 neuron의 활성을 관찰해보자.
1 2 3 4 | plt.figure() plt.plot(sim.trange(), sim.data[p]) plt.plot(sim.trange(), sim.data[inp_p]) | cs |
5초의 simulation 동안 정확하게 input value가 0 이상일 때 발화한 것을 관찰할 수 있었다.
아까 말했 듯이, p값은 ens의 활성을 '디코딩'한 결과물이기 때문에, 그림처럼 보인다.
그럼 voltage_p를 관찰해보면 어떨까?
neuron이 발화하는게 정확하게 보인다 ^^
5) two neuron
이번엔 약간의 parameter setting을 통해 서로 다른 두 개의 neuron을 만들어보자
1 2 3 4 5 6 7 8 9 10 | with nengo.Network() as net: inp = nengo.Node(output=np.sin) #ens = nengo.Ensemble(2, 1, neuron_type=nengo.LIF()) ens = nengo.Ensemble(2, 1,neuron_type=nengo.LIF(), encoders=[[1], [-1]]) nengo.Connection(inp, ens, synapse=0.1) p = nengo.Probe(ens) inp_p = nengo.Probe(inp) spike_p = nengo.Probe(ens.neurons) voltage_p = nengo.Probe(ens.neurons, 'voltage') | cs |
위의 코드랑 정확히 똑같은데, encoder의 값을 서로 상반되게 만들었다.
encoder는 neuron으로 들어오는 input value를 neuron이 어떻게 encoding을 하는지 변경할 수 있다.
input value * encoder를 matrix 연산을 통해 neuron의 활성으로 변환된다.
이 떄, row는 Ensemble의 각 neuron들을 말하고, column은 input의 dimension이 된다.
위와 같이 encoder를 -1, 1로 둠으로써, 같은 입력에 대해 반대로 활성이 조절되는 두 neuron을 만들게 된 것이다.
똑같이 tuning curve를 출력해보면 아래와 같다.
음.. 뭔가 마음에 들지 않는다.
Neuron을 잔뜩 만들어보자!
6) multi neurons
Neuron 200개를 만들어 넣어봤다!
이제 neuron들의 활성이 sine graph처럼 보인다 ^^ 아 이뿌다.
'Deep Learning Tools > Nengo' 카테고리의 다른 글
Nengo 음성 데이터를 neural network에 입력으로 넣기 (0) | 2018.11.07 |
---|---|
Nengo neuron에 특정한 값 input으로 넣기 (0) | 2018.11.06 |
많은 neuron으로 sine wave 표현하기 (0) | 2018.11.05 |
Nengo로 구현하는 MNIST CNN spiking neural network 예제 (5) | 2018.10.26 |
Nengo Python 환경설정 (0) | 2018.10.23 |