天天看点

七十行代码的Java

七十行代码的Java

=====ann.pas源程序===================================

unit ann;

interface

type

  Tdbarr=array of double;

  TBpDeep=class

  private

    layer:array of array of double;

    layerErr:array of array of double;

    layer_weight:array of array of array of double;

    layer_weight_delta:array of array of array of double;

    mobp,rate:double;

    procedure updateWeight(tar:array of double);

  public

    constructor Create(layernum:array of integer;rate,mobp:double);

    function computeout(input:array of double):Tdbarr;

    procedure train(input,tar:array of double);

  end;

implementation

constructor TBpDeep.Create(layernum:array of integer;rate,mobp:double);

var

  a,i,j,k:integer;

begin

  self.rate:=rate;

  self.mobp:=mobp;

  a:=length(layernum);

  if a<2 then exit;

  setlength(layer,a);

  setlength(layerErr,a);

  setlength(layer_weight,a-1);

  setlength(layer_weight_delta,a-1);

  Randomize;

  for k:=0 to a-1 do

  begin

    setlength(layer[k],layernum[k]);

    setlength(layerErr[k],layernum[k]);

    if k+1<a then

    begin

      setlength(layer_weight[k],layernum[k]+1,layernum[k+1]);

      setlength(layer_weight_delta[k],layernum[k]+1,layernum[k+1]);

      for j:=0 to layernum[k]-1 do

      for i:=0 to layernum[k+1]-1 do

        layer_weight[k][j][i]:=Random;//随机初始化权重

    end;

end;

function TBpDeep.computeout(input:array of double):Tdbarr;

  i,j,k:integer;

  z:double;

  for k:=1 to high(layer) do

  for j:=0 to high(layer[k]) do

    z:=layer_weight[k-1][length(layer[k-1])][j];

    for i:=0 to high(layer[k-1]) do

      if k=1 then layer[k-1][i]:=input[i];

      z:=z+layer_weight[k-1][i][j]*layer[k-1][i];

    layer[k][j]:=1/(1+exp(-z));

  result:=Tdbarr(layer[high(layer)]);

procedure TBpDeep.updateWeight(tar:array of double);

  k:=high(layer);

  for j:=0 to high(layererr[k]) do layerErr[k][j]:=layer[k][j]*(1-layer[k][j])*(tar[j]-layer[k][j]);

  while k>0 do

    dec(k);

    for j:=0 to high(layererr[k]) do

      z:=0;

      for i:=0 to high(layererr[k+1]) do

      begin

        if z+k>0 then z:=layerErr[k+1][i]*layer_weight[k][j][i]

        else z:=0;

        layer_weight_delta[k][j][i]:=mobp*layer_weight_delta[k][j][i]+rate*layerErr[k+1][i]*layer[k][j];//隐含层动量调整

        layer_weight[k][j][i]:=layer_weight[k][j][i]+layer_weight_delta[k][j][i];//隐含层权重调整

        if j=high(layererr[k]) then

        begin

          layer_weight_delta[k][j+1][i]:=mobp*layer_weight_delta[k][j+1][i]+rate*layerErr[k+1][i];//截距动量调整

          layer_weight[k][j+1][i]:=layer_weight[k][j+1][i]+layer_weight_delta[k][j+1][i];//截距权重调整

        end;

      end;

      layerErr[k][j]:=z*layer[k][j]*(1-layer[k][j]);//记录误差

procedure TBpDeep.train(input,tar:array of double);

  computeout(input);

  updateWeight(tar);

end.

========================================

测试代码:

procedure TForm1.bttrainClick(Sender: TObject);//训练

  i,k:integer;

const

  data:array[0..3] of array[0..1] of double=((1,2),(2,2),(1,1),(2,1));

  tar:array[0..3] of array[0..1] of double=((1,0),(0,1),(0,1),(1,0));

  for k:=0 to 499 do

  for i:=0 to high(data) do

    bp.train(data[i], tar[i]);

procedure TForm1.btcomputeClick(Sender: TObject);//识别

  rst:Tdbarr;

  x:array[0..1] of double;

  x[0]:=strtofloat(xx.Text);

  x[1]:=strtofloat(yy.Text);

  rst:=bp.computeout(x);

  memo1.Lines.Append(floattostr(rst[0])+' '+floattostr(rst[1]));

procedure TForm1.FormCreate(Sender: TObject);//初始化

  bp:=TBpdeep.Create([2,10,2],0.15,0.8);