-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathneuron.erl
86 lines (78 loc) · 2.91 KB
/
neuron.erl
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
-module(neuron).
-compile(export_all).
-include("records.hrl").
-define(DELTA_MULTIPLIER,math:pi()*2).
-define(SAT_LIMIT,math:pi()*2).
gen(ExoSelf_PId,Node)->
spawn(Node,?MODULE,prep,[ExoSelf_PId]).
prep(ExoSelf_PId) ->
rand:seed(exsss),
receive
{ExoSelf_PId,{Id,Cx_PId,AF,Input_PIdPs,Output_PIds}} ->
loop(Id,ExoSelf_PId,Cx_PId,AF,{Input_PIdPs,Input_PIdPs},Output_PIds,0)
end.
loop(Id,ExoSelf_PId,Cx_PId,AF,{[{Input_PId,Weights}|Input_PIdPs],MInput_PIdPs},Output_PIds,Acc)->
receive
{Input_PId,forward,Input}->
Result = dot(Input,Weights,0),
loop(Id,ExoSelf_PId,Cx_PId,AF,{Input_PIdPs,MInput_PIdPs},Output_PIds,Result+Acc);
{ExoSelf_PId,weight_backup}->
put(weights,MInput_PIdPs),
loop(Id,ExoSelf_PId,Cx_PId,AF,{[{Input_PId,Weights}|Input_PIdPs],MInput_PIdPs},Output_PIds,Acc);
{ExoSelf_PId,weight_restore}->
RInput_PIdPs = get(weights),
loop(Id,ExoSelf_PId,Cx_PId,AF,{RInput_PIdPs,RInput_PIdPs},Output_PIds,Acc);
{ExoSelf_PId,weight_perturb}->
PInput_PIdPs=perturb_IPIdPs(MInput_PIdPs),
loop(Id,ExoSelf_PId,Cx_PId,AF,{PInput_PIdPs,PInput_PIdPs},Output_PIds,Acc);
{ExoSelf_PId,get_backup}->
ExoSelf_PId ! {self(),Id,MInput_PIdPs},
loop(Id,ExoSelf_PId,Cx_PId,AF,{[{Input_PId,Weights}|Input_PIdPs],MInput_PIdPs},Output_PIds,Acc);
{ExoSelf_PId,terminate}->
ok
end;
loop(Id,ExoSelf_PId,Cx_PId,AF,{[Bias],MInput_PIdPs},Output_PIds,Acc)->
Output = neuron:AF(Acc+Bias),
[Output_PId ! {self(),forward,[Output]} || Output_PId <- Output_PIds],
loop(Id,ExoSelf_PId,Cx_PId,AF,{MInput_PIdPs,MInput_PIdPs},Output_PIds,0);
loop(Id,ExoSelf_PId,Cx_PId,AF,{[],MInput_PIdPs},Output_PIds,Acc)->
Output = neuron:AF(Acc),
[Output_PId ! {self(),forward,[Output]} || Output_PId <- Output_PIds],
loop(Id,ExoSelf_PId,Cx_PId,AF,{MInput_PIdPs,MInput_PIdPs},Output_PIds,0).
dot([I|Input],[W|Weights],Acc) ->
dot(Input,Weights,I*W+Acc);
dot([],[],Acc)->
Acc.
tanh(Val)->
math:tanh(Val).
perturb_IPIdPs(Input_PIdPs)->
Tot_Weights=lists:sum([length(Weights) || {_Input_PId,Weights}<-Input_PIdPs]),
MP = 1/math:sqrt(Tot_Weights),
perturb_IPIdPs(MP,Input_PIdPs,[]).
perturb_IPIdPs(MP,[{Input_PId,Weights}|Input_PIdPs],Acc)->
U_Weights = perturb_weights(MP,Weights,[]),
perturb_IPIdPs(MP,Input_PIdPs,[{Input_PId,U_Weights}|Acc]);
perturb_IPIdPs(MP,[Bias],Acc)->
U_Bias = case rand:uniform() < MP of
true-> sat((rand:uniform()-0.5)*?DELTA_MULTIPLIER+Bias,-?SAT_LIMIT,?SAT_LIMIT);
false -> Bias
end,
lists:reverse([U_Bias|Acc]);
perturb_IPIdPs(_MP,[],Acc)->
lists:reverse(Acc).
perturb_weights(MP,[W|Weights],Acc)->
U_W = case rand:uniform() < MP of
true->
sat((rand:uniform()-0.5)*?DELTA_MULTIPLIER+W,-?SAT_LIMIT,?SAT_LIMIT);
false ->
W
end,
perturb_weights(MP,Weights,[U_W|Acc]);
perturb_weights(_MP,[],Acc)->
lists:reverse(Acc).
sat(Val,Min,Max)->
if
Val < Min -> Min;
Val > Max -> Max;
true -> Val
end.