function sheet12

% Learning rate
rate = 0.05;

% Iterations of learning
iterations = 1000;

% Create XOR problem (2 dimensions + 1 bias dimension)
[X,Y] = create_data();

% Init network with 3 input, 5 hidden and 1 output neuron
N = net_init(3, 5, 1);

% Stochastic learning
for i = 1:iterations
    % Select random point
    j = ceil(rand() * length(Y));

    % Forward/backward pass
    N = net_forward(N, X(:,j));
    N = net_backward(N, Y(j));
    N = net_update(N, rate);

    % Store error at point j
    e(i) = mean((N.Y2 - Y(j)).^2);
end

clf; plot(e);
ylabel('Iterations');
xlabel('Mean squared error');

function [X,Y] = create_data()
X = [ 1 1; -1 -1; 1 -1; -1 1]';
Y = [ 1  1  -1 -1];
X = [X ; ones(size(Y))];

%% 
% Initialize neural network 
% Input:
%    n     Number of input neurons
%    k     Number of hidden neurons
%    m     Number of output neurons
% Output:
%    N.W1  Weight matrix (n x k)
%    N.W2  Weight matrix (k x m)
function N = net_init(n,k,m)
...

%%
% Forward pass through network
% Input:
%    N     Network structure
%    x     Input vector (1 x n)
% Output:
%    N.Y0  Input vector (1 x n)  
%    N.Y1  Output at hidden layer (1 x k)
%    N.Y2  Output at output layer (1 x m)
function N = net_forward(N, x)
...

%%
% Backward pass through network
% Input:
%    N     Network structure
%    y     Target vector (1 x m)
% Output:
%    N.D2  Partial derivative at output layer (1 x m)
%    N.D1  Partial derivative at hidden layer (1 x k)
function N = net_backward(N, y)
...

%%
% Update the network weights
% Input:
%    N     Network structure
%    r     Learning rate
% Output:
%    N.W1  Updated weights
%    N.W2  Updated weights
function N = net_update(N, r)
...
