Регистрация | Вход
unit nnet;interface//Константы для функций активацииconst THRESHOLD=1; //пороговая SIGNUM=2; //знаковая (сигнатурная) SIGMOID=3; //сигмоидальная (логистическая) SEMILINEAR=4; //полулинейная LINEAR=5; //линейная RADIAL_BASIS=6; //радиальная базисная (гауссова) SEMILINEAR_WITH_SAT=7; //полулинейная с насыщением LINEAR_WITH_SAT=8; //линейная с насыщением HYPER_TAN=9; //гиперболический тангенс (сигмоидальная) TRIANGULAR=10; //треугольная type TDouble1DVector=array[1..100] of double; TInt1DVector=array[1..100] of integer; type TNeuron=record //нейрон inputs_count:integer; //количество входов Inputs,Weights:TDouble1DVector; //входы и веса Threshold:double; //порог act_function:integer; //тип функции активации output:double; //выход нейрона error:double; //ошибка sigma:double; //сигма sum:double; //взвешенная сумма (без вычитания порога) end; type TLayer=record //слой neurons_count:integer; //нейронов в слое Neurons:array[1..100] of TNeuron; //нейроны end; type TNeuralNetwork=record //нейросеть layers_count:integer; //слоев в нейросети Layers:array[1..100] of TLayer; //слои input_vals_count:integer; //количество входных значений input_vals,output_vals:TDouble1DVector;//входные и выходные значения end; function f(x:double; act_function:integer):double; //функция активации function df(x:double; act_function:integer):double; //производная от функции активации //инициализация нейросети procedure InitNeuralNetwork(l_count:integer; //количество слоев neurons_in_layer:TInt1DVector; //нейронов в слое act_function:TInt1DVector; //функции активации inp_count:integer; //количество входов в сеть var Net:TNeuralNetwork); //инициализированная сеть //обучение нейросети procedure TrainNeuralNetwork(inp_count:integer; //количество входов в сеть inp:TDouble1DVector; //входы desired_outputs_count:integer; //количество выходов из сети desired_outputs:TDouble1DVector; //желаемые выходы var Net:TNeuralNetwork); //натренированная нейросеть //получение результатов от нейросети procedure GetResults(inp_count:integer; //количество входов в сеть inp:TDouble1DVector; //входы Net:TNeuralNetwork; //натренированная нейросеть var desired_outputs_count:integer; //количество выходов из сети var desired_outputs:TDouble1DVector); //выходы из сетиimplementation function f(x:double; act_function:integer):double; begin case act_function of 1: if x<0 then f:=0 else f:=1; 2: if x>0 then f:=1 else f:=-1; 3: if abs(x) < 38 then f:=1/(1+exp(-x)) else if x >= 38 then f:=1 else f:=0; 4: if x>0 then f:=x else f:=0; 5: f:=x; 6: f:=exp(-x*x); 7: if x<=0 then f:=0 else if (0<x) and (x<1) then f:=x else f:=1; 8: if x<=-1 then f:=-1 else if (-1<x) and (x<1) then f:=x else f:=1; 9: f:=(exp(x)-exp(-x))/(exp(x)+exp(-x)); 10: if abs(x)<=1 then f:=1-abs(x) else f:=0; else f:=0; end; end; function df(x:double; act_function:integer):double; begin case act_function of 1: df:=0; 2: df:=0; 3: df:=1/(1+exp(-x))*(1-1/(1+exp(-x))); 4: if x>0 then df:=1 else df:=0; 5: df:=1; 6: df:=-2*x*exp(-x*x); 7: if x<=0 then df:=0 else if (0<x) and (x<1) then df:=1 else df:=0; 8: if x<=-1 then df:=0 else if (-1<x) and (x<1) then df:=1 else df:=0; 9: df:=4/sqr(exp(x)+exp(-x)); 10: if (-1<=x) and (x<0) then df:=1 else if (0<=x) and (x<=1) then df:=-1 else df:=0; else df:=0; end; end; procedure InitNeuralNetwork(l_count:integer; neurons_in_layer:TInt1DVector; act_function:TInt1DVector; inp_count:integer; var Net:TNeuralNetwork); var i,j,k:integer; begin Randomize; //Количество слоев Net.layers_count:=l_count; //Количество нейронов в слоях for i:=1 to l_count do Net.Layers[i].neurons_count:=neurons_in_layer[i]; //Функция активации в каждом слое for i:=1 to l_count do for j:=1 to Net.Layers[i].neurons_count do Net.Layers[i].Neurons[j].act_function:=act_function[i]; //Количество входов в каждый нейрон первого слоя for i:=1 to Net.Layers[1].neurons_count do Net.Layers[1].Neurons[i].inputs_count:=inp_count; //Для каждого след. слоя количество входов = количеству нейронов в пред. слое for i:=2 to Net.layers_count do for j:=1 to Net.Layers[i].neurons_count do Net.Layers[i].Neurons[j].inputs_count:=Net.Layers[i-1].neurons_count; //Задаем начальные значения весов и порогов for i:=1 to Net.Layers_count do for j:=1 to Net.Layers[i].neurons_count do begin for k:=1 to Net.Layers[i].Neurons[j].inputs_count do begin Net.Layers[i].Neurons[j].Weights[k]:=random(5000)/10000; Net.Layers[i].Neurons[j].error:=10E+38; end; Net.Layers[i].Neurons[j].Threshold:=random(5000)/10000; end; end; procedure TrainNeuralNetwork(inp_count:integer; inp:Tdouble1DVector; desired_outputs_count:integer; desired_outputs:Tdouble1DVector; var Net:TNeuralNetwork); const epochs=10000; procedure RunNetwork(); //прогон сети var i,j,k:integer; begin //Подсчет выходных значений нейронов for i:=1 to Net.layers_count do begin for j:=1 to Net.Layers[i].neurons_count do with Net.Layers[i].Neurons[j] do begin sum:=0; for k:=1 to inp_count do sum:=sum+Inputs[k]*Weights[k]; output:=f(sum-Threshold,act_function); end; //Передача сигналов с выходов пред. слоя на входы след. слоя if i<Net.layers_count then for j:=1 to Net.Layers[i+1].neurons_count do for k:=1 to Net.Layers[i+1].Neurons[j].inputs_count do Net.Layers[i+1].Neurons[j].Inputs[k]:=Net.Layers[i].Neurons[k].output; end; end; procedure CalculateErrors(); //вычисление ошибок var i,m,k:integer; sum_err:double; begin for k:=Net.layers_count downto 1 do for i:=1 to Net.Layers[k].neurons_count do if k=Net.layers_count then //Если последний слой with Net.Layers[k].Neurons[i] do begin error:=desired_outputs[i]-output; sigma:=error*df(output,act_function); end else //если другой слой begin sum_err:=0; for m:=1 to Net.Layers[k+1].neurons_count do with Net.Layers[k+1].Neurons[m] do sum_err:=sum_err+Weights[i]*sigma; with Net.Layers[k].Neurons[i] do begin error:=sum_err; sigma:=error*df(output,act_function); end; end; end; procedure UpdateWeights(); const eta=0.025; var i,j,k:integer; begin for k:=Net.layers_count downto 1 do for i:=1 to Net.Layers[k].neurons_count do begin for j:=1 to Net.Layers[k].Neurons[i].inputs_count do with Net.Layers[k].Neurons[i] do begin Weights[j]:=Weights[j]+2*eta*sigma*inputs[j]; Threshold:=Threshold-2*eta*sigma; end; end; end; var i,j:integer; begin for i:=1 to Net.Layers[1].neurons_count do for j:=1 to Net.Layers[1].Neurons[i].inputs_count do Net.Layers[1].Neurons[i].Inputs[j]:=inp[j]; for i:=1 to epochs do begin RunNetwork(); CalculateErrors(); UpdateWeights(); end; end; procedure GetResults(inp_count:integer; inp:Tdouble1DVector; Net:TNeuralNetwork; var desired_outputs_count:integer; var desired_outputs:Tdouble1DVector); procedure RunNetwork(); //прогон сети var i,j,k:integer; begin //Подсчет выходных значений нейронов for i:=1 to Net.layers_count do begin for j:=1 to Net.Layers[i].neurons_count do with Net.Layers[i].Neurons[j] do begin sum:=0; for k:=1 to inp_count do sum:=sum+Inputs[k]*Weights[k]; output:=f(sum-Threshold,act_function); end; //Передача сигналов с выходов пред. слоя на входы след. слоя if i<Net.layers_count then for j:=1 to Net.Layers[i+1].neurons_count do for k:=1 to Net.Layers[i+1].Neurons[j].inputs_count do Net.Layers[i+1].Neurons[j].Inputs[k]:=Net.Layers[i].Neurons[k].output; end; end; var i,j:integer; begin for i:=1 to Net.Layers[1].neurons_count do for j:=1 to Net.Layers[1].Neurons[i].inputs_count do Net.Layers[1].Neurons[i].Inputs[j]:=inp[j]; RunNetwork(); desired_outputs_count:=Net.Layers[Net.layers_count].neurons_count; for i:=1 to desired_outputs_count do desired_outputs[i]:=Net.Layers[Net.layers_count].Neurons[i].output; end;end.
program NeuralNets;{$APPTYPE CONSOLE}{$M 16777216}uses SysUtils, nnet in ''nnet.pas'';var neurons_in_layer:TInt1DVector; act_function:TInt1DVector; Net:TNeuralNetwork; inputs:TDouble1DVector; desired_outputs:TDouble1DVector; i,x:integer; desired_outputs_count:integer;begin neurons_in_layer[1]:=14; neurons_in_layer[2]:=14; neurons_in_layer[3]:=14; neurons_in_layer[4]:=1; act_function[1]:=SIGMOID; act_function[2]:=SIGMOID; act_function[3]:=SIGMOID; act_function[4]:=LINEAR; InitNeuralNetwork(4,neurons_in_layer,act_function,14,Net); for i:=1 to 16 do begin for x:=i to 14+i-1 do begin inputs[x-i+1]:=x*x; //write(inputs[x-i+1]:0:1,'' ''); end; desired_outputs[1]:=(i+14)*(i+14); TrainNeuralNetwork(14,inputs,1,desired_outputs,Net); //writeln(Net.Layers[4].Neurons[1].output:0:1); end; for x:=17 to 30 do begin inputs[x-16]:=x*x; //write(inputs[x-16]:0:1,'' ''); end; desired_outputs[1]:=0; GetResults(14,inputs,Net,desired_outputs_count,desired_outputs); writeln(desired_outputs[1]:0:1); readln;end.