воскресенье, 26 декабря 2010 г.

Пример нейронной сети на PHP

ИИ всегда интересовал меня. Если верить фантастам да и статьям из эпохи первых компьютеров, в наше время мы должны уже жить вместе с роботами с искусственным интеллектом. Но до сих пор, на сколько мне известно, разумного, мыслящего ИИ не создано.

Чтобы немного представить как работает нейронанная сеть, можно воспользоваться ниже приведенным примером:
Код - пример #1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
  Пример нейронной сети, которая учится отличать
  маленькие русские буквы от всех остальных.
  Язык - 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;
    while($temp=each($s)) {
       $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();
    reset($s);
    while($temp=each($s)) {
       $this->inputWeights[]=mt_rand(0,100)/100;
    }
  }
}

class R {  // Решатель. Смотрит, что пришло от нейронов, считает среднее, выдаёт ответ.
  var $answer=array();
  function think($a){
    $this->answer=array();
    while($temp=each($a)) {
       $this->answer[]=$temp[1]->active;
    }
    return ((array_sum($this->answer)/count($this->answer)) > 0.5);
  }
}

$s=array();
$a=array();

// В символе восемь бит. Сделаем 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++){ // просто цикл.

$input=rand(0,255);
/*
  Буква ё сложная для обучения, у неё код символа далеко от остальных русских букв.
  Поэтому увеличим частоту её выпадания.
*/
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;
echo ' '.chr($input).'';
if ($correct>500) {
  echo "Для обучения сети потребовалось $ww обучающих примеров.";
  break;
}
}

var_dump($s);
var_dump($a);
var_dump($r);
Пример взял вот отсюда

5 комментариев:

  1. хорошая нейросеть, но ее можно переделать чтобы считала цифры на рулетке и заносила последовательность в базу, база как бы память, из этой памяти нейросет уже сама будет подбирать нужное число для победы над рулеткой, вот и весь секрет заработка на рулетке))

    ОтветитьУдалить
  2. забыл еще сказать, на рулетке 37 чисел(от 0 до 36) следовательно входных слоев нужно 37 енное количество скрытых и один нейрон на выходе)), поправка к первому комментарию, не нейросет а нейросеть)))

    ОтветитьУдалить
  3. Любопытства ради решил поэксперементировать и подставил вместо кирилицы латиницу. И что я вижу - правильных ответов подряд не больше 30. Т.е. сеть какбудто перестала обучаться.
    Вернул все назад и просто исключил букву "ё". Теперь количество правильных ответов подряд при обучении не поднимается выше 9.
    У меня отсутсвуют даже догадки по этому поводу.

    ОтветитьУдалить
    Ответы
    1. А вы вообще код программы читали, в особенности комментарии? :)

      Удалить