forked from crjimene/spikinglab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SpikingLab_Demo_Artificial_Insect_and_STDP_10032020_Netlogo.nlogo
2070 lines (1716 loc) · 57.5 KB
/
SpikingLab_Demo_Artificial_Insect_and_STDP_10032020_Netlogo.nlogo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;; SpikingLab: Modelling Spiking Neural Networks with STDP learning
;; Author: Cristian Jimenez Romero - The Open University - 2015
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SpikingLab SNN related code:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
breed [neurontypes neurontype]
breed [inputneurons inputneuron]
breed [normalneurons normalneuron]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Demo: Artificial insect related code:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
breed [testcreatures testcreature]
breed [visualsensors visualsensor]
breed [sightlines sightline]
directed-link-breed [sight-trajectories sight-trajectory]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
breed [itrails itrail]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
directed-link-breed [normal-synapses normal-synapse]
directed-link-breed [input-synapses input-synapse]
;;;
;;; Global variables including SpikingLab internals
;;;
globals [
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SNN Module globals;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
neuron_state_open;; describe state machine of the neuron
neuron_state_firing;; describe state machine of the neuron
neuron_state_refractory;; describe state machine of the neuron
excitatory_synapse
inhibitory_synapse
system_iter_unit ;;time steps of each iteration expressed in milliseconds
plot-list
plot-list2
PulseHistoryBuffSize ;;Size of pulse history buffer
input_value_empty ;;Indicate that there is no input value
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Demo globals;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pspikefrequency ;;Number of spikes emitted by an input neuron in response to one stimulus
error_free_counter ;;Number of iterations since the insect collided with a noxious stimulus
required_error_free_iterations ;;Number of error-free iterations necessary to stop training
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;World globals;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
min_x_boundary ;;Define initial x coordinate of simulation area
min_y_boundary ;;Define initial y coordinate of simulation area
max_x_boundary ;;Define final x coordinate of simulation area
max_y_boundary ;;Define final y coordinate of simulation area
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
]
neurontypes-own [
neurontypeid
;;;;;;;;;;Neuron Dynamics;;;;;;;;;;;
restingpotential
firethreshold
decayrate ;Decay rate constant
relrefractorypotential ;Refractory potential
intervrefractoryperiod ;Duration of absolute-refractory period
minmembranepotential ;lowest boundary for membrane potential
;;;;;;;Learning Parameters;;;;;;;;;
pos_hebb_weight ;;Weight to increase the efficacy of synapses
pos_time_window ;; Positive learning window
neg_hebb_weight ;;Weight to decrease the efficacy of synapses
neg_time_window ;; negative learning window
max_synaptic_weight ;;Maximum synaptic weight
min_synaptic_weight ;;Minimum synaptic weight
pos_syn_change_interval ;;ranges of pre–to–post synaptic interspike intervals over which synaptic change occur.
neg_syn_change_interval
]
normalneurons-own [
nlayernum
nneuronid
nneuronstate
nrestingpotential
nfirethreshold
nmembranepotential
ndecayrate
nrelrefractorypotential
nintervrefractoryperiod
nrefractorycounter
naxondelay
nsynapsesarray
nnumofsynapses
nlast-firing-time
nincomingspikes
nlastspikeinput
nneuronlabel
nminmembranepotential
;;;;;;;;;;;;;;;;Learning Parameters;;;;;;;;;;;;;;;;;
npos_hebb_weight ;;Weight to increase the efficacy of synapses
npos_time_window ;; Positive learning window
nneg_hebb_weight ;;Weight to decrease the efficacy of synapses
nneg_time_window ;; negative learning window
nmax_synaptic_weight ;;Maximum synaptic weight
nmin_synaptic_weight ;;Minimum synaptic weight
npos_syn_change_interval ;;ranges of pre–to–post synaptic interspike intervals over which synaptic change occur.
nneg_syn_change_interval
]
normal-synapses-own [
presynneuronlabel
possynneuronlabel
presynneuronid
possynneuronid
synapseefficacy
exc_or_inh
synapsedelay
joblist
learningon?
]
inputneurons-own [
layernum
neuronid
neuronstate
pulsecounter ;;Count the number of sent pulses
interspikecounter ;;Count the time between pulses
numberofspikes ;;Number of spikes to send
postsynneuron
encodedvalue
isynapseefficacy ;;In most cases should be large enough to activate possynn with a single spike
neuronlabel
]
testcreatures-own [
creature_label
creature_id
reward_neuron
pain_neuron
move_neuron
rotate_neuron
creature_sightline
]
visualsensors-own [
sensor_id
perceived_stimuli
distance_to_stimuli
relative_rotation ;;Position relative to front
attached_to_colour
attached_to_neuron
attached_to_creature
]
itrails-own
[
ttl
]
;;;
;;; Set global variables with their initial values
;;;
to initialize-global-vars
set system_iter_unit 1 ;; each simulation iteration represents 1 time unit
set neuron_state_open 1 ;;State machine idle
set neuron_state_firing 2 ;;State machine firing
set neuron_state_refractory 3 ;;State machine refractory
set excitatory_synapse 1
set inhibitory_synapse 2
set plot-list[] ;;List for spike history
set plot-list2[] ;;List for spike history
set PulseHistoryBuffSize 30
set input_value_empty -1
;;;;;;;;;;;;;;;;;;;;;;;;;;;Simulation area globals;;;;;;;;;;;;;;;;;;;;;;;;
set min_x_boundary 80 ;;Define initial x coordinate of simulation area
set min_y_boundary 1 ;;Define initial y coordinate of simulation area
set max_x_boundary 120 ;;Define final x coordinate of simulation area
set max_y_boundary 60 ;;Define final y coordinate of simulation area
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Insect globals;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set pspikefrequency 1
set error_free_counter 0
set required_error_free_iterations 35000
end
;;;
;;; Create a neuron type
;;; Parameters: Type-identifier, resting potential, firing threshold, decay rate, refractory potential, duration of refractory period, lowest boundary for membrane potential
to setup-neurontype [#pneurontypeid #prestpot #pthreshold #pdecayr #prefractpot #pintrefrectp #minmembranepotential]
create-neurontypes 1
[
set shape "square"
set neurontypeid #pneurontypeid
set restingpotential #prestpot
set firethreshold #pthreshold
set decayrate #pdecayr
set relrefractorypotential #prefractpot
set intervrefractoryperiod #pintrefrectp
set minmembranepotential #minmembranepotential
ht
]
end
;;;
;;; Set learning parameters for neuron type pneurontypeid
;;;
to set-neurontype-learning-params [ #pneurontypeid #ppos_hebb_weight #ppos_time_window #pneg_hebb_weight #pneg_time_window #pmax_synaptic_weight
#pmin_synaptic_weight #ppos_syn_change_interval #pneg_syn_change_interval]
ask neurontypes with [neurontypeid = #pneurontypeid]
[
set pos_hebb_weight #ppos_hebb_weight
set pos_time_window #ppos_time_window
set neg_hebb_weight #pneg_hebb_weight
set neg_time_window #pneg_time_window
set max_synaptic_weight #pmax_synaptic_weight
set min_synaptic_weight #pmin_synaptic_weight
set pos_syn_change_interval #ppos_syn_change_interval
set neg_syn_change_interval #pneg_syn_change_interval
]
end
;;;
;;; Declare an existing neuron "pneuronid" as neuron-type "pneurontypeid"
;;;
to set-neuron-to-neurontype [ #pneurontypeid #pneuronid ] ;Call by observer
ask neurontypes with [neurontypeid = #pneurontypeid]
[
ask normalneuron #pneuronid
[
set nrestingpotential [restingpotential] of myself
set nmembranepotential [restingpotential] of myself
set nfirethreshold [firethreshold] of myself
set ndecayrate [decayrate] of myself
set nrelrefractorypotential [relrefractorypotential] of myself
set nintervrefractoryperiod [intervrefractoryperiod] of myself
set nminmembranepotential [minmembranepotential] of myself
;;;;;;;;;;;;;;;;Learning Parameters;;;;;;;;;;;;;;;;;
set npos_hebb_weight [pos_hebb_weight] of myself
set npos_time_window [pos_time_window] of myself
set nneg_hebb_weight [neg_hebb_weight] of myself
set nneg_time_window [neg_time_window] of myself
set nmax_synaptic_weight [max_synaptic_weight] of myself
set nmin_synaptic_weight [min_synaptic_weight] of myself
set npos_syn_change_interval [pos_syn_change_interval] of myself
set nneg_syn_change_interval [neg_syn_change_interval] of myself
]
]
end
;;;
;;; Get intern identifier of the input-neuron with label = #pneuronlabel
;;;
to-report get-input-neuronid-from-label [#pneuronlabel]
let returned_id nobody
ask one-of inputneurons with [neuronlabel = #pneuronlabel][set returned_id neuronid]
report returned_id
end
;;;
;;; Get intern identifier of the normal-neuron with label = #pneuronlabel
;;;
to-report get-neuronid-from-label [#pneuronlabel]
let returned_id nobody
ask one-of normalneurons with [nneuronlabel = #pneuronlabel][set returned_id nneuronid]
report returned_id
end
;;;
;;; Create a new synapse between pre-synaptic neuron: #ppresynneuronlabel and post-synaptic neuron: #ppossynneuronlabel
;;;
to setup-synapse [#ppresynneuronlabel #ppossynneuronlabel #psynapseefficacy #pexc_or_inh #psyndelay #plearningon?]
let presynneuid get-neuronid-from-label #ppresynneuronlabel
let possynneuid get-neuronid-from-label #ppossynneuronlabel
let postsynneu normalneuron possynneuid
ask normalneuron presynneuid [
create-normal-synapse-to postsynneu [
set presynneuronlabel #ppresynneuronlabel
set possynneuronlabel #ppossynneuronlabel
set presynneuronid presynneuid
set possynneuronid possynneuid
set synapseefficacy #psynapseefficacy
set exc_or_inh #pexc_or_inh
set synapsedelay #psyndelay
set joblist []
set learningon? #plearningon?
ifelse (#pexc_or_inh = inhibitory_synapse)
[
set color red
]
[
set color grey
]
]
]
end
;;;
;;; Process incoming pulse from input neuron
;;;
to receive-input-neuron-pulse [ #psnefficacy #pexcinh ];;called by Neuron
if ( nneuronstate != neuron_state_refractory )
[
;;Adjust membrane potential:
ifelse ( #pexcinh = excitatory_synapse )
[
set nmembranepotential nmembranepotential + #psnefficacy ;;increase membrane potential
]
[
set nmembranepotential nmembranepotential - #psnefficacy ;;decrease membrane potential
if (nmembranepotential < nminmembranepotential) ;; Floor for the membrane potential in case of extreme inhibition
[
set nmembranepotential nminmembranepotential
]
]
]
set nlastspikeinput ticks
end
;;;
;;; Neuron pstneuronid# processes incoming pulse from neuron #prneuronid
;;;
to receive-pulse [ #prneuronid #snefficacy #excinh #plearningon? ];;called by neuron
if ( nneuronstate != neuron_state_refractory )
[
;;Perturb membrane potential:
ifelse ( #excinh = excitatory_synapse )
[
set nmembranepotential nmembranepotential + (#snefficacy * epsp-kernel) ;;increase membrane potential
]
[
set nmembranepotential nmembranepotential - (#snefficacy * ipsp-kernel) ;;decrease membrane potential
if (nmembranepotential < nminmembranepotential) ;; Floor for the membrane potential in case of extreme inhibition
[
set nmembranepotential nminmembranepotential
]
]
]
;;Remember last input spike:
set nlastspikeinput ticks
;; If plasticity is activated then store pulse info for further processing and apply STDP
if (#plearningon? and istrainingmode?)
[
;;Don't let incoming-pulses history-buffer grow beyond limits (delete oldest spike):
check-pulse-history-buffer
;;Create list of parameters and populate it:
let pulseinflist[]
set pulseinflist lput #prneuronid pulseinflist ;;Add Presynaptic neuron Id
set pulseinflist lput #snefficacy pulseinflist ;;Add Synaptic efficacy
set pulseinflist lput #excinh pulseinflist ;;Add excitatory or inhibitory info.
set pulseinflist lput ticks pulseinflist ;;Add arriving time
set pulseinflist lput false pulseinflist ;;Indicate if pulse has been processed as an EPSP following a Postsynaptic spike ( Post -> Pre, negative hebbian)
;;Add list of parameters to list of incoming pulses:
set nincomingspikes lput pulseinflist nincomingspikes
;;Apply STDP learning rule:
apply-stdp-learning-rule
]
end
;;;
;;; Neuron prepares to fire
;;;
to prepare-pulse-firing ;;Called by Neurons
;;Remember last firing time
set nlast-firing-time ticks
;;Apply learning rule and after that empty incoming-pulses history:
apply-stdp-learning-rule
empty-pulse-history-buffer
;;transmit Pulse to postsynaptic neurons:
propagate-pulses
;;Set State to refractory
set nneuronstate neuron_state_refractory
;;initialize counter of refractory period in number of iterations
set nrefractorycounter nintervrefractoryperiod
end
;;;
;;; Kernel for inhibitory post-synaptic potential
;;;
to-report ipsp-kernel ;;Called by Neurons
report 1
end
;;;
;;; Kernel for excitatory post-synaptic potential
;;;
to-report epsp-kernel ;;Called by Neurons
report 1
end
;;;
;;; Kernel for membrane decay towards resting potential (If current membrane pot. > Resting pot.)
;;;
to-report negative-decay-kernel ;;Called by Neurons
report abs(nrestingpotential - nmembranepotential) * ndecayrate
end
;;;
;;; Kernel for membrane decay towards resting potential (If current membrane pot. < Resting pot.)
;;;
to-report positive-decay-kernel ;;Called by Neurons
report abs(nrestingpotential - nmembranepotential) * ndecayrate
end
;;;
;;; Bring membrane potential towards its resting state
;;;
to decay ;;Called by Neurons
;;Move membrane potential towards resting potential:
ifelse (nmembranepotential > nrestingpotential )
[
let expdecay negative-decay-kernel ;
ifelse ((nmembranepotential - expdecay) < nrestingpotential)
[
set nmembranepotential nrestingpotential
]
[
set nmembranepotential nmembranepotential - expdecay
]
]
[
let expdecay positive-decay-kernel ;
ifelse ((nmembranepotential + expdecay) > nrestingpotential)
[
set nmembranepotential nrestingpotential
]
[
set nmembranepotential nmembranepotential + expdecay
]
]
end
;;;
;;; Process neuron dynamics according to its machine state
;;;
to do-neuron-dynamics ;;Called by Neurons
ifelse ( nneuronstate = neuron_state_open )
[
if (nmembranepotential != nrestingpotential )
[
;;Check if membrane potential reached the firing threshold
ifelse( nmembranepotential >= nfirethreshold )
[
prepare-pulse-firing
set color red
]
[
;;Move membrane potential towards resting potential:
decay
]
]
]
[
;;Not idle and not firing, then refractory:
set color pink ;;Restore normal colour
;;Decrease timer of absolute refractory period:
set nrefractorycounter nrefractorycounter - system_iter_unit
;;Set membrane potential with refractory potential:
set nmembranepotential nrelrefractorypotential
if ( nrefractorycounter <= 0) ;;End of absolute refractory period?
[
;;Set neuron in open state:
set nneuronstate neuron_state_open
]
]
;;Continue with Axonal dynamics independently of the neuron state:
do-synaptic-dynamics
end
;;;
;;; Delete history of incoming spikes
;;;
to empty-pulse-history-buffer ;;Called by neurons
set nincomingspikes[]
end
;;;
;;; Apply the Spike Timing Dependent Plasticity rule
;;;
to apply-stdp-learning-rule ;;Call by neurons
;Apply rule: Ap.exp(dt/Tp); if dt < 0; dt = prespt - postspt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
let currspikeinfo[]
let itemcount 0
let deltaweight 0
while [itemcount < ( length nincomingspikes ) ]
[
set currspikeinfo ( item itemcount nincomingspikes ) ;;Get spike info: prneuronid[0], snefficacy[1], excinh[2], arrivaltime[3], processedBynegHebb[4]
ifelse ( item 2 currspikeinfo ) = excitatory_synapse ;;Is the spike coming from an excitatory synapsis?
[
let deltaspike ( item 3 currspikeinfo ) - nlast-firing-time
if ( deltaspike >= nneg_time_window and deltaspike <= npos_time_window) ;;Is spike within learning window?
[
;;Calculate learning factor:
ifelse ( deltaspike <= 0 ) ;;Increase weight
[
set deltaweight npos_hebb_weight * exp(deltaspike / npos_syn_change_interval )
ask normal-synapse ( item 0 currspikeinfo ) nneuronid [update-synapse-efficacy deltaweight [nmax_synaptic_weight] of myself [nmin_synaptic_weight] of myself]
]
[
if (( item 4 currspikeinfo ) = false) ;;if spike has not been processed then compute Hebb rule:
[
set deltaweight (- nneg_hebb_weight * exp(- deltaspike / nneg_syn_change_interval )) ;;Turn positive delta into a negative weight
set currspikeinfo replace-item 4 currspikeinfo true ;Indicate that this pulse has already been processed as a EPSP after Postsyn neuron has fired (negative hebbian)
set nincomingspikes replace-item itemcount nincomingspikes currspikeinfo
ask normal-synapse ( item 0 currspikeinfo ) nneuronid [update-synapse-efficacy deltaweight [nmax_synaptic_weight] of myself [nmin_synaptic_weight] of myself]
]
]
]
]
[
;;Inhibitory Synapses: Plasticity in inhibitory synapses not implemented yet
]
set itemcount itemcount + 1
]
end
;;;
;;; Don't store more pulses than the specified by PulseHistoryBuffSize
;;;
to check-pulse-history-buffer ;;Call by neurons
if( length nincomingspikes > PulseHistoryBuffSize )
[
;; Remove oldest pulse in the list
set nincomingspikes remove-item 0 nincomingspikes
]
end
;;;
;;; Propagate pulse to all post-synaptic neurons
;;;
to propagate-pulses ;;Call by neurons
;; Insert a new pulse in all synapses having the current neuron as presynaptic
ask my-out-normal-synapses
[
add-pulse-job
]
end
;;;
;;; Process synaptic dynamics of synapses with pre-synaptic neuron: presynneuronid
;;;
to do-synaptic-dynamics ;;Call by neurons
;; Process all outgoing synapses with pulses in their job-list
ask my-out-normal-synapses with [ length joblist > 0 ]
[
process-pulses-queue
]
end
;;;
;;; Enqueue pulse in synapse
;;;
to add-pulse-job ;;Call by link (synapse)
;;Add a new Pulse with its delay time at the end of the outgoing-synapse joblist
set joblist lput synapsedelay joblist
end
;;;
;;; Change synaptic weight
;;;
to update-synapse-efficacy [ #deltaweight #pmax_synaptic_weight #pmin_synaptic_weight] ;;Call by synapse
ifelse ( synapseefficacy + #deltaweight ) > #pmax_synaptic_weight
[
set synapseefficacy #pmax_synaptic_weight
]
[
ifelse ( synapseefficacy + #deltaweight ) < #pmin_synaptic_weight
[
set synapseefficacy #pmin_synaptic_weight
]
[
set synapseefficacy synapseefficacy + #deltaweight
]
]
end
;;;
;;; For each traveling pulse in synapse check if pulse has already arrived at the post-synaptic neuron
;;;
to process-pulses-queue ;;Call by synapse
set joblist map [ i -> i - 1 ] joblist ;;Decrease all delay counters by 1 time-unit
foreach filter [i -> i <= 0] joblist ;;Process pulses that reached the postsynaptic neuron
[
;;Transmit Pulse to Postsyn Neuron:
ask other-end [receive-pulse [presynneuronid] of myself [synapseefficacy] of myself [exc_or_inh] of myself [learningon?] of myself]
]
;;Keep only "traveling" pulses in the list :
;;set joblist filter [? > 0] joblist
set joblist filter [i -> i > 0] joblist
end
;;;
;;; Create one input neuron and attach it to neuron with label #ppostsynneuronlabel (input neurons have one connection only)
;;;
to setup-input-neuron [#pposx #pposy #label #ppostsynneuronlabel #psynapseefficacy #pcoding #pnumofspikes]
let postsynneuronid get-neuronid-from-label #ppostsynneuronlabel
set-default-shape inputneurons "square"
create-inputneurons 1
[
set layernum 0
set neuronid who
set neuronstate neuron_state_open
set pulsecounter 0
set interspikecounter 0
set numberofspikes #pnumofspikes
set postsynneuron postsynneuronid
set encodedvalue input_value_empty
set isynapseefficacy #psynapseefficacy
setxy #pposx #pposy
set color green
set label #label
set neuronlabel #label
setup-input-synapse
]
end
;;;
;;; Process pulses in input neuron
;;;
to do-input-neuron-dynamics ;;Called by inputneurons
if ( pulsecounter > 0 ) ;;process only if input-neuron has something to do
[
set interspikecounter interspikecounter + 1
if (interspikecounter > encodedvalue)
[
;;Transmit pulse to Post-synaptic Neuron;
ask out-input-synapse-neighbors [receive-input-neuron-pulse [isynapseefficacy] of myself [excitatory_synapse] of myself]
set interspikecounter 0
set pulsecounter pulsecounter - 1
]
]
end
;;;
;;; Encode input value (integer number) into pulses
;;;
to-report set-input-value [#pencodedvalue] ;;Called by inputneurons
;;Check if input neuron is ready to receive input
let inputready false
if ( pulsecounter = 0 )
[
set encodedvalue #pencodedvalue
set pulsecounter numberofspikes ;;Initialize counter with the number of pulses to transmit with the encoded value
set interspikecounter 0
set inputready true
]
report inputready
end
;;;
;;; Ask input neuron with id = #pneuronid to accept and encode a new input value
;;;
to feed-input-neuron [#pneuronid #pencodedvalue];;Called by observer
ask inputneuron #pneuronid
[
let inputready set-input-value #pencodedvalue
]
end
;;;
;;; Ask input neuron with label = #pneuronlabel to accept and encode a new input value
;;;
to feed-input-neuron_by_label [#pneuronlabel #pencodedvalue];;Called by observer
ask one-of inputneurons with [ neuronlabel = #pneuronlabel ]
[
let inputready set-input-value #pencodedvalue
]
end
;;;
;;; Create link to represent synapse from input neuron to post-synaptic neuron: postsynneuron
;;;
to setup-input-synapse ;;Call from inputneurons
let psnneuron postsynneuron
let postsynneu one-of (normalneurons with [nneuronid = psnneuron])
create-input-synapse-to postsynneu
end
;;;
;;; Create and initialize neuron
;;;
to setup-normal-neuron [#playernum #pposx #pposy #label #pneurontypeid]
set-default-shape normalneurons "circle"
let returned_id nobody
create-normalneurons 1
[
set nlayernum #playernum
set nneuronid who
set nneuronstate neuron_state_open
set nrefractorycounter 0
set nincomingspikes[]
set nnumofsynapses 0
set nlastspikeinput 0
setxy #pposx #pposy
set color pink
set label #label
set nneuronlabel #label
set returned_id nneuronid
]
set-neuron-to-neurontype #pneurontypeid returned_id
end
;;;
;;; Process neural dynamics
;;;
to do-network-dynamics
ask inputneurons [ do-input-neuron-dynamics ] ;Process input neurons in random order
ask normalneurons [do-neuron-dynamics] ;Process normal neurons in random order
end
;;;
;;; Show information about neuron with id: #srcneuron
;;;
to show-neuron-info [#srcneuron] ;;Called by observer
;set plot-list lput ( [nmembranepotential] of one-of normalneurons with [nneuronid = neuronid_monitor1] ) plot-list
ask normalneurons with [nneuronid = #srcneuron]
[
print ""
write "Neuron Id:" write nneuronid print ""
write "Layer " write nlayernum print ""
write "Membrane potential: " write nmembranepotential print ""
write "Spike threshold: " write nfirethreshold print ""
write "Resting potential: " write nrestingpotential print ""
write "Refractory potential: " write nrelrefractorypotential print ""
write "Last input-pulse received at:" write nlastspikeinput print ""
write "Last spike fired at: " write nlast-firing-time print ""
write "Current state: " write (ifelse-value ( nneuronstate = neuron_state_open ) ["idle"] ["refractory"] ) print ""
print ""
]
end
;;;
;;; Show information about synapse with pre-synaptic neuron: #srcneuron and post-synaptic neuron: #dstneuron
;;;
to show-synapse-info-from-to [#srcneuron #dstneuron] ;;Called by observer
ask normal-synapses with [presynneuronid = #srcneuron and possynneuronid = #dstneuron]
[
print "Synapse from:"
write "Neuron " write #srcneuron write " to neuron " write #dstneuron print ""
write "Weight: " write synapseefficacy print ""
write "Delay: " write synapsedelay write "iteration(s)" print ""
write "Excitatory or Inhibitory: "
write (ifelse-value ( exc_or_inh = excitatory_synapse ) ["Excitatory"] ["Inhibitory"] )
print ""
]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;End of SNN code;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Create insect agent
;;;
to-report create-creature [#xpos #ypos #creature_label #reward_neuron_label #pain_neuron_label #move_neuron_label #rotate_neuron_label]
let reward_neuron_id get-input-neuronid-from-label #reward_neuron_label
let pain_neuron_id get-input-neuronid-from-label #pain_neuron_label
let move_neuron_id get-neuronid-from-label #move_neuron_label
let rotate_neuron_id get-neuronid-from-label #rotate_neuron_label
let returned_id nobody
create-testcreatures 1 [
set shape "bug"
setxy #xpos #ypos
set size 3
set color yellow
set creature_label #creature_label
set reward_neuron reward_neuron_id
set pain_neuron pain_neuron_id
set move_neuron move_neuron_id
set rotate_neuron rotate_neuron_id
set creature_id who
set returned_id creature_id
]
report returned_id
end
;;;
;;; Create photoreceptor and attach it to insect
;;;
to create-visual-sensor [ #psensor_id #pposition #colour_sensitive #attached_neuron_label #attached_creature] ;;Called by observer
let attached_neuron_id get-input-neuronid-from-label #attached_neuron_label
create-visualsensors 1 [
set sensor_id #psensor_id
set relative_rotation #pposition ;;Degrees relative to current heading - Left + Right 0 Center
set attached_to_colour #colour_sensitive
set attached_to_neuron attached_neuron_id
set attached_to_creature #attached_creature
ht
]
end
;;;
;;; Ask photoreceptor if there is a patch ahead (within insect_view_distance) with a perceivable colour (= attached_to_colour)
;;;
to view-world-ahead ;;Called by visualsensors
let itemcount 0
let foundobj black
;;;;;;;;;;;;;;;Take same position and heading of creature:;;;;;;;;;;;;;;;
let creature_px 0
let creature_py 0
let creature_heading 0
ask testcreature attached_to_creature [set creature_px xcor set creature_py ycor set creature_heading heading];
set xcor creature_px
set ycor creature_py
set heading creature_heading
rt relative_rotation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
let view_distance insect_view_distance
let xview 0
let yview 0
while [itemcount <= view_distance and foundobj = black]
[
set itemcount itemcount + 0.2;1
ask patch-ahead itemcount [
set foundobj pcolor
set xview pxcor
set yview pycor
]
]
update-creature-sightline-position attached_to_creature xview yview
ifelse (foundobj = attached_to_colour) ;;Found perceivable colour?
[
set distance_to_stimuli itemcount
set perceived_stimuli foundobj
]
[
set distance_to_stimuli 0
set perceived_stimuli 0
]
end
;;;
;;; Process Nociceptive, reward and visual sensation
;;;
to perceive-world ;;Called by testcreatures
let nextobject 0
let distobject 0
let onobject 0
;; Get color of current position
ask patch-here [ set onobject pcolor ]
ifelse (onobject = white)
[
ifelse (noxious_white) ;;is White attached to a noxious stimulus
[
feed-input-neuron pain_neuron 1 ;;induce Pain
if (istrainingmode?)
[
;;During training phase move the creature forward to avoid infinite rotation
move-creature 0.5 ;;
set error_free_counter 0
]
]
[
feed-input-neuron reward_neuron 1 ;;induce happiness
ask patch-here [ set pcolor black ] ;;Eat patch
]
]
[
ifelse (onobject = red)
[
ifelse (noxious_red) ;;is Red attached to a noxious stimulus
[
feed-input-neuron pain_neuron 1 ;;induce Pain
if (istrainingmode?)
[
;;During training phase move the creature forward to avoid infinite rotation
move-creature 0.5
set error_free_counter 0
]
]
[