Repository navigation
Expand file tree
/
Copy pathGAModel.m
More file actions
143 lines (119 loc) · 5.16 KB
/
Copy pathGAModel.m
File metadata and controls
143 lines (119 loc) · 5.16 KB
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
classdef GAModel < matlab.mixin.Heterogeneous & handle
%GAMODEL Summary of this class goes here
% Detailed explanation goes here
properties
forest = {}
% Blueprint for the layers
layersbp = {}
end
methods
function gamodel = GAModel()
end
function add(gamodel, layer)
if ~isa(layer, 'GALayer')
throw(MException('GAModel:notALayer', ...
'Not a GALayer.'));
end
gamodel.layersbp{end+1} = layer;
end
function gaseqmodel = newindividual(gamodel)
gaseqmodel = GASequentialModel();
for i = 1:length(gamodel.layersbp)
gaseqmodel.add(gamodel.layersbp{i}.copy());
end
gaseqmodel.compile();
gamodel.forest{end+1} = gaseqmodel;
end
function populate(gamodel, n)
% n is the size the of population
for i = 1:n
gamodel.newindividual();
end
end
function [minfitnesses, maxfitnesses] = run(gamodel, func, X, y, options, verbose)
% verbose can be ignored. By defulat: 1
if nargin < 6
verbose = 1;
end
nummodels = length(gamodel.forest);
minfitnesses = zeros(options.generations, 1);
maxfitnesses = zeros(options.generations, 1);
for generation = 1:options.generations
for i = 1:nummodels
if verbose == 2
if mod(i, 10) == 0 || i == 1
fprintf('[Generation %d / %d] Simulating: %d / %d\n', ...
generation, options.generations, i, nummodels);
end
end
func(gamodel.forest{i}, X, y);
end
gamodel.sortforest();
minfitnesses(generation) = gamodel.forest{nummodels}.fitness;
maxfitnesses(generation) = gamodel.forest{1}.fitness;
if verbose > 0 || ...
(verbose == -1 && generation == 1) || ...
(verbose == -1 && generation ~= 1 && maxfitnesses(generation) > maxfitnesses(generation - 1))
fprintf('[Generation [%d / %d] Fitness: %3.2f / %3.2f]\n', ...
generation, options.generations, ...
minfitnesses(generation), maxfitnesses(generation));
end
% Natural selection
keepidx = int32(nummodels * options.keeprate);
gamodel.forest = {gamodel.forest{:, 1:keepidx}};
fitnesses = cellfun(@(x)x.fitness, gamodel.forest);
chances = fitnesses / sum(fitnesses);
cp = [0, cumsum(chances)];
% Reproduction
for i = keepidx+1:nummodels
r = rand();
sela = find(r>cp, 1, 'last');
selb = sela;
while selb == sela
r = rand();
selb = find(r>cp, 1, 'last');
end
if sela == selb
disp("a=" + sela + " b=" + selb);
end
modela = gamodel.forest{sela};
modelb = gamodel.forest{selb};
newmodel = gamodel.newindividual();
% Set the parameters
for layeridx = 2:length(newmodel.layers)
newmodel.layers{layeridx}.W = modela.layers{layeridx}.W;
newmodel.layers{layeridx}.b = modela.layers{layeridx}.b;
newmodel.layers{layeridx}.crossover(modelb.layers{layeridx}.W, ...
modelb.layers{layeridx}.b);
newmodel.layers{layeridx}.mutate(options.mutationrate);
end
end
assert(nummodels == length(gamodel.forest));
end
end
function sortforest(gamodel)
fitnesses = cellfun(@(x)x.fitness, gamodel.forest);
[~,sortidx] = sort(fitnesses, "descend");
gamodel.forest = gamodel.forest(sortidx);
end
function mutateall(gamodel, options)
nummodels = length(gamodel.forest);
for i = 1:nummodels
numlayers = length(gamodel.forest{i}.layers);
for j = 1:numlayers
gamodel.forest{i}.layers{j}.mutate(options.mutationrate)
end
end
end
function replicatefrommodel(gamodel, model)
nummodels = length(gamodel.forest);
numlayers = length(model.layers);
for i = 1:nummodels
for j = 2:numlayers
gamodel.forest{i}.layers{j}.W = model.layers{j}.W;
gamodel.forest{i}.layers{j}.b = model.layers{j}.b;
end
end
end
end
end