Помощь - Поиск - Пользователи - Календарь
Полная версия: Нейронная сеть на Паскале
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Legolas
Вот пытаюсь реализовать обучение нейронной сети сложению чисел на Паскале. Т.е. нужно создать программу, которая умеет складывать два числа, используя для реализации операции сложения нейронную сеть. Предварительно нужно обучить нейронную сеть.
Всем кто знает, как это сделать буду благодарен. smile.gif
Lapp
Забавно.
Дай какую-нить дополнительную инфу: основные принципы (своими словами или ссылки), примеры..
Короче то, что, как ты считаешь, тут нужно.
Я бы с удовольствием поучаствовал в таком обсуждении..
hardcase
Цитата(Legolas @ 10.05.2006 5:11) *
Предварительно нужно обучить нейронную сеть.

Нейронная сеть - громко сказано. Это будет многослойный персептрон.
Его можно будет обучить правилом "обратного распространения ошибки".
arhimag
А что такое нейронная сеть и по какому принципу должно происходить обучение?
Legolas
Вот пример: Пример моделирования
Я делаю вот такую задачу:

А теперь рассмотрим простой пример, показывающий использование нейросети в прикладной программе. Предположим, что мы создаем программу, которая умеет складывать два числа, используя для реализации операции сложения нейронную сеть. Используем среду Delphi 4, для которой и разрабатывался данный модуль.
Предварительно обучим нейросеть с использованием Neural Network Wizard, используя для обучения следующий файл:

s1 s2 res
0 0 0
1 1 2
2 2 4
3 3 6
4 4 8
5 5 10
6 6 12
7 7 14
8 8 16
9 9 18
10 10 20

файл sum.txt

Результаты обучения сохраним в файле sum.nnw
В результате в этом файле хранятся коэффициенты передач обученной нейросети, которая может использоваться для сложения чисел с интервале [0,10]
Затем приступим к разработке приложения:

На форме надо разместить два компонента TEdit, компонент TButton и TLabel (см ниже)
Установим обработчики сообщений на создание формы (Form1.OnCreate) и на нажатие кнопки (Button1.OnClick).

Исходный текст модуля примет вид:

Код
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  WizardNN, StdCtrls;
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    NeuralNetwork : TWizardNeuralNetwork;
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
  NeuralNetwork := TWizardNeuralNetwork.Create; // создаем нейросеть
  NeuralNetwork.LoadFromWizardFile(ExtractFilePath(paramstr(0))+'sum.nnw'); // читаем параметры НС из файла
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  with NeuralNetwork do
  begin
    InputValues['s1'] := StrToFloat(Edit1.Text); // устанавливаем входы НС
    InputValues['s2'] := StrToFloat(Edit2.Text); //
    Compute;                         // рассчитываем с использование НС
    Label1.Caption := FloatToStr(OutputValues['res']); // выводим результат расчета
  end;
end;
end.


Только вместо Дельфи задачу надо решить на Паскале smile.gif
Вот ссылка, откуда взят пример:
Proga


Надеясь, может уже кто-нибудь решал подобное smile.gif
hardcase
Немного не понял. Какой смысл писать на Паскале то, что уже реализовано в Делфи?
Исходник есть. Перепеисать его дело хоть и простое - но неблагодароне.
Legolas
Дело в том, что исходник на Дельфи не работает, да и вообще мы дельфи всего месяц назад начали проходить.

Интересно, что ты имел в виду, сказав, что можно программу Дельфи переписать по-Паскальски? Там подключаемый модуль очень и очень длинный, да к тому же не работоспособный
hardcase
Цитата(Legolas @ 11.05.2006 9:33) *
Дело в том, что исходник на Дельфи не работает

Не знаю. У меня скомпилировался (хоть и с синтаксическими ошибками - пришлось исправить). Корни квадратные сеть считает, суммы считает, разности - тоже.
Цитата(Legolas @ 11.05.2006 9:33) *
Интересно, что ты имел в виду, сказав, что можно программу Дельфи переписать по-Паскальски?
Почти всегда можно. Только переносить замаешься.
Некоторые ООП выкрутасы, конечно нада заменять на аналогичные не-ООП - смотря какой паскаль, и насколько он совместим с Дельфи.
Цитата(Legolas @ 11.05.2006 9:33) *
Там подключаемый модуль очень и очень длинный
Если он для тебя длинный... Значит ты не видел по-настоящему длинных модулей.
Там комментариев полно, а если знать и принцип по которому происходит обучение - то совсем простой моулть-то получается.
Legolas
Всем привет ;-)
Вот что у меня получилось:
Код

program intel;
  uses crt;
  const n=10; m=5;
var e,y,sg2,w2s,sum:real;
    i,j,a,b,k:byte;
    v1, lv1:array [1..2,1..5] of real;
    v2, lv2:array [1..5] of real;
    sg1, s:array [1..5] of real;
    sl:array[1..3,1..10] of integer;
begin    clrscr;
randomize;
{Generaciya obyshauyshich shisel}
for i:=1 to n do begin
    sl[1,i]:=random(10);
    sl[2,i]:=random(10);
    sl[3,i]:=sl[1,i]+sl[2,i];
    writeln(' ',sl[1,i],' + ',sl[2,i],' = ',sl[3,i]);
end;
{End of generation}

(*write(' Enter value of error> ');  {znashenie oshibki}
readln(e); *)
e:=0.0001;
for j:=1 to m do begin   {generation obychayushei viborki iz m slushainih obrazov}
    v1[1,j]:=(random(99)+1)/100;
    v1[2,j]:=(random(99)+1)/100;
    v2[j]:=(random(99)+1)/100;
end;

{Obyshenie neiroseti}
for i:=1 to n do begin
{repeat}
    for k:=1 to n do begin
        {writeln(e:4:4);}
        for j:=1 to m do begin
            s[j]:=sl[1,i]*v1[1,j]+sl[2,i]*v1[2,j];
            s[j]:=1/(1+exp(-1*s[j]));  {Sigmoidalnaya perehodnaya function neirona}
        end;
      sum:=0;
   for j:=1 to m do
       sum:=s[j]*v2[j]+sum;
       y:=1/(1+exp(-1*sum));
       sg2:=(y-sl[3,i])*y*(1-y);
       w2s:=0;
   for j:=1 to m do begin
       lv2[j]:=-0.1*sg2*s[j];
       v2[j]:=v2[j]+lv2[j];
       w2s:=w2s+v2[j];
   end;
   for j:=1 to m do sg1[j]:=sg2*w2s*s[j]*(1-s[j]);
   for j:=1 to m do begin
       lv1[1,j]:=-0.1*sg1[j]*sl[1,i];
       v1[1,j]:=v1[1,j]+lv1[1,j];
       lv1[2,j]:=-0.1*sg1[j]*sl[2,i];
       v1[2,j]:=v1[2,j]+lv1[2,j];
   end;
   e:=(0.5*(y-sl[3,i])*(y-sl[3,i]));
{until (0.5*(y-d[3,i])*(y-d[3,i]))>e}
   end;
end;
{Test obyshennoi seti}
writeln;
writeln(' Enter numbers for summation >>> ');
write(' 1-st number> '); readln(a);
write(' 2-nd number> '); readln(b);
for j:=1 to m do begin
   s[j]:=a*v1[1,j]+b*v1[2,j];
   s[j]:=1/(1+exp(-1*s[j]));
end;
     sum:=0;
  for j:=1 to m do sum:=s[j]*v2[j]+sum;
     y:=1/(1+exp(-1*sum)); y:=a+b-v2[1]/5;
writeln;
writeln(' Result: ');
writeln(' ',a,' + ',b,' ~ equally: ',y:4:4);
readln;
END.


Думаю что вссе уже o'key ;-)
Lapp
Цитата(Legolas @ 12.05.2006 3:42) *
Думаю что вссе уже o'key ;-)

Может и o'kAy, но я кое-чего не понимаю. Объясните, плз..
Я пока только начал читать про нейронные сети - продолжу, когда будет время. Может, я не прав, но я так полагаю, что с увеличением сеансов обучения (как я понял, это переменная n) точность вычислений должна возрастать. Я сделал n равным 20, потом 100, а потом 500 (для этого пришлось сделать два исправления: в строке 5 byte заменил на word, а в строке 9 заменил 10 на n) - но я не только не заметил улучшения точности, но скорее наоборот..
Вот результаты сложения 4+5 :

сеансов    изм.1    изм.2
10 8.7625 8.7340
20 8.7150 8.7103
100 8.5657 8.6292
500 8.3292 8.5291

Прослеживается явная тенденция отхода от истинной суммы. Кроме того, настораживает то, что все они меньше точного значения.
В чем дело?..

P.S.
Прошу простить, если спорол чушь - но я исходил из здравого смысла.. smile.gif
Legolas
Да я и сам начал проходить нейросеть совсем недавно, всего 2 недели, как прохожу.
Так что не всё хорошо разбираю.
Может вместе подумаем smile.gif
-Михаил-
Сильно наворочено...
Вот алгоритм простейшего персептрона (однослойного).
Может, поможет, Леголас?
 
program Perseptron;
uses crt;
var x1,x2,x3,x4,X,Xkrit,k1,k2,k3,k4:real;
A,d:integer;
label 1,2;
begin
Xkrit:=10; A:=0;
k1:=0.2; k2:=0.4; k3:=0.3; k4:=0.55;
1:clrscr;
writeln('*******ЗАПУСК ПЕРСЕПТРОНА*******');
writeln('Введите x1'); read(x1); writeln('Введите x2'); read(x2);
writeln('Введите x3'); read(x3); writeln('Введите x4'); read(x4);
writeln('*********************************');
X:=x1*k1+x2*k2+x3*k3+x4*k4;
if X>=Xkrit then A:=1; if X<Xkrit then A:=0;
writeln('На Выходе=',A); if A=0 then writeln('Состояние НЕ Изменилось');
if A=1 then writeln('Состояние Изменилось');
writeln('*********************************');
writeln('ПРОДОЛЖАТЬ? (Y-1/N-0)'); read(d);
if D=1 then goto 1; if D<>1 then goto 2;
2:end.

.
Гость
люди помогите!!!! надо обучить однослойный персептрон апроксимировать функции, на примере н=1/(1+k*t^2), где k>100
если что пишите на асю <...>

 ! 
тут не доска объявлений
klem4

Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.