refractoring

This commit is contained in:
2023-05-22 20:10:10 +07:00
parent 666e29ffc2
commit b9550a348a
5 changed files with 116 additions and 121 deletions

View File

@@ -346,7 +346,7 @@ version = "0.19.3"
[[deps.GeneralUtils]] [[deps.GeneralUtils]]
deps = ["DataStructures", "Distributions", "JSON3"] deps = ["DataStructures", "Distributions", "JSON3"]
path = "C:\\Users\\naraw\\.julia\\dev\\GeneralUtils" path = "/home/ton/.julia/dev/GeneralUtils"
uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe" uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
version = "0.1.0" version = "0.1.0"

View File

@@ -14,11 +14,11 @@ function (m::model)(input_data::AbstractVector)
m.timeStep += 1 m.timeStep += 1
# process all corresponding KFN # process all corresponding KFN
raw_model_respond = m.knowledgeFn[:I](m, input_data) raw_model_respond, outputNeuron_v_t1 = m.knowledgeFn[:I](m, input_data)
# the 2nd return (KFN error) should not be used as model error but I use it because there is # the 2nd return (KFN error) should not be used as model error but I use it because there is
# only one KFN in a model right now # only one KFN in a model right now
return raw_model_respond return raw_model_respond::Array{Bool}, outputNeuron_v_t1::Array{Float64}
end end
#------------------------------------------------------------------------------------------------100 #------------------------------------------------------------------------------------------------100
@@ -96,7 +96,7 @@ function (kfn::kfn_1)(m::model, input_data::AbstractVector)
out = [n.z_t1 for n in kfn.outputNeuronsArray] out = [n.z_t1 for n in kfn.outputNeuronsArray]
outputNeuron_v_t1 = [n.v_t1 for n in kfn.outputNeuronsArray] outputNeuron_v_t1 = [n.v_t1 for n in kfn.outputNeuronsArray]
return out, outputNeuron_v_t1 return out::Array{Bool}, outputNeuron_v_t1::Array{Float64}
end end
#------------------------------------------------------------------------------------------------100 #------------------------------------------------------------------------------------------------100

View File

@@ -10,11 +10,11 @@ export learn!
#------------------------------------------------------------------------------------------------100 #------------------------------------------------------------------------------------------------100
function learn!(m::model, modelRespond, correctAnswer=nothing) function learn!(m::model, modelRespond::Vector{Bool}, correctAnswer::Union{AbstractVector, Nothing})
if correctAnswer === nothing if correctAnswer === nothing
correctAnswer_I = zeros(length(modelRespond)) correctAnswer_I = BitArray(undef, length(modelRespond))
else else
correctAnswer_I = correctAnswer # correct answer for kfn I correctAnswer_I = Bool.(correctAnswer) # correct answer for kfn I
end end
learn!(m.knowledgeFn[:I], correctAnswer_I) learn!(m.knowledgeFn[:I], correctAnswer_I)
@@ -22,7 +22,7 @@ end
""" knowledgeFn learn() """ knowledgeFn learn()
""" """
function learn!(kfn::kfn_1, correctAnswer::AbstractVector) function learn!(kfn::kfn_1, correctAnswer::BitVector)
# compute kfn error # compute kfn error
outs = [n.z_t1 for n in kfn.outputNeuronsArray] outs = [n.z_t1 for n in kfn.outputNeuronsArray]
for (i, out) in enumerate(outs) for (i, out) in enumerate(outs)
@@ -76,13 +76,13 @@ end
""" passthroughNeuron learn() """ passthroughNeuron learn()
""" """
function learn!(n::passthroughNeuron, error::Number) function learn!(n::passthroughNeuron, error::Float64)
# skip # skip
end end
""" lif learn() """ lif learn()
""" """
function learn!(n::lifNeuron, error::Number) function learn!(n::lifNeuron, error::Float64)
n.eRec = n.phi * n.epsilonRec n.eRec = n.phi * n.epsilonRec
ΔwRecChange = n.eta * error * n.eRec ΔwRecChange = n.eta * error * n.eRec
n.wRecChange .+= ΔwRecChange n.wRecChange .+= ΔwRecChange
@@ -91,7 +91,7 @@ end
""" alifNeuron learn() """ alifNeuron learn()
""" """
function learn!(n::alifNeuron, error::Number) function learn!(n::alifNeuron, error::Float64)
n.eRec_v = n.phi * n.epsilonRec n.eRec_v = n.phi * n.epsilonRec
n.eRec_a = -n.phi * n.beta * n.epsilonRecA n.eRec_a = -n.phi * n.beta * n.epsilonRecA
n.eRec = n.eRec_v + n.eRec_a n.eRec = n.eRec_v + n.eRec_a
@@ -103,7 +103,7 @@ end
""" linearNeuron learn() """ linearNeuron learn()
""" """
function learn!(n::linearNeuron, error::Number) function learn!(n::linearNeuron, error::Float64)
n.eRec = n.phi * n.epsilonRec n.eRec = n.phi * n.epsilonRec
ΔwRecChange = n.eta * error * n.eRec ΔwRecChange = n.eta * error * n.eRec
n.wRecChange .+= ΔwRecChange n.wRecChange .+= ΔwRecChange

View File

@@ -260,7 +260,7 @@ end
one may use bias = -5 to transform synaptic strength into range -5 to 5 one may use bias = -5 to transform synaptic strength into range -5 to 5
the return value is shifted back to original scale the return value is shifted back to original scale
""" """
function synapticConnStrength(currentStrength::AbstractFloat, updown::String, bias::Number=0) function synapticConnStrength(currentStrength::AbstractFloat, updown::String, bias::Number=0)::Float64
currentStrength += bias currentStrength += bias
if currentStrength > 0 if currentStrength > 0
Δstrength = (1.0 - sigmoid(currentStrength)) Δstrength = (1.0 - sigmoid(currentStrength))

View File

@@ -27,8 +27,8 @@ abstract type computeNeuron <: neuron end
Base.@kwdef mutable struct model <: Ironpen Base.@kwdef mutable struct model <: Ironpen
knowledgeFn::Union{Dict,Nothing} = nothing knowledgeFn::Union{Dict,Nothing} = nothing
modelParams::Union{Dict,Nothing} = nothing modelParams::Union{Dict,Nothing} = nothing
error::Union{Float64,Nothing} = 0.0 error::Float64 = 0.0
outputError::Union{Array,Nothing} = Vector{AbstractFloat}() outputError::Array{Float64} = Float64[]
""" "inference" = no learning params will be collected. """ "inference" = no learning params will be collected.
"learning" = neuron will accumulate epsilon_j, compute Δw_rec_change each time "learning" = neuron will accumulate epsilon_j, compute Δw_rec_change each time
@@ -82,19 +82,19 @@ end
""" knowledgeFn struct """ knowledgeFn struct
""" """
Base.@kwdef mutable struct kfn_1 <: knowledgeFn Base.@kwdef mutable struct kfn_1 <: knowledgeFn
knowledgeFnName::Union{String,Nothing} = nothing knowledgeFnName::String = "not defined"
kfnParams::Union{Dict,Nothing} = nothing # store params of knowledgeFn itself for later use kfnParams::Union{Dict,Nothing} = nothing # store params of knowledgeFn itself for later use
timeStep::Number = 0.0 timeStep::Number = 0.0
# Bn contain error coefficient for both neurons and output neurons in one place # Bn contain error coefficient for both neurons and output neurons in one place
Bn::Vector{Float64} = Vector{Float64}() # error projection coefficient from kfn output's error to each neurons's error Bn::Vector{Float64} = Float64[] # error projection coefficient from kfn output's error to each neurons's error
neuronsArray::Union{Array,Nothing} = [] # put neurons here neuronsArray::Array{neuron} = neuron[] # put neurons here
""" put output neuron here. I seperate output neuron because """ put output neuron here. I seperate output neuron because
1. its calculation is difference than other neuron types 1. its calculation is difference than other neuron types
2. other neuron type will not induced to connnect to output neuron 2. other neuron type will not induced to connnect to output neuron
3. output neuron does not induced to connect to its own type """ 3. output neuron does not induced to connect to its own type """
outputNeuronsArray::Union{Array,Nothing} = [] outputNeuronsArray::Array{outputNeuron} = outputNeuron[]
""" "inference" = no learning params will be collected. """ "inference" = no learning params will be collected.
"learning" = neuron will accumulate epsilon_j, compute Δw_rec_change each time "learning" = neuron will accumulate epsilon_j, compute Δw_rec_change each time
@@ -103,18 +103,18 @@ Base.@kwdef mutable struct kfn_1 <: knowledgeFn
"reflect" = neuron will merge wRecChange into wRec then reset wRecChange. """ "reflect" = neuron will merge wRecChange into wRec then reset wRecChange. """
learningStage::String = "inference" learningStage::String = "inference"
error::Union{Float64,Nothing} = nothing error::Float64 = 0.0
firedNeurons::Array{Int64} = Vector{Int64}() # store unique id of firing neurons to be used when random neuron connection firedNeurons::Array{Int64} = Int64[] # store unique id of firing neurons to be used when random neuron connection
firedNeurons_t0::Union{Vector{Bool},Nothing} = nothing # store firing state of all neurons at t0 firedNeurons_t0::Union{Vector{Bool},Nothing} = nothing # store firing state of all neurons at t0
firedNeurons_t1::Union{Vector{Bool},Nothing} = nothing # store firing state of all neurons at t1 firedNeurons_t1::Union{Vector{Bool},Nothing} = nothing # store firing state of all neurons at t1
avgNeuronsFiringRate::Union{Float64,Nothing} = 0.0 # for displaying average firing rate over all neurons avgNeuronsFiringRate::Union{Float64,Nothing} = 0.0 # for displaying average firing rate over all neurons
avgNeurons_v_t1::Union{Float64,Nothing} = 0.0 # for displaying average v_t1 over all neurons avgNeurons_v_t1::Union{Float64,Nothing} = 0.0 # for displaying average v_t1 over all neurons
nExcitatory::Union{Array,Nothing} = Vector{Integer}() # list of excitatory neuron id nExcitatory::Array{Int64} =Int64[] # list of excitatory neuron id
nInhabitory::Union{Array,Nothing} = Vector{Integer}() # list of inhabitory neuron id nInhabitory::Array{Int64} = Int64[] # list of inhabitory neuron id
nExInType::Union{Array,Nothing} = Vector{Integer}() # list all neuron EX or IN nExInType::Array{Int64} = Int64[] # list all neuron EX or IN
excitatoryPercent::Integer = 60 # percentage of excitatory neuron, inhabitory percent will be 100-ExcitatoryPercent excitatoryPercent::Int64 = 60 # percentage of excitatory neuron, inhabitory percent will be 100-ExcitatoryPercent
end end
#------------------------------------------------------------------------------------------------100 #------------------------------------------------------------------------------------------------100
@@ -285,13 +285,13 @@ end
""" passthroughNeuron struct """ passthroughNeuron struct
""" """
Base.@kwdef mutable struct passthroughNeuron <: inputNeuron Base.@kwdef mutable struct passthroughNeuron <: inputNeuron
id::Union{Int64,Nothing} = nothing # ID of this neuron which is it position in knowledgeFn array id::Int64 = 0 # ID of this neuron which is it position in knowledgeFn array
type::String = "passthroughNeuron" type::String = "passthroughNeuron"
knowledgeFnName::Union{String,Nothing} = nothing # knowledgeFn that this neuron belongs to knowledgeFnName::String = "not defined" # knowledgeFn that this neuron belongs to
z_t::Bool = false z_t::Bool = false
z_t1::Bool = false z_t1::Bool = false
timeStep::Number = 0.0 # current time timeStep::Int64 = 0 # current time
ExInType::Integer = 1 # 1 excitatory, -1 inhabitory. input neuron is always excitatory ExInType::Int64 = 1 # 1 excitatory, -1 inhabitory. input neuron is always excitatory
end end
function passthroughNeuron(params::Dict) function passthroughNeuron(params::Dict)
@@ -315,14 +315,13 @@ end
""" lifNeuron struct """ lifNeuron struct
""" """
Base.@kwdef mutable struct lifNeuron <: computeNeuron Base.@kwdef mutable struct lifNeuron <: computeNeuron
id::Union{Int64,Nothing} = nothing # this neuron ID i.e. position of this neuron in knowledgeFn id::Int64 = 0 # this neuron ID i.e. position of this neuron in knowledgeFn
type::String = "lifNeuron" type::String = "lifNeuron"
ExInType::Integer = 1 # 1 excitatory, -1 inhabitory ExInType::Int64 = 1 # 1 excitatory, -1 inhabitory
knowledgeFnName::Union{String,Nothing} = nothing # knowledgeFn that this neuron belongs to knowledgeFnName::String = "not defined" # knowledgeFn that this neuron belongs to
subscriptionList::Union{Array{Int64},Nothing} = nothing # list of other neuron that this neuron synapse subscribed to subscriptionList::Array{Int64} = Int64[] # list of other neuron that this neuron synapse subscribed to
# subExInType::Array{Int64} = Vector{Int64}() # store ExIn type of subscribed neurons timeStep::Int64 = 0 # current time
timeStep::Number = 0.0 # current time wRec::Array{Float64} = Float64[] # synaptic weight (for receiving signal from other neuron)
wRec::Union{Array{Float64},Nothing} = nothing # synaptic weight (for receiving signal from other neuron)
v_t::Float64 = 0.0 # vᵗ, postsynaptic neuron membrane potential of previous timestep v_t::Float64 = 0.0 # vᵗ, postsynaptic neuron membrane potential of previous timestep
v_t1::Float64 = rand() # vᵗ⁺¹, postsynaptic neuron membrane potential at current timestep v_t1::Float64 = rand() # vᵗ⁺¹, postsynaptic neuron membrane potential at current timestep
v_th::Float64 = 1.0 # vᵗʰ, neuron firing threshold v_th::Float64 = 1.0 # vᵗʰ, neuron firing threshold
@@ -333,30 +332,29 @@ Base.@kwdef mutable struct lifNeuron <: computeNeuron
# forward calculation. Each neuron requires access to other neuron's firing status # forward calculation. Each neuron requires access to other neuron's firing status
# during v_t1 calculation hence I need a variable to hold z_t1 so that I'm not replacing z_t # during v_t1 calculation hence I need a variable to hold z_t1 so that I'm not replacing z_t
z_t1::Bool = false # neuron postsynaptic firing at current timestep (after neuron's calculation) z_t1::Bool = false # neuron postsynaptic firing at current timestep (after neuron's calculation)
z_i_t::Union{Array{Bool},Nothing} = nothing # neuron presynaptic firing at current timestep (which is other neuron postsynaptic firing of previous timestep) z_i_t::Array{Bool} = Bool[] # neuron presynaptic firing at current timestep (which is other neuron postsynaptic firing of previous timestep)
z_i_t_commulative::Union{Array{Integer},Nothing} = nothing # used to compute connection strength z_i_t_commulative::Array{Int64} = Int64[] # used to compute connection strength
synapticStrength::Union{Array{Float64},Nothing} = nothing synapticStrength::Array{Float64} = Float64[]
synapticStrengthLimit::Union{NamedTuple,Nothing} = (lowerlimit=(0=>0), upperlimit=(10=>10)) synapticStrengthLimit::NamedTuple = (lowerlimit=(-5=>-5), upperlimit=(5=>5))
gammaPd::Union{Float64,Nothing} = 0.3 # γ_pd, discount factor, value from paper gammaPd::Float64 = 0.3 # γ_pd, discount factor, value from paper
alpha::Union{Float64,Nothing} = nothing # α, neuron membrane potential decay factor alpha::Float64 = 0.0 # α, neuron membrane potential decay factor
phi::Union{Float64,Nothing} = nothing # ϕ, psuedo derivative phi::Float64 = 0.0 # ϕ, psuedo derivative
epsilonRec::Union{Array{Float64},Nothing} = nothing # ϵ_rec, eligibility vector for neuron spike epsilonRec::Array{Float64} = Float64[] # ϵ_rec, eligibility vector for neuron spike
decayedEpsilonRec::Union{Array{Float64},Nothing} = nothing # α * epsilonRec decayedEpsilonRec::Array{Float64} = Float64[] # α * epsilonRec
eRec::Union{Array{Float64},Nothing} = nothing # eligibility trace for neuron spike eRec::Array{Float64} = Float64[] # eligibility trace for neuron spike
delta::Union{Float64,Nothing} = 1.0 # δ, discreate timestep size in millisecond delta::Float64 = 1.0 # δ, discreate timestep size in millisecond
refractoryDuration::Union{Float64,Nothing} = 3 # neuron's refratory period in millisecond refractoryDuration::Int64 = 3 # neuron's refratory period in millisecond
# refractory_state_active::Union{Bool,Nothing} = false # if true, neuron is in refractory state and cannot process new information refractoryCounter::Int64 = 0
refractoryCounter::Integer = 0 tau_m::Float64 = 0.0 # τ_m, membrane time constant in millisecond
tau_m::Union{Float64,Nothing} = nothing # τ_m, membrane time constant in millisecond eta::Float64 = 0.01 # η, learning rate
eta::Union{Float64,Nothing} = 0.01 # η, learning rate wRecChange::Array{Float64} = Float64[] # Δw_rec, cumulated wRec change
wRecChange::Union{Array{Float64},Nothing} = nothing # Δw_rec, cumulated wRec change recSignal::Float64 = 0.0 # incoming recurrent signal
recSignal::Union{Float64,Nothing} = nothing # incoming recurrent signal alpha_v_t::Float64 = 0.0 # alpha * v_t
alpha_v_t::Union{Float64,Nothing} = nothing # alpha * v_t error::Float64 = 0.0 # local neuron error
error::Union{Float64,Nothing} = nothing # local neuron error # optimiser::Union{Any,Nothing} = load_optimiser("AdaBelief") # Flux optimizer
optimiser::Union{Any,Nothing} = load_optimiser("AdaBelief") # Flux optimizer
firingCounter::Integer = 0 # store how many times neuron fires firingCounter::Int64 = 0 # store how many times neuron fires
firingRateTarget::Float64 = 20.0 # neuron's target firing rate in Hz firingRateTarget::Float64 = 20.0 # neuron's target firing rate in Hz
firingDiff::Float64 = 0.0 # e-prop supplement paper equation 5 firingDiff::Float64 = 0.0 # e-prop supplement paper equation 5
firingRateError::Float64 = 0.0 # local neuron error w.r.t. firing regularization firingRateError::Float64 = 0.0 # local neuron error w.r.t. firing regularization
@@ -407,14 +405,13 @@ end
""" alifNeuron struct """ alifNeuron struct
""" """
Base.@kwdef mutable struct alifNeuron <: computeNeuron Base.@kwdef mutable struct alifNeuron <: computeNeuron
id::Union{Int64,Nothing} = nothing # this neuron ID i.e. position of this neuron in knowledgeFn id::Int64 = 0 # this neuron ID i.e. position of this neuron in knowledgeFn
type::String = "alifNeuron" type::String = "alifNeuron"
ExInType::Integer = -1 # 1 excitatory, -1 inhabitory ExInType::Int64 = -1 # 1 excitatory, -1 inhabitory
knowledgeFnName::Union{String,Nothing} = nothing # knowledgeFn that this neuron belongs to knowledgeFnName::String = "not defined" # knowledgeFn that this neuron belongs to
subscriptionList::Union{Array{Int64},Nothing} = nothing # list of other neuron that this neuron synapse subscribed to subscriptionList::Array{Int64} = Int64[] # list of other neuron that this neuron synapse subscribed to
# subExInType::Array{Int64} = Vector{Int64}() # store ExIn type of subscribed neurons timeStep::Int64 = 0 # current time
timeStep::Union{Number,Nothing} = nothing # current time wRec::Array{Float64} = Float64[] # synaptic weight (for receiving signal from other neuron)
wRec::Union{Array{Float64},Nothing} = nothing # synaptic weight (for receiving signal from other neuron)
v_t::Float64 = 0.0 # vᵗ, postsynaptic neuron membrane potential of previous timestep v_t::Float64 = 0.0 # vᵗ, postsynaptic neuron membrane potential of previous timestep
v_t1::Float64 = rand() # vᵗ⁺¹, postsynaptic neuron membrane potential at current timestep v_t1::Float64 = rand() # vᵗ⁺¹, postsynaptic neuron membrane potential at current timestep
v_th::Float64 = 1.0 # vᵗʰ, neuron firing threshold v_th::Float64 = 1.0 # vᵗʰ, neuron firing threshold
@@ -425,43 +422,42 @@ Base.@kwdef mutable struct alifNeuron <: computeNeuron
# forward calculation. Each neuron requires access to other neuron's firing status # forward calculation. Each neuron requires access to other neuron's firing status
# during v_t1 calculation hence I need a variable to hold z_t1 so that I'm not replacing z_t # during v_t1 calculation hence I need a variable to hold z_t1 so that I'm not replacing z_t
z_t1::Bool = false # neuron postsynaptic firing at current timestep (after neuron's calculation) z_t1::Bool = false # neuron postsynaptic firing at current timestep (after neuron's calculation)
z_i_t::Union{Array{Bool},Nothing} = nothing # neuron presynaptic firing at current timestep (which is other neuron postsynaptic firing of previous timestep) z_i_t::Array{Bool} = Bool[] # neuron presynaptic firing at current timestep (which is other neuron postsynaptic firing of previous timestep)
z_i_t_commulative::Union{Array{Integer},Nothing} = nothing # used to compute connection strength z_i_t_commulative::Array{Int64} = Int64[] # used to compute connection strength
synapticStrength::Union{Array{Float64},Nothing} = nothing synapticStrength::Array{Float64} = Float64[]
synapticStrengthLimit::Union{NamedTuple,Nothing} = (lowerlimit=(-5=>0), upperlimit=(5=>5)) synapticStrengthLimit::NamedTuple = (lowerlimit=(-5=>0), upperlimit=(5=>5))
alpha::Union{Float64,Nothing} = nothing # α, neuron membrane potential decay factor alpha::Float64 = 0.0 # α, neuron membrane potential decay factor
delta::Union{Float64,Nothing} = 1.0 # δ, discreate timestep size in millisecond delta::Float64 = 1.0 # δ, discreate timestep size in millisecond
epsilonRec::Union{Array{Float64},Nothing} = nothing # ϵ_rec(v), eligibility vector for neuron i spike epsilonRec::Array{Float64} = Float64[] # ϵ_rec(v), eligibility vector for neuron i spike
epsilonRecA::Union{Array{Float64},Nothing} = nothing # ϵ_rec(a) epsilonRecA::Array{Float64} = Float64[] # ϵ_rec(a)
decayedEpsilonRec::Union{Array{Float64},Nothing} = nothing # α * epsilonRec decayedEpsilonRec::Array{Float64} = Float64[] # α * epsilonRec
eRec_v::Union{Array{Float64},Nothing} = nothing # a component of neuron's eligibility trace resulted from v_t eRec_v::Array{Float64} = Float64[] # a component of neuron's eligibility trace resulted from v_t
eRec_a::Union{Array{Float64},Nothing} = nothing # a component of neuron's eligibility trace resulted from av_th eRec_a::Array{Float64} = Float64[] # a component of neuron's eligibility trace resulted from av_th
eRec::Union{Array{Float64},Nothing} = nothing # neuron's eligibility trace eRec::Array{Float64} = Float64[] # neuron's eligibility trace
eta::Union{Float64,Nothing} = 0.01 # eta, learning rate eta::Float64 = 0.01 # eta, learning rate
gammaPd::Union{Float64,Nothing} = 0.3 # γ_pd, discount factor, value from paper gammaPd::Float64 = 0.3 # γ_pd, discount factor, value from paper
phi::Union{Float64,Nothing} = nothing # ϕ, psuedo derivative phi::Float64 = 0.0 # ϕ, psuedo derivative
refractoryDuration::Union{Float64,Nothing} = 3 # neuron's refractory period in millisecond refractoryDuration::Int64 = 3 # neuron's refractory period in millisecond
# refractory_state_active::Union{Bool,Nothing} = false # if true, neuron is in refractory state and cannot process new information refractoryCounter::Int64 = 0
refractoryCounter::Integer = 0 tau_m::Float64 = 0.0 # τ_m, membrane time constant in millisecond
tau_m::Union{Float64,Nothing} = nothing # τ_m, membrane time constant in millisecond wRecChange::Array{Float64} = Float64[] # Δw_rec, cumulated wRec change
wRecChange::Union{Array{Float64},Nothing} = nothing # Δw_rec, cumulated wRec change recSignal::Float64 = 0.0 # incoming recurrent signal
recSignal::Union{Float64,Nothing} = nothing # incoming recurrent signal alpha_v_t::Float64 = 0.0 # alpha * v_t
alpha_v_t::Union{Float64,Nothing} = nothing # alpha * v_t error::Float64 = 0.0 # local neuron error
error::Union{Float64,Nothing} = nothing # local neuron error
optimiser::Union{Any,Nothing} = load_optimiser("AdaBelief") # Flux optimizer optimiser::Union{Any,Nothing} = load_optimiser("AdaBelief") # Flux optimizer
firingCounter::Integer = 0 # store how many times neuron fires firingCounter::Int64 = 0 # store how many times neuron fires
firingRateTarget::Float64 = 20.0 # neuron's target firing rate in Hz firingRateTarget::Float64 = 20.0 # neuron's target firing rate in Hz
firingDiff::Float64 = 0.0 # e-prop supplement paper equation 5 firingDiff::Float64 = 0.0 # e-prop supplement paper equation 5
firingRateError::Float64 = 0.0 # local neuron error w.r.t. firing regularization firingRateError::Float64 = 0.0 # local neuron error w.r.t. firing regularization
firingRate::Float64 = 0.0 # running average of firing rate, Hz firingRate::Float64 = 0.0 # running average of firing rate, Hz
tau_a::Union{Float64,Nothing} = nothing # τ_a, adaption time constant in millisecond tau_a::Float64 = 0.0 # τ_a, adaption time constant in millisecond
beta::Union{Float64,Nothing} = 0.15 # β, constant, value from paper beta::Float64 = 0.15 # β, constant, value from paper
rho::Union{Float64,Nothing} = nothing # ρ, threshold adaptation decay factor rho::Float64 = 0.0 # ρ, threshold adaptation decay factor
a::Union{Float64,Nothing} = 0.0 # threshold adaptation a::Float64 = 0.0 # threshold adaptation
av_th::Union{Float64,Nothing} = nothing # adjusted neuron firing threshold av_th::Float64 = 0.0 # adjusted neuron firing threshold
""" "inference" = no learning params will be collected. """ "inference" = no learning params will be collected.
"learning" = neuron will accumulate epsilon_j, compute Δw_rec_change each time "learning" = neuron will accumulate epsilon_j, compute Δw_rec_change each time
@@ -514,18 +510,17 @@ end
""" linearNeuron struct """ linearNeuron struct
""" """
Base.@kwdef mutable struct linearNeuron <: outputNeuron Base.@kwdef mutable struct linearNeuron <: outputNeuron
id::Union{Int64,Nothing} = nothing # ID of this neuron which is it position in knowledgeFn array id::Float64 = 0.0 # ID of this neuron which is it position in knowledgeFn array
type::String = "linearNeuron" type::String = "linearNeuron"
knowledgeFnName::Union{String,Nothing} = nothing # knowledgeFn that this neuron belongs to knowledgeFnName::String = "not defined" # knowledgeFn that this neuron belongs to
subscriptionList::Union{Array{Int64},Nothing} = nothing # list of other neuron that this neuron synapse subscribed to subscriptionList::Array{Int64} = Int64[] # list of other neuron that this neuron synapse subscribed to
timeStep::Union{Number,Nothing} = nothing # current time timeStep::Int64 = 0 # current time
# subExInType::Array{Int64} = Vector{Int64}() # store ExIn type of subscribed neurons wRec::Array{Float64} = Float64[] # synaptic weight (for receiving signal from other neuron)
wRec::Union{Array{Float64},Nothing} = nothing # synaptic weight (for receiving signal from other neuron)
v_t::Float64 = 0.0 # vᵗ, postsynaptic neuron membrane potential of previous timestep v_t::Float64 = 0.0 # vᵗ, postsynaptic neuron membrane potential of previous timestep
v_t1::Float64 = rand() # vᵗ⁺¹, postsynaptic neuron membrane potential at current timestep v_t1::Float64 = rand() # vᵗ⁺¹, postsynaptic neuron membrane potential at current timestep
v_th::Float64 = 1.0 # vᵗʰ, neuron firing threshold v_th::Float64 = 1.0 # vᵗʰ, neuron firing threshold
vRest::Float64 = 0.0 # resting potential after neuron fired vRest::Float64 = 0.0 # resting potential after neuron fired
vError::Union{Float64,Nothing} = nothing # used to compute model error vError::Float64 = 0.0 # used to compute model error
z_t::Bool = false # zᵗ, neuron postsynaptic firing of previous timestep z_t::Bool = false # zᵗ, neuron postsynaptic firing of previous timestep
# zᵗ⁺¹, neuron firing status at time = t+1. I need this because the way I calculate all # zᵗ⁺¹, neuron firing status at time = t+1. I need this because the way I calculate all
# neurons forward function at each timestep-by-timestep is to do every neuron # neurons forward function at each timestep-by-timestep is to do every neuron
@@ -535,27 +530,27 @@ Base.@kwdef mutable struct linearNeuron <: outputNeuron
# neuron presynaptic firing at current timestep (which is other neuron postsynaptic firing of # neuron presynaptic firing at current timestep (which is other neuron postsynaptic firing of
# previous timestep) # previous timestep)
z_i_t::Union{Array{Bool},Nothing} = nothing z_i_t::Array{Bool} = Bool[]
z_i_t_commulative::Union{Array{Integer},Nothing} = nothing # used to compute connection strength z_i_t_commulative::Array{Int64} = Int64[] # used to compute connection strength
synapticStrength::Union{Array{Float64},Nothing} = nothing synapticStrength::Array{Float64} = Float64[]
synapticStrengthLimit::Union{NamedTuple,Nothing} = (lowerlimit=(-5=>-5), upperlimit=(5=>5)) synapticStrengthLimit::NamedTuple = (lowerlimit=(-5=>-5), upperlimit=(5=>5))
gammaPd::Union{Float64,Nothing} = 0.3 # γ_pd, discount factor, value from paper gammaPd::Float64 = 0.3 # γ_pd, discount factor, value from paper
alpha::Union{Float64,Nothing} = nothing # α, neuron membrane potential decay factor alpha::Float64 = 0.0 # α, neuron membrane potential decay factor
phi::Union{Float64,Nothing} = nothing # ϕ, psuedo derivative phi::Float64 = 0.0 # ϕ, psuedo derivative
epsilonRec::Union{Array{Float64},Nothing} = nothing # ϵ_rec, eligibility vector for neuron spike epsilonRec::Array{Float64} = Float64[] # ϵ_rec, eligibility vector for neuron spike
decayedEpsilonRec::Union{Array{Float64},Nothing} = nothing # α * epsilonRec decayedEpsilonRec::Array{Float64} = Float64[] # α * epsilonRec
eRec::Union{Array{Float64},Nothing} = nothing # eligibility trace for neuron spike eRec::Array{Float64} = Float64[] # eligibility trace for neuron spike
delta::Union{Float64,Nothing} = 1.0 # δ, discreate timestep size in millisecond delta::Float64 = 1.0 # δ, discreate timestep size in millisecond
refractoryDuration::Union{Float64,Nothing} = 3 # neuron's refratory period in millisecond refractoryDuration::Int64 = 3 # neuron's refratory period in millisecond
refractoryCounter::Integer = 0 refractoryCounter::Int64 = 0
tau_out::Union{Float64,Nothing} = nothing # τ_out, membrane time constant in millisecond tau_out::Float64 = 0.0 # τ_out, membrane time constant in millisecond
eta::Union{Float64,Nothing} = 0.01 # η, learning rate eta::Float64 = 0.01 # η, learning rate
wRecChange::Union{Array{Float64},Nothing} = nothing # Δw_rec, cumulated wRec change wRecChange::Array{Float64} = Float64[] # Δw_rec, cumulated wRec change
recSignal::Union{Float64,Nothing} = nothing # incoming recurrent signal recSignal::Float64 = 0.0 # incoming recurrent signal
alpha_v_t::Union{Float64,Nothing} = nothing # alpha * v_t alpha_v_t::Float64 = 0.0 # alpha * v_t
firingCounter::Integer = 0 # store how many times neuron fires firingCounter::Int64 = 0 # store how many times neuron fires
end end
""" linear neuron outer constructor """ linear neuron outer constructor