-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLayer.m
73 lines (52 loc) · 1.96 KB
/
Layer.m
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
classdef Layer
# Define the function and its derivative as tributes
properties
# Define important properties
neurons = 0;
weights = [];
funct = 0;
optim = "";
epsilon = 0.001;
limit = 1;
endproperties
methods
# Constructor
function layer = Layer(input_size, output_size, funct, optim)
display(optim);
# Store the number of neurons per layer
layer.neurons = input_size + 1;
# The +1 is to take the bias into account
layer.weights = rand([layer.neurons output_size]);
# Save the activation function and its derivative
layer.funct = funct;
layer.optim = optim;
endfunction
# Takes an row vector as input adds the bias and forwards
# it into the layer
function y = forward(layer, x)
# Add the bias
x = [x 1];
# Forward
y = layer.funct.f(x * layer.weights);
endfunction
# Takes the inputs of the network
function [x_grad w_grad] = backward(layer, grad, inputs, outputs)
# Calc the gradient using a defined optim
switch(layer.optim)
case "cg"
g = cg_min(layer.funct.fc, layer.funct.dfc, outputs', [1 layer.epsilon 0 layer.limit])';
g = g ./ -norm(g); # Make g a unitary vector since all we need is the direction
case "dg"
g = layer.funct.df(outputs);
endswitch
# Calc the gradient of the actv function
# IxO =IxO .* IxO
grad = grad .* g;
# Calc weight gradient and input grad
# NxO = NxI * IxO
w_grad = inputs' * grad;
# I+1xI= I+1xO * OxI
x_grad = layer.weights * grad';
endfunction
endmethods
endclassdef