ISODATA zhlukovací algoritmus
Iterative Self-Organizing Data Analysis Technique (ISODATA) algoritmus je použitý na nájdenie zhlukov v obrázku.
Použitý algoritmus je prebratý z dizertačnej práce Slavka Vasilica zo strany 41. Implementácia algoritmu je popísaná v článku ISODATA algoritmus - implementácia školského zadania.
Návod na spustenie
Do programu je potrebné vložiť obrázok vo formáte BMP (napr. špirála), na ktorom sa bude neuronová sieť učiť.
V programe je možné nastaviť veľkosť trénovacej množiny. To je počet náhodne vybraných bodov, ktoré patria do obrázka (v našom prípade do špirály). Parameter stability/plasticity určuje veľkosť zhlukov.
Po kliknutí na tlačidlo "Štart" sa neurónová sieť začne učiť. To môže trvať niekoľko sekúnd, v závislosti od rýchlosti vášho počítača. Po skončení učenia sa výsledok zobrazí na stránke. Modré body reprezentujú trénovacie množinu, červené body sú hodnoty váh na druhej vrstve neurónovej siete a obdlžníky znázorňujú hranice zhlukov.
Program
Program je skrátený a znázornuje len učiacu funkciu.
// number of neurons in layer
var num_clusters = 0;
// number of samples that belongs to cluster
var n = new Array();
for(var s=0; s<train_set_length; s++)
{
var sample = train_set[s];
var sample_in = sample['in'];
var winner = get_winner(sample_in, num_inputs);
var winner_id = winner.id;
// create new cluster
if(winner.dist > threshold)
{
weights.push(sample_in.slice(0));
num_clusters++;
var new_id = weights.length - 1;
n[new_id] = 1;
sample['c'] = new_id;
continue;
}
// remember that sample belongs to cluster
sample['c'] = winner_id;
// change weight of winning neuron
for(var i=0; i<num_inputs; i++)
{
weights[winner_id][i] = ((n[winner_id] * weights[winner_id][i]) / (n[winner_id] + 1)) + (sample_in[i] / (n[winner_id] + 1));
}
n[winner_id]++;
}
var changed;
do
{
changed = false;
for(var s=0; s<train_set_length; s++)
{
var sample = train_set[s];
var sample_in = sample['in'];
// sample belongs to cluster
var c = sample['c'];
var winner = get_winner(sample_in, num_inputs);
if(winner.dist > threshold)
{
weights.push(sample_in.slice(0));
num_clusters++;
var new_id = weights.length - 1;
n[new_id] = 1;
sample['c'] = new_id;
for(var i=0; i<num_inputs; i++)
{
weights[c][i] = ((n[c] * weights[c][i]) / (n[c] - 1)) - (sample_in[i] / (n[c] - 1));
}
n[c]--;
changed = true;
break;
}
var id = winner.id;
if(id != c)
{
for(var i=0; i<num_inputs; i++)
{
weights[id][i] = ((n[id] * weights[id][i]) / (n[id] + 1)) + (sample_in[i] / (n[id] + 1));
weights[c][i] = ((n[c] * weights[c][i]) / (n[c] - 1)) - (sample_in[i] / (n[c] - 1));
}
n[id]++;
n[c]--;
sample['c'] = id;
changed = true;
break;
}
}
}
while(changed)