Тяпничный Кохонен.

MasterZiv
Дата: 13.03.2015 16:40:23
А вот кому Кохонена ?
А именно, KNNL.

В общем, небольшая программка (нужно QT5), которая реализует классический пример для работы с картами Кохонена:
распределяет цвета цветового пространства по карте, и показывает её. Показывает по шагам в процессе обучения.
Полезно для овладевания основами работы с картами Кохонена.
Также можно использовать в качестве очень плохого скринсейвера.

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <iterator>
#include <algorithm>

#include <functors.hpp>
#include <basic_neuron.hpp>
#include <euclidean_distance_function.hpp>
#include <rectangular_container.hpp>
#include <kohonen_network.hpp>
#include <randomize_policy.hpp>
#include <print_network.hpp>
#include <wta_training_algorithm.hpp>
#include <wtm_topology.hpp>
#include <generalized_training_weight.hpp>

#include "neuro.h"

std::ostream& operator << ( std::ostream &os, const color_t &c )
{
    os << '(' << c.r() << ',' << c.g() << ',' << c.b() << ')';
    return os;
}

void generateColors( color_set_t &colors )
{
    size_t max_coloroid_val = 32;
    size_t nc = max_coloroid_val * max_coloroid_val * max_coloroid_val;
    colors.clear();
    colors.reserve( nc );
    for( coloroid_t r = 0; r < max_coloroid_val; ++r)
        for( coloroid_t g = 0; g < max_coloroid_val; ++g)
            for( coloroid_t b = 0; b < max_coloroid_val; ++b)
                colors.push_back( color_t( r,g,b ) );
}

WTMColorLearning generateColorsSOM( color_set_t &colors, som_t &som )
{
    neural_net::generate_kohonen_network( 30, 30, CauchyOfDouble(2.0, 2), ColorEuclideanDistanceFunc(), colors, som, neural_net::Internal_randomize() );
    //neural_net::print_network_weights( std::cout, som );
    return WTMColorLearning ( ColorTraining( Classic_weight( G_f_net ( 10, 2 ), G_f_space( 100, 1 ), Maxtop(), ColorEuclideanDistanceFunc() ), 0.3) );
}

void trainColorsSOM( color_set_t &colors, som_t &som, WTMColorLearning &learn )
{
    // learning
    std::random_shuffle( colors.begin(), colors.end() );

    //std::cout << "\nLeaning phase #" << i << "...";  std::cout.flush();
    learn( colors.begin(), colors.end(), &som );
    //std::cout << "done" << std::endl;

    // decrease sigma parameter in network
    // will make training process more sharpen with each epoch,
    // but it have to be done slowly :-)
    double sigma = learn.training_functional.generalized_training_weight.network_function.sigma * 0.75;
    if( 1 || sigma > 0.5 )
        learn.training_functional.generalized_training_weight.network_function.sigma = sigma;

    //neural_net::print_network_weights( std::cout, som );
}

std::pair< unsigned, unsigned > findColorBMU( const som_t &som, const color_t &color )
{
    double r = 100000000000.;
    std::pair< unsigned, unsigned > bmu( 0, 0 );

    for( unsigned i = 0; i < som.get_no_rows(); ++i )
        for( unsigned j = 0; i < som.get_no_columns(); ++i )
        {
            double rk = som.objects [ i ][ j ] ( color );
            if( rk < r )
            {
                bmu = std::pair< unsigned, unsigned >( i, j );
                r = rk;
            }
        }
    return bmu;
}


double totalDistance( const color_set_t &colors, const som_t &som )
{
    double d = 0;
    for( auto clr = colors.cbegin(); clr != colors.cend(); ++clr )
    {
        std::pair< unsigned, unsigned > bmu = findColorBMU( som, *clr );
        const ColorSOMNeuron &n = som.objects [ bmu.first ] [ bmu.second ];
        d += n( *clr );
    }
    return d;
}


/*
double totalDistance( const color_set_t &colors, const som_t &som )
{
    double d = 0;
    for( auto clr = colors.cbegin(); clr != colors.cend(); ++clr )
        for( unsigned r = 0; r < som.get_no_rows(); ++r )
            for( unsigned c = 0; c < som.get_no_columns(); ++c )
            {
                const ColorSOMNeuron &n = som.objects [ r ] [ c ];
                //color_t wc( n.weights.r(), n.weights.g(), n.weights.b() );
                d += n( *clr );
            }
    return d;
}
*/


Весь код с проектом в архиве

----
Читал хинты оракла. Много думал...
mayton
Дата: 13.03.2015 17:41:51
Ее реально собрать в консоли?
Герой дня
Дата: 13.03.2015 17:52:02
хотелось бы скриншотов
mayton
Дата: 13.03.2015 17:54:49
Помнится... в универе мы ради прикола собирали в С++ свой собственный скринсейвер. Для Win95.
MasterZiv
Дата: 13.03.2015 20:13:59
mayton
Ее реально собрать в консоли?


Собрать -- реально. Но работать в консоли не будет -- нужен графический дисплей.
MasterZiv
Дата: 13.03.2015 20:19:38
Герой дня
хотелось бы скриншотов


Вот.
многоразовый клон 26
Дата: 14.03.2015 01:42:32
MasterZiv,

отличная таблица для дизайнера
mayton
Дата: 04.06.2020 17:30:09
Up. Хорошая тема была.

Жаль что не поддержали. Предлагаю ее поднять новым пятничным топиком в Программировании.

Разумеется мы ее переосмыслим. Саму постановку.
PetroNotC Sharp
Дата: 05.06.2020 08:49:54
mayton,
Qt ставить потребуется
mayton
Дата: 05.06.2020 08:54:54
Мы не будем ограничиваться KNNL.

Собственно кохонен описан в теории и меня интересует именно своя реализация и практическое использование.