-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathdev_nn_reg.tex
More file actions
292 lines (244 loc) · 11.1 KB
/
Copy pathdev_nn_reg.tex
File metadata and controls
292 lines (244 loc) · 11.1 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
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
\documentclass{tufte-handout}
\usepackage{../braph2_dev}
%\geometry{showframe} % display margins for debugging page layout
\title{Implement a New Neural Network Regressor}
\author[The BRAPH~2 Developers]{The BRAPH~2 Developers}
\begin{document}
\maketitle
\begin{abstract}
\noindent
This is the developer tutorial for implementing a new neural network regressor.
In this tutorial, you will learn how to create the generator file \fn{*.gen.m} for a new neural network regressor, which can then be compiled by \code{braph2genesis}. All kinds of neural network models are (direct or indirect) extensions of the base element \code{NNBase}. Here, you will use as example the neural network regressor \code{NNRegressorMLP} (multi-layer perceptron regressor).
\end{abstract}
\tableofcontents
\clearpage
\section{Implementation of a neural network regressor (\code{NNRegressorMLP})}
You will start by implementing in detail \code{NNRegressorMLP}, which is a direct extension of \code{NNBase}.
A multi-layer perceptron regressor \code{NNRegressorMLP} comprises a multi-layer perceptron regressor model and a given dataset.
\begin{lstlisting}[
label=cd:m:NNRegressorMLP:header,
caption={
{\bf NNRegressorMLP element header.}
The \code{header} section of the generator code in \fn{\_NNRegressorMLP.gen.m} provides the general information about the \code{NNRegressorMLP} element.
}
]
%% ¡header!
NNRegressorMLP < NNBase (nn, multi-layer perceptron regressor) comprises a multi-layer perceptron regressor model and a given dataset. ¥\circled{1}\circlednote{1}{ defines \code{NNRegressorMLP} as a subclass of \code{NNBase}. The moniker will be \code{nn}.}¥
%%% ¡description!
A neural network multi-layer perceptron regressor (NNRegressorMLP) comprises a multi-layer perceptron regressor model and a given dataset.
NNRegressorMLP trains the multi-layer perceptron regressor with a formatted inputs ("CB", channel and batch) derived from the given dataset.
%%% ¡build!
1
\end{lstlisting}
\begin{lstlisting}[
label={cd:m:NNRegressorMLP:prop_update},
caption={
{\bf NNRegressorMLP element prop update.}
The \code{props\_update} section of the generator code in \fn{\_NNRegressorMLP.gen.m} updates the properties of the \code{NNRegressorMLP} element. This defines the core properties of the data point.
}
]
%% ¡props_update!
%%% ¡prop!
NAME (constant, string) is the name of the neural network multi-layer perceptron regressor.
%%%% ¡default!
'NNRegressorMLP'
%%% ¡prop!
DESCRIPTION (constant, string) is the description of the neural network multi-layer perceptron regressor.
%%%% ¡default!
'A neural network multi-layer perceptron regressor (NNRegressorMLP) comprises a multi-layer perceptron regressor model and a given dataset. NNRegressorMLP trains the multi-layer perceptron regressor with a formatted inputs ("CB", channel and batch) derived from the given dataset.'
%%% ¡prop!
TEMPLATE (parameter, item) is the template of the neural network multi-layer perceptron regressor.
%%%% ¡settings!
'NNRegressorMLP'
%%% ¡prop!
ID (data, string) is a few-letter code for the neural network multi-layer perceptron regressor.
%%%% ¡default!
'NNRegressorMLP ID'
%%% ¡prop!
LABEL (metadata, string) is an extended label of the neural network multi-layer perceptron regressor.
%%%% ¡default!
'NNRegressorMLP label'
%%% ¡prop!
NOTES (metadata, string) are some specific notes about the neural network multi-layer perceptron regressor.
%%%% ¡default!
'NNRegressorMLP notes'
%%% ¡prop! ¥\circled{1}\circlednote{1}{ defines \code{NNDataset} which contains the \code{NNDataPoint} to train this regressor.}¥
D (data, item) is the dataset to train the neural network model, and its data point class DP_CLASS defaults to one of the compatible classes within the set of DP_CLASSES.
%%%% ¡settings!
'NNDataset'
%%%% ¡default!
NNDataset('DP_CLASS', 'NNDataPoint_CON_REG')
%%% ¡prop!
DP_CLASSES (parameter, classlist) is the list of compatible data points.
%%%% ¡default! ¥\circled{2}\circlednote{2}{ defines the compatible \code{NNDataPoint} classes with this \code{NNRegressorMLP}.}¥
{'NNDataPoint_CON_REG' 'NNDataPoint_CON_FUN_MP_REG' 'NNDataPoint_Graph_REG' 'NNDataPoint_Measure_REG'}
%%% ¡prop!
INPUTS (query, cell) constructs the data in the CB (channel-batch) format.
%%%% ¡calculate! ¥\circled{3}\circlednote{3}{ is a query that transforms the input data of \code{NNDataPoint} to the CB (channel-batch) format by flattening its included cells.}¥
% inputs = nn.get('inputs', D) returns a cell array with the
% inputs for all data points in dataset D.
if isempty(varargin)
value = {};
return
end
d = varargin{1};
inputs_group = d.get('INPUTS');
if isempty(inputs_group)
value = {};
else
flattened_inputs_group = [];
for i = 1:1:length(inputs_group)
inputs_individual = inputs_group{i};
flattened_inputs_individual = [];
while ~isempty(inputs_individual)
currentData = inputs_individual{end}; % Get the last element from the stack
inputs_individual = inputs_individual(1:end-1); % Remove the last element
if iscell(currentData)
% If it's a cell array, add its contents to the stack
inputs_individual = [inputs_individual currentData{:}];
else
% If it's numeric or other data, append it to the vector
flattened_inputs_individual = [currentData(:); flattened_inputs_individual];
end
end
flattened_inputs_group = [flattened_inputs_group; flattened_inputs_individual'];
end
value = {flattened_inputs_group};
end
%%% ¡prop!
TARGETS (query, cell) constructs the targets in the CB (channel-batch) format.
%%%% ¡calculate! ¥\circled{4}\circlednote{4}{ is a query that collects all the target values from all data points.}¥
% targets = nn.get('PREDICT', D) returns a cell array with the
% targets for all data points in dataset D.
if isempty(varargin)
value = {};
return
end
d = varargin{1};
targets = d.get('TARGETS');
if isempty(targets)
value = {};
else
nn_targets = [];
for i = 1:1:length(targets)
target = cell2mat(targets{i});
nn_targets = [nn_targets; target(:)'];
end
value = {nn_targets};
end
%%% ¡prop!
MODEL (result, net) is a trained neural network model.
%%%% ¡calculate! ¥\circled{5}\circlednote{5}{ trains the regressor.}¥
inputs = cell2mat(nn.get('INPUTS', nn.get('D'))); ¥\circled{6}¥
targets = cell2mat(nn.get('TARGETS', nn.get('D'))); ¥\circled{7}\circlednote{6}{ and \circled{7} extract the inputs and targets.}¥
if isempty(inputs) || isempty(targets)
value = network();
else
number_features = size(inputs, 2);
number_targets = size(targets, 2);
layers = nn.get('LAYERS');¥\circled{8}\circlednote{8}{ defines the neural network architecture with user-specified number of neurons and number of layers.}¥
nn_architecture = [featureInputLayer(number_features, 'Name', 'Input')];
for i = 1:1:length(layers)
nn_architecture = [nn_architecture
fullyConnectedLayer(layers(i), 'Name', ['Dense_' num2str(i)])
batchNormalizationLayer('Name', ['BatchNormalization_' num2str(i)])
dropoutLayer('Name', ['Dropout_' num2str(i)])
];
end
nn_architecture = [nn_architecture
reluLayer('Name', 'Relu_output')
fullyConnectedLayer(number_targets, 'Name', 'Dense_output')
regressionLayer('Name', 'Output')
];
% specify trianing options ¥\circled{9}\circlednote{9}{ defines the neural network training options.}¥
options = trainingOptions( ...
nn.get('SOLVER'), ...
'MiniBatchSize', nn.get('BATCH'), ...
'MaxEpochs', nn.get('EPOCHS'), ...
'Shuffle', nn.get('SHUFFLE'), ...
'Plots', nn.get('PLOT_TRAINING'), ...
'Verbose', nn.get('VERBOSE') ...
);
% train the neural network ¥\circled{10}\circlednote{10}{ trains the model with those parameters and the neural network architecture.}¥
value = trainNetwork(inputs, targets, nn_architecture, options);
end
\end{lstlisting}
\begin{lstlisting}[
label={cd:m:NNRegressorMLP:props},
caption={
{\bf NNRegressorMLP element props.}
The \code{props} section of generator code in \fn{\_NNRegressorMLP.gen.m} defines the properties to be used in \fn{NNRegressorMLP}.
}
]
%% ¡props!
%%% ¡prop! ¥\circled{1}\circlednote{1}{ defines the number of neuron per layer. For example, \code{[32 32]} represents two layers, each containing 32 neurons.}¥
LAYERS (data, rvector) defines the number of layers and their neurons.
%%%% ¡default!
[32 32]
%%%% ¡gui!
pr = PanelPropRVectorSmart('EL', nn, 'PROP', NNRegressorMLP.LAYERS, ...
'MIN', 0, 'MAX', 2000, ...
'DEFAULT', NNRegressorMLP.getPropDefault('LAYERS'), ...
varargin{:});
%%% ¡prop!
WAITBAR (gui, logical) detemines whether to show the waitbar.
%%%% ¡default!
true
\end{lstlisting}
\clearpage
\begin{lstlisting}[
label=cd:m:NNRegressprMLP:tests,
caption={
{\bf NNRegressprMLP element tests.}
The \code{tests} section from the element generator \fn{\_NNRegressprMLP.gen.m}.
A test for creating example files should be prepared to test the properties of the data point. Furthermore, an additional test should be prepared for validating the value of input and target for the data point.
}
]
%% ¡tests!
%%% ¡test!
%%%% ¡name!
train the regressor with example data
%%%% ¡code!
% ensure the example data is generated
if ~isfile([fileparts(which('NNDataPoint_CON_REG')) filesep 'Example data NN REG CON XLS' filesep 'atlas.xlsx'])
create_data_NN_REG_CON_XLS() % create example files
end
% Load BrainAtlas
im_ba = ImporterBrainAtlasXLS( ...
'FILE', [fileparts(which('NNDataPoint_CON_REG')) filesep 'Example data NN REG CON XLS' filesep 'atlas.xlsx'], ...
'WAITBAR', true ...
);
ba = im_ba.get('BA');
% Load Groups of SubjectCON
im_gr = ImporterGroupSubjectCON_XLS( ...
'DIRECTORY', [fileparts(which('NNDataPoint_CON_REG')) filesep 'Example data NN REG CON XLS' filesep 'CON_Group_XLS'], ...
'BA', ba, ...
'WAITBAR', true ...
);
gr = im_gr.get('GR');
% create a item list of NNDataPoint_CON_REG
it_list = cellfun(@(x) NNDataPoint_CON_REG( ...
'ID', x.get('ID'), ...
'SUB', x, ...
'TARGET_IDS', x.get('VOI_DICT').get('KEYS')), ...
gr.get('SUB_DICT').get('IT_LIST'), ...
'UniformOutput', false);
% create a NNDataPoint_CON_REG DICT
dp_list = IndexedDictionary(...
'IT_CLASS', 'NNDataPoint_CON_REG', ...
'IT_LIST', it_list ...
);
% create a NNData containing the NNDataPoint_CON_REG DICT
d = NNDataset( ...
'DP_CLASS', 'NNDataPoint_CON_REG', ...
'DP_DICT', dp_list ...
);
nn = NNRegressorMLP('D', d, 'LAYERS', [20 20]);
trained_model = nn.get('MODEL');
% Check whether the number of fully-connected layers matches (excluding Dense_output layer)¥\circled{1}\circlednote{1}{ checks whether the number of layers from the trained model is correctly set.}¥
assert(length(nn.get('LAYERS')) == sum(contains({trained_model.Layers.Name}, 'Dense')) - 1, ...
[BRAPH2.STR ':NNRegressorMLP:' BRAPH2.FAIL_TEST], ...
'NNRegressorMLP does not construct the layers correctly. The number of the inputs should be the same as the length of dense layers the property.' ...
)
\end{lstlisting}
\end{document}