77 lines
3.5 KiB
MiniZinc
77 lines
3.5 KiB
MiniZinc
include "fzn_neural_net.mzn";
|
|
include "fzn_neural_net_reif.mzn";
|
|
|
|
|
|
enum NEURON_TYPE = { NT_RELU, NT_STEP, NT_LINEAR, NT_SOFTPLUS };
|
|
|
|
/** @group globals.learning
|
|
constrain the output layer of a neural net to take the value defined by the input layer.
|
|
the arguments are
|
|
\a inputs: an array of float variables
|
|
\a input_ids: array[int] of node
|
|
\a outputs: an array of float variables
|
|
\a output_ids: array[int] of node
|
|
\a bias: array[node] of float
|
|
\a edge_weight: array[edge] of float (dummy one at end!)
|
|
\a edge_parent: array[edge] of neuron (start neuron for edge)
|
|
\a first_edge: array[node] of 1..m+1
|
|
\a neuron_type: { NT_RELU, NT_STEP, NT_LINEAR, NT_SOFTPLUS }
|
|
*/
|
|
predicate neural_net(array[int] of var float: inputs,
|
|
array[int] of int: input_ids,
|
|
array[int] of var float: outputs,
|
|
array[int] of int: output_ids,
|
|
array[int] of float: bias,
|
|
array[int] of float: edge_weight,
|
|
array[int] of int: edge_parent,
|
|
array[int] of int: first_edge,
|
|
NEURON_TYPE: neuron_type) =
|
|
assert(index_set(inputs) == index_set(input_ids),
|
|
"neural_net: number of input vars not equal to number of input_ids") /\
|
|
assert(index_set(outputs) == index_set(output_ids),
|
|
"neural_net: number of output vars not equal to number of output_ids") /\
|
|
let { set of int: node = index_set(bias) } in
|
|
let { set of int: edge = index_set(edge_weight) } in
|
|
assert(index_set(edge_parent) == edge,
|
|
"neural_net: index sets of edge_weight and edge_parent do not agree") /\
|
|
assert(index_set(first_edge) == node,
|
|
"neural_new: index sets of bias and first_edge do not agree") /\
|
|
forall(i in index_set(input_ids))
|
|
(assert(input_ids[i] in node,
|
|
"neural_net: input_ids\(i) = \(input_ids[i]) not a correct node number"))
|
|
/\
|
|
forall(i in index_set(output_ids))
|
|
(assert(output_ids[i] in node,
|
|
"neural_net: output_ids\(i) = \(output_ids[i]) not a correct node number"))
|
|
/\
|
|
forall(i in index_set(first_edge))
|
|
(assert(first_edge[i] in edge,
|
|
"neural_net: first_edge\(i) = \(first_edge[i]) not a correct edge number"))
|
|
/\
|
|
forall(i in index_set(edge_parent))
|
|
(assert(edge_parent[i] in edge,
|
|
"neural_net: edge_parent\(i) = \(edge_parent[i]) not a correct node number"))
|
|
/\
|
|
assert(mincreasing(first_edge),
|
|
"neural_net: first_edge array is not in increasing order")
|
|
/\
|
|
fzn_neural_net(inputs,input_ids,outputs,output_ids,bias,
|
|
edge_weight,edge_parent,first_edge,neuron_type);
|
|
|
|
test mincreasing(array[int] of int: x) =
|
|
forall(i in index_set(x) diff { max(index_set(x)) })
|
|
(x[i] <= x[i+1]);
|
|
|
|
predicate neural_net(array[int] of var float: inputs,
|
|
array[int] of int: input_ids,
|
|
array[int] of var float: outputs,
|
|
array[int] of int: output_ids,
|
|
array[int] of float: bias,
|
|
array[int] of float: edge_weight,
|
|
array[int] of int: edge_parent,
|
|
array[int] of int: first_edge) =
|
|
neural_net(inputs,input_ids,outputs,output_ids,bias,
|
|
edge_weight,edge_parent,first_edge,NT_RELU);
|
|
|
|
%-----------------------------------------------------------------------------%
|