Простая RBF-сеть в Octave
Описание процесса создания RBF-сети в среде Octave + исходные коды.
Для математического пакета Octave на момент написания статьи, насколько мне известно, из нейронных сетей реализован только многослойный персептрон.
Так случилось, что мне понадобилась радиально-базисная (RBF) нейронная сеть. Встала задача аппроксимации функции одной переменной, а, судя по результатам этой работы, радиально-базисная сеть справляется с аппроксимацией лучше всех.
Где-то за день я написал подобную сеть для Octave. Делюсь своим решением – оно может послужить как прототипом, так и реально решить чьи-то задачи.
Сеть я охарактеризовал следующими параметрами:
- вектором
R, содержащим радиусы функций нейронов скрытого слоя - вектором
C, содержащим их центры - вектором
W– с набором весов для каждого скрытого нейрона - и, собственно, целым числом
hc– содержащем количество нейронов скрытого слоя.
Функция инициализации нейросети будет выглядеть следующим образом:
function [rbf] = rbfnetinit (hidden_count, min_x, max_x)
rbf.hc = hidden_count;
rbf.R = linspace(1, hidden_count, hidden_count);
rbf.C = linspace(1, hidden_count, hidden_count);
rbf.W = linspace(1, hidden_count, hidden_count);
for i = 1:hidden_count
rbf.R(i) = (max_x – min_x) / (hidden_count – 1);
rbf.C(i) = min_x + (max_x – min_x) / (hidden_count – 1) * (i – 1);
rbf.W(i) = 0;
endfor
endfunction
Здесь сделано некоторое допущение относительно начального расположения радиусов и центров. Они задаются таким образом, чтобы равномерно «покрыть» площадь от максимального до минимального значения.
Выберем функцией нашей нейронной сети гауссиану:
function [res] = haussian (x, r, c)
res = exp(-(((x-c)^2) / (r^2)));
endfunction
Тогда выходная функция нейронной сети будет описана так:
function [y] = rbfnetout (rbf, x)
y = 0;
for i = 1:rbf.hc
y += haussian(x, rbf.R(i), rbf.C(i)) * rbf.W(i);
endfor
endfunction
А обучение нейронной сети будет осуществляться такой функцией:
function [W] = rbfnettrain (rbf, X, Y, sample_count)
H = zeros(sample_count, rbf.hc);
for j = 1:sample_count
for i = 1:rbf.hc
H(j, i) = haussian(X(j), rbf.R(i), rbf.C(i));
endfor
endfor
H = pinv(H);
W = H * Y;
endfunction
Здесь sample_count – это объём выборки; X – вектор входных значений, Y – вектор входных значений.
Результат аппроксимации функции одной переменной с помощью этой RBF-сети представлен на графике:

Для улучшения работы RBF-сети обычно нормализуют входные и, иногда, выходные данные.
Скачать полные исходные коды, включающие, кроме вышеописанного кода:
два вида нормализации
чтение данных из файла
отображение полученного результата на экран в виде графика
можно по этой ссылке.