Daniel@0: %DEMSOM1 Demonstrate SOM for visualisation. Daniel@0: % Daniel@0: % Description Daniel@0: % This script demonstrates the use of a SOM with a two-dimensional Daniel@0: % grid to map onto data in two-dimensional space. Both on-line and Daniel@0: % batch training algorithms are shown. Daniel@0: % Daniel@0: % See also Daniel@0: % SOM, SOMPAK, SOMTRAIN Daniel@0: % Daniel@0: Daniel@0: % Copyright (c) Ian T Nabney (1996-2001) Daniel@0: Daniel@0: Daniel@0: randn('state', 42); Daniel@0: rand('state', 42); Daniel@0: nin = 2; Daniel@0: ndata = 300; Daniel@0: % Give data an offset so that network has something to learn. Daniel@0: x = rand(ndata, nin) + ones(ndata, 1)*[1.5 1.5]; Daniel@0: Daniel@0: clc; Daniel@0: disp('This demonstration of the SOM, or Kohonen network, shows how the') Daniel@0: disp('network units after training lie in regions of high data density.') Daniel@0: disp('First we show the data, which is generated uniformly from a square.') Daniel@0: disp('Red crosses denote the data and black dots are the initial locations') Daniel@0: disp('of the SOM units.') Daniel@0: disp(' ') Daniel@0: disp('Press any key to continue.') Daniel@0: pause Daniel@0: net = som(nin, [8, 7]); Daniel@0: c1 = sompak(net); Daniel@0: h1 = figure; Daniel@0: plot(x(:, 1), x(:, 2), 'r+'); Daniel@0: hold on Daniel@0: plot(c1(:,1), c1(:, 2), 'k.'); Daniel@0: drawnow; % Force figure to be drawn before training starts Daniel@0: options = foptions; Daniel@0: Daniel@0: % Ordering phase Daniel@0: options(1) = 1; Daniel@0: options(14) = 50; Daniel@0: %options(14) = 5; % Just for testing Daniel@0: options(18) = 0.9; % Initial learning rate Daniel@0: options(16) = 0.05; % Final learning rate Daniel@0: options(17) = 8; % Initial neighbourhood size Daniel@0: options(15) = 1; % Final neighbourhood size Daniel@0: Daniel@0: disp('The SOM network is trained in two phases using an on-line algorithm.') Daniel@0: disp('Initially the neighbourhood is set to 8 and is then reduced') Daniel@0: disp('linearly to 1 over the first 50 iterations.') Daniel@0: disp('Each iteration consists of a pass through the complete') Daniel@0: disp('dataset, while the weights are adjusted after each pattern.') Daniel@0: disp('The learning rate is reduced linearly from 0.9 to 0.05.') Daniel@0: disp('This ordering phase puts the units in a rough grid shape.') Daniel@0: disp('Blue circles denote the units at the end of this phase.') Daniel@0: disp(' ') Daniel@0: disp('Press any key to continue.') Daniel@0: pause Daniel@0: net2 = somtrain(net, options, x); Daniel@0: c2 = sompak(net2); Daniel@0: plot(c2(:, 1), c2(:, 2), 'bo'); Daniel@0: drawnow; Daniel@0: Daniel@0: % Convergence phase Daniel@0: options(1) = 1; Daniel@0: options(14) = 400; Daniel@0: options(18) = 0.05; Daniel@0: options(16) = 0.01; Daniel@0: options(17) = 0; Daniel@0: options(15) = 0; Daniel@0: Daniel@0: disp('The second, convergence, phase of learning just updates the winning node.') Daniel@0: disp('The learning rate is reduced from 0.05 to 0.01 over 400 iterations.') Daniel@0: disp('Note how the error value does not decrease monotonically; it is') Daniel@0: disp('difficult to decide when training is complete in a principled way.') Daniel@0: disp('The units are plotted as green stars.') Daniel@0: disp(' ') Daniel@0: disp('Press any key to continue.') Daniel@0: pause Daniel@0: net3 = somtrain(net2, options, x); Daniel@0: c3 = sompak(net3); Daniel@0: plot(c3(:, 1), c3(:, 2), 'g*'); Daniel@0: drawnow; Daniel@0: Daniel@0: % Now try batch training Daniel@0: options(1) = 1; Daniel@0: options(6) = 1; Daniel@0: options(14) = 50; Daniel@0: options(17) = 3; Daniel@0: options(15) = 0; Daniel@0: disp('An alternative approach to the on-line algorithm is a batch update') Daniel@0: disp('rule. Each unit is updated to be the average weights') Daniel@0: disp('in a neighbourhood (which reduces from 3 to 0) over 50 iterations.'); Daniel@0: disp('Note how the error is even more unstable at first, though eventually') Daniel@0: disp('it does converge.') Daniel@0: disp('The final units are shown as black triangles.') Daniel@0: disp(' ') Daniel@0: disp('Press any key to continue.') Daniel@0: pause Daniel@0: net4 = somtrain(net, options, x); Daniel@0: c4 = sompak(net4); Daniel@0: plot(c4(:, 1), c4(:, 2), 'k^') Daniel@0: legend('Data', 'Initial weights', 'Weights after ordering', ... Daniel@0: 'Weights after convergence', 'Batch weights', 2); Daniel@0: drawnow; Daniel@0: Daniel@0: disp(' ') Daniel@0: disp('Press any key to end.') Daniel@0: disp(' ') Daniel@0: pause Daniel@0: Daniel@0: close(h1);