/*
Пример нейронной сети, которая учится отличать
маленькие русские буквы от всех остальных.
Язык - php.
Пожалуйста, не удаляйте этот текст при копировании. (c) Секрет. Realme.ru
*/
class S { // глаза сети. Каждый глазик видит свою часть данных.
var $input=0;
}
class A { // нейроны
var $inputWeights=array(); // нейрон связан с каждым глазом с разной силой. var $active=0;
/*
нейрон получает от всех глаз данные, единицу или ноль.
Умножаем на силу связи глаз-нейрон, считаем среднее,
сравниваем с 0.2 - это число выбрано интуитивно.
Если поставить 1, сети потребуется в 4-5 раз больше обучающих примеров.
*/
function think($s){
reset($this->inputWeights); $this->active=0;
$temp2=each($this->inputWeights); $this->active+=($temp[1]->input)*$temp2[1];
}
$this->active/=count($s); $this->active=($this->active > 0.2);
}
/*
при создании нейрона связываем с глазами случайным образом.
*/
function __construct($s){
$this->inputWeights=array(); $this->inputWeights[]=mt_rand(0,100)/100; }
}
}
class R { // Решатель. Смотрит, что пришло от нейронов, считает среднее, выдаёт ответ.
function think($a){
$this->answer[]=$temp[1]->active;
}
}
}
// В символе восемь бит. Сделаем 8 глаз.
for($q=0;$q<8;$q++) $s[$q]=new S();
/*
Cделаем 20 нейронов. Собственно, для решения этой задачи достаточно
одного нейрона, он нормально обучается. Стоит 20 просто для примера.
*/
for($q=0;$q<20;$q++) $a[$q]=new A($s);
$r=new R();
$correct=0;
for($ww=0;$ww<10000;$ww++){ // просто цикл.
/*
Буква ё сложная для обучения, у неё код символа далеко от остальных русских букв.
Поэтому увеличим частоту её выпадания.
*/
if (rand(1,100)==1) $input=ord('ё'); // правильный ответ нужен для процесса обучения.
$answer=((($input<=ord('я'))AND
($input>=ord('а')))OR
(ord('ё')==$input)); // ну или preg_match('/[а-яё]/',$input);, кому так понятнее.
for($q=0;$q<8;$q++) $s[$q]->input=($input & pow(2,$q)) >> $q; // глазки смотрят. for($q=0;$q<20;$q++) $a[$q]->think($s); // нейроны думают.
/*
Процесс обучения.
Для каждого нейрона смотрим, ответил ли он правильно.
Почему нейрон ошибается? Потому что не знает, от каких глаз данные важнее.
Например, если старший бит ноль, то русской буквой символ точно быть не может.
Этого нейрон не поймёт, но научиться, что данные от старшего бита важнее, он может.
Изменяем силу связи с теми глазами, которые видели единицу.
Единицы от одних глаз станут влиять на результат сильнее, от других - слабее.
*/
for($q=0;$q<20;$q++) if ($a[$q]->active != $answer) {
foreach($a[$q]->inputWeights as $k=>$v){
if ($s[$k]->input) {
$a[$q]->inputWeights[$k]+=(($answer)?0.01:-0.01);
}
}
}
$think=$r->think($a);
// считаем, сколько раз подряд ответили верно.
if ($think == $answer) {
$correct++;
} else {
$correct=0;
}
echo (int)$think;
echo (int)$answer;
if ($correct>500) {
echo "Для обучения сети потребовалось $ww обучающих примеров.";
break;
}
}