数模论坛

 找回密码
 注-册-帐-号
搜索
热搜: 活动 交友 discuz
查看: 6552|回复: 2

俺写的BP算法源程序(Pascal)

[复制链接]
发表于 2005-10-1 09:16:22 | 显示全部楼层 |阅读模式
<>delphi 2005下编译通过。支持变学习率。具有通用性,传递函数可自己写(动态调用)。</P>
<>下面是程序和使用的例子。学习《人工智能与专家系统》时写的。</P>

<>//////////////////主程序////////////////////////</P>
<P>program BP;<BR>{<BR>  输入文件:BP.in<BR>  第一行:DLL文件名<BR>  第二行:layer_count, n(1), n(2), ... , n(layer_count) ;n(i) &lt;--第i层神经元个数<BR>  第三行:允许误差ε 学习率η 学习实例个数N 附加测试输入个数M 迭代次数(若0则不计迭代次数) 最低学习率min_yita<BR>    // 若迭代次数为零,则最低学习率可以不用写<BR>    // 若迭代次数不为零,则学习率为最高学习率,且必须输入最低学习率<BR>  接下来是学习实例,每个学习实例2行:<BR>    第一行:输入的n(1)个数<BR>    第二行:期望的输出<BR>  再接下来是M个测试输入<BR>    测试输入<BR>  N&lt;=40,M&lt;=100<BR>  n(i)&lt;=10<BR>  3&lt;=layer_count&lt;=10<BR>  0&lt;η&lt;1,推荐0.3&lt;=η&lt;=0.9<BR>  输入:[0,1]</P>
<P>  注意:误差E[j,k]=1/2*(y*[j,k]-y[j,k])^2&lt;=ε</P>
<P>  输出文件:BP.out<BR>  第一行:总迭代次数<BR>  接下来N行:对应每个学习实例的输出和测试输入的输出<BR>  接下来为所有权值<BR>}</P>
<P>uses<BR>  SysUtils,<BR>  Windows,<BR>  ClassFunctionsUnit in 'ClassFunctionsUnit.pas';</P>
<P>{ Global Variables }</P>
<P>var<BR>  yita,epsilon,min_yita,delta_yita:Extended;<BR>  layer_count,t,k,instance_count,total_time,ExtraCount:integer;<BR>    // t - 迭代次数,k - 学习实例序号,total_time - 总迭代次数<BR>  func:TFunctions;<BR>  n:array[1..10] of integer; // 每层的神经元个数<BR>  instances:array[1..140] of record // 学习实例 <BR>    X,Y:array[1..10] of Extended;<BR>    end;</P>
<P>  W:array[1..9] of array[1..10,1..10] of Extended;<BR>  IO_map:array[1..10,1..10] of record<BR>    I,Extended;<BR>    end;<BR>  E:array[1..10] of Extended;  // E - 神经网络输出误差<BR>  delta:array[1..10,1..10] of Extended;</P>
<P>{ Global Procedures }</P>
<P>  procedure LoadFromFile;<BR>  var F:TextFile;<BR>      FileName:String;<BR>      i,j:integer;<BR>  begin<BR>  AssignFile(F,'BP.in');<BR>  Reset(F);<BR>  Readln(F,FileName);</P>
<P>  func:=TFunctions.Create(FileName);</P>
<P>  Read(F,layer_count);</P>
<P>  for i:=1 to layer_count do<BR>    read(f,n);<BR>  Readln(F);</P>
<P>  Read(F,epsilon);<BR>  read(F,yita);<BR>  Read(F,instance_count);<BR>  Read(F,ExtraCount);<BR>  Read(F,total_time);<BR>  if total_time&gt;0 then Read(F,min_yita);<BR>  Readln(F);</P>
<P>  for i:=1 to instance_count do<BR>    begin<BR>    for j:=1 to n[1] do<BR>      read(f,instances.X[j]);<BR>    Readln(F);<BR>    for j:=1 to n[layer_count] do<BR>      read(F,Instances.Y[j]);<BR>    Readln(F);<BR>    end;<BR>  if ExtraCount&gt;0 then<BR>    for i:=instance_count+1 to ExtraCount+instance_count do<BR>      begin<BR>      for j:=1 to n[1] do<BR>        read(f,instances.X[j]);<BR>      Readln(F);<BR>      end;</P>
<P>  CloseFile(F);<BR>  end;</P>
<P>  procedure MapIO;forward;</P>
<P>  procedure WriteResultToFile;<BR>  var F:TextFile;<BR>      i,j,r:integer;<BR>  begin<BR>  AssignFile(F,'BP.out');<BR>  Rewrite(F);<BR>  Writeln(F,t-1);<BR>  //for k:=1 to instance_count do<BR>  k:=1;<BR>  while k&lt;=instance_count+ExtraCount do<BR>    begin<BR>    MapIO;<BR>    if n[1]&gt;1 then<BR>      for i:=1 to n[1]-1 do<BR>        write(F,Format('%f,',[Instances[k].X]));<BR>    write(F,Format('%f',[Instances[k].X[n[1]]]));<BR>    write(F,'   --&gt;   ');<BR>    if n[layer_count]&gt;1 then<BR>      for i:=1 to n[layer_count]-1 do<BR>        write(F,Format('%f,',[IO_map[layer_count,i].O]));<BR>    writeln(F,Format('%f',[IO_map[layer_count,n[layer_count]].O]));<BR>    k:=k+1;<BR>    end;<BR>  for i:=1 to layer_count-1 do<BR>    for j:=1 to n do<BR>      for r:=1 to n[i+1] do<BR>        Writeln(F,Format('w(%d,%d-&gt;%d,%d): %f',[i,j,i+1,r,W[j,r]]));<BR>  CloseFile(F);<BR>  end;</P>
<P>  procedure Init;<BR>  var i,j,r:integer;<BR>  begin<BR>  // init W<BR>  for i:=1 to layer_count-1 do<BR>    for j:=1 to n do<BR>      for r:=1 to n[i+1] do<BR>        W[j,r]:=Random(100)/1000;<BR>  //init t,k<BR>  t:=1;<BR>  k:=1;<BR>  // init delta_yita<BR>  if total_time&gt;0 then<BR>    delta_yita:=(yita-min_yita)/total_time<BR>    else delta_yita:=0;<BR>  end;</P>
<P>  function computeIn(layer,q:integer):Extended;<BR>  { TEST OK }<BR>    // 计算layer层第q个神经元的输入<BR>  var j:integer;<BR>      a,b:Extended;<BR>  begin<BR>  if layer=1 then<BR>    begin<BR>    Result:=Instances[k].X[q];<BR>    Exit;<BR>    end;</P>
<P>  Result:=0;<BR>  for j:=1 to n[layer-1] do<BR>    begin<BR>    a:=IO_map[layer-1,j].O;<BR>    b:=W[layer-1][j,q];<BR>    Result:=Result+a*b;<BR>    end;<BR>  end;</P>
<P>  { MapIO 搞定所有神经元的输入输出值 }<BR>  procedure MapIO;<BR>  var i,j:integer;<BR>  begin<BR>  for i:=1 to layer_count do<BR>    for j:=1 to n do<BR>      begin<BR>      IO_map[i,j].I:=computeIn(i,j);<BR>      if i=1 then<BR>        IO_map[i,j].=func.layer1(IO_map[i,j].I)<BR>      else begin<BR>        if i=layer_count then<BR>          IO_map[i,j].=func.last_layer(IO_map[i,j].I)<BR>        else IO_map[i,j].=func.middle_layer(IO_map[i,j].I);<BR>        end;<BR>      end;<BR>  end;</P>
<P>  { computeE 计算神经网络的输出误差,在<BR>    调用该过程前要先MapIO }<BR>  procedure computeE;<BR>  var i:integer;<BR>  begin<BR>  for i:=1 to n[layer_count] do<BR>    E:=sqr(Instances[k].Y-IO_map[layer_count,i].O)/2;<BR>  end;</P>
<P>  procedure computeDelta;<BR>  { maybe test OK }<BR>  var i,j,r:integer;<BR>      x:Extended;<BR>  begin<BR>  for i:=1 to n[layer_count] do<BR>    delta[layer_count,i]:=(IO_map[layer_count,i].O-Instances[k].Y)*<BR>      func.d_last_layer(IO_map[layer_count,i].I);<BR>  for i:=layer_count-1 downto 1 do<BR>    for j:=1 to n do<BR>      begin<BR>      x:=0;<BR>      for r:=1 to n[i+1] do<BR>        x:=x+delta[i+1,r]*W[j,r];<BR>      if i&gt;1 then<BR>        // middle layer<BR>        x:=x*func.d_middle_layer(IO_map[i,j].I)<BR>        else // first layer<BR>        x:=x*func.d_layer1(IO_map[i,j].I);<BR>      delta[i,j]:=x;<BR>      end;<BR>  end;</P>
<P>  procedure makeWChange;<BR>  { maybe Test OK }<BR>  var deltaW:Extended;<BR>      i,j,r:integer;<BR>  begin<BR>  for i:=1 to layer_count-1 do<BR>    for j:=1 to n do<BR>      for r:=1 to n[i+1] do<BR>        begin<BR>        deltaW:=-yita*delta[i+1,r]*IO_map[i,j].O;<BR>        W[j,r]:=W[j,r]+deltaW;<BR>        end;<BR>  end;</P>
<P>  function isInRange:Boolean;<BR>  var i:integer;<BR>  begin<BR>  Result:=True;<BR>  for i:=1 to n[layer_count] do<BR>    if E&gt;epsilon then begin Result:=False; break; end;<BR>  end;</P>
<P>  function isAllInRange:Boolean;<BR>  var old_k:integer;<BR>  begin<BR>  old_k:=k;<BR>  k:=1;<BR>  Result:=True;<BR>  while (k&lt;=instance_count)and(k&lt;&gt;old_k) do<BR>      // 增加几行代码,减少了不少不必要的浮点运算 <BR>    begin<BR>    MapIO;<BR>    computeE;<BR>    if not isInRange then<BR>      begin<BR>      Result:=False;<BR>      Break;<BR>      end;<BR>    k:=k+1;<BR>    end;<BR>  k:=old_k;<BR>  MapIO;<BR>  computeE;<BR>  if not isInRange then<BR>    Result:=False;<BR>  end;</P>
<P>  procedure MainCompute;<BR>  begin<BR>  while true do<BR>    begin<BR>    if (total_time&gt;0) and (t&gt;total_time) then break;<BR>    if isAllInRange then Break;<BR>//    MapIO;   &lt;-- included in isAllInRange<BR>//    computeE;<BR>    computeDelta;<BR>    makeWChange;<BR>    t:=t+1;<BR>    k:=((k+1) mod instance_count)+1;<BR>    yita:=yita-delta_yita;<BR>    end;<BR>  end;</P>
<P>begin<BR>Randomize;<BR>LoadFromFile;</P>
<P>Init;<BR>MainCompute;</P>
<P>WriteResultToFile;</P>
<P>func.Free;<BR>end.</P>


<P>////////////////////file: ClassFunctionsUnit.pas/////////////////////////</P>
<P>unit ClassFunctionsUnit;</P>
<P>interface</P>
<P>type<BR>  TFunction=function (input:Extended):Extended;stdcall;</P>
<P>  TFunctions=class  // 这个类定义了所有的传递函数以及他们的导数<BR>  private<BR>    DLLHandle:Cardinal;<BR>  public<BR>    layer1:TFunction;                           //输入层传递函数<BR>    d_layer1:TFunction;                         //输入层传递函数的导数<BR>    middle_layer:TFunction;                     //隐层传递函数<BR>    d_middle_layer:TFunction;                   //隐层传递函数的导数<BR>    last_layer:TFunction;                       //输出层传递函数<BR>    d_last_layer:TFunction;                     //输出层传递函数的导数<BR>    //所有的这些都是在Create的时候从动态连接库导入<BR>    //若DLL读入失败,则使用默认<BR>    constructor Create(DLLFileName:string);<BR>    destructor Destroy;override;<BR>  end;</P>
<P>implementation</P>
<P>uses Windows;</P>
<P>{ Default Functions }</P>
<P>function TDefaultFunctions_d_last_layer(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=1;<BR>end;</P>
<P>function TDefaultFunctions_d_layer1(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=1;<BR>end;</P>
<P>function TDefaultFunctions_d_middle_layer(input: Extended): Extended;stdcall;<BR>var ex,ex2:Extended;<BR>begin<BR>ex:=exp(-input);<BR>ex2:=1+ex;<BR>Result:=ex/(ex2*ex2);<BR>end;</P>
<P>function TDefaultFunctions_last_layer(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=input;<BR>end;</P>
<P>function TDefaultFunctions_layer1(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=input;<BR>end;</P>
<P>function TDefaultFunctions_middle_layer(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=1/(1+exp(-input));<BR>end;</P>
<P>{ TFuncions }</P>
<P>constructor TFunctions.Create(DLLFileName: string);<BR>  procedure LoadDefault;<BR>  begin<BR>  layer1:=TDefaultFunctions_layer1;<BR>  d_layer1:=TDefaultFunctions_d_layer1;<BR>  middle_layer:=TDefaultFunctions_middle_layer;<BR>  d_middle_layer:=TDefaultFunctions_d_middle_layer;<BR>  last_layer:=TDefaultFunctions_last_layer;<BR>  d_last_layer:=TDefaultFunctions_d_last_layer;</P>
<P>  DLLHandle:=0;<BR>  end;<BR>begin<BR>DLLHandle:=LoadLibrary(PAnsiChar(DLLFileName));</P>
<P>if DLLHandle=0 then<BR>  begin<BR>  LoadDefault;<BR>  Exit;<BR>  end;</P>
<P>// load from dll<BR>@layer1:=GetProcAddress(DLLHandle,'layer1');<BR>@d_layer1:=GetProcAddress(DLLHandle,'d_layer1');<BR>@middle_layer:=GetProcAddress(DLLHandle,'middle_layer');<BR>@d_middle_layer:=GetProcAddress(DLLHandle,'d_middle_layer');<BR>@last_layer:=GetProcAddress(DLLHandle,'last_layer');<BR>@d_last_layer:=GetProcAddress(DLLHandle,'d_last_layer');<BR>end;</P>
<P>destructor TFunctions.Destroy;<BR>begin<BR>  if DLLHandle=0 then<BR>    FreeLibrary(DLLHandle);<BR>  inherited;<BR>end;</P>
<P><BR>end.</P>


<P>//////////////使用例子1 - BP.in//////////////////</P>
<P><BR>3 1 3 1<BR>0.000000000001 0.3 3 11 100000<BR>1<BR>-5.874<BR>2<BR>-5.994<BR>0.5<BR>-5.469<BR>3<BR>4<BR>-5<BR>6<BR>-7<BR>8<BR>-0.9<BR>0.25<BR>0.75<BR>-1<BR>-1.24<BR></P>
<P>////////////////////使用例子2 - BP.in/////////////////////</P>
<P>BPTest3.dll<BR>4 2 3 3 2<BR>0.00000001 0.3 20 0 1000000 0.3<BR>0.05 0.02<BR>1 0<BR>0.09 0.11<BR>1 0<BR>0.12 0.20<BR>1 0<BR>0.15 0.22<BR>1 0<BR>0.20 0.25<BR>1 0<BR>0.75 0.75<BR>0 1<BR>0.80 0.83<BR>0 1<BR>0.82 0.80<BR>0 1<BR>0.90 0.89<BR>0 1<BR>0.95 0.89<BR>0 1<BR>0.09 0.04<BR>1 0<BR>0.10 0.10<BR>1 0<BR>0.14 0.21<BR>1 0<BR>0.18 0.24<BR>1 0<BR>0.22 0.28<BR>1 0<BR>0.77 0.78<BR>0 1<BR>0.79 0.81<BR>0 1<BR>0.84 0.82<BR>0 1<BR>0.94 0.93<BR>0 1<BR>0.98 0.99<BR>0 1</P>

<P>///////////////BPTest3.dll 源程序////////////////////</P>
<P>library BPTest3;</P>
<P>function layer1(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=input;<BR>end;</P>
<P>function middle_layer(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=1/(1+exp(-input));<BR>end;</P>
<P>function last_layer(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=1/(1+exp(-input));<BR>end;</P>
<P>function d_layer1(input: Extended): Extended;stdcall;<BR>begin<BR>Result:=1;<BR>end;</P>
<P>function d_middle_layer(input: Extended): Extended;stdcall;<BR>var ex,ex2:Extended;<BR>begin<BR>ex:=exp(-input);<BR>ex2:=1+ex;<BR>Result:=ex/(ex2*ex2);<BR>end;</P>
<P>function d_last_layer(input: Extended): Extended;stdcall;<BR>var ex,ex2:Extended;<BR>begin<BR>ex:=exp(-input);<BR>ex2:=1+ex;<BR>Result:=ex/(ex2*ex2);<BR>end;</P>
<P>exports<BR>  layer1,<BR>  middle_layer,<BR>  last_layer,<BR>  d_layer1,<BR>  d_middle_layer,<BR>  d_last_layer;</P>
<P>begin<BR>end.</P>








<P>多多指教</P>
 楼主| 发表于 2005-10-17 21:09:27 | 显示全部楼层
<>最近才发现这个程序有点问题,改正和改进了,如下:</P>

<>{<BR>  BP 算法 源程序<BR>  ** 1. 用BP算法对神经网络进行训练<BR>  ** 2. 对额外的神经网络输入计算输出值<BR>  2005, by stlxv<BR>  <a href="mailtstlxv@21cn.com" target="_blank" >stlxv@21cn.com</A></P>
<>  输入文件:BP.in<BR>  第一行:DLL文件名<BR>  第二行:layer_count, n(1), n(2), ... , n(layer_count) ;n(i) &lt;--第i层神经元个数<BR>  第三行:允许误差ε 学习率η 学习实例个数N 附加测试输入个数M 迭代次数(若0则不计迭代次数) 最低学习率min_yita<BR>    // 若迭代次数为零,则最低学习率可以不用写<BR>    // 若迭代次数不为零,则学习率为最高学习率,且必须输入最低学习率<BR>  接下来是学习实例,每个学习实例2行:<BR>    第一行:输入的n(1)个数<BR>    第二行:期望的输出<BR>  再接下来是M个测试输入<BR>    测试输入<BR>  N&lt;=40,M&lt;=100<BR>  n(i)&lt;=MAX_note  // 通过修改常量MAX_layer_count来修改<BR>  3&lt;=layer_count&lt;=MAX_layer_count  // 通过修改常量MAX_note来修改<BR>  0&lt;η&lt;1,推荐0.3&lt;=η&lt;=0.9<BR>  输入:[0,1]</P>
<P>  注意:误差E[j,k]=1/2*(y*[j,k]-y[j,k])^2&lt;=ε</P>
<P>  输出文件:BP.out<BR>  第一行:总迭代次数<BR>  接下来N行:对应每个学习实例的输出和测试输入的输出<BR>  接下来为所有权值<BR>}</P>
<P>uses<BR>  SysUtils,<BR>  Windows,<BR>  ClassFunctionsUnit in 'ClassFunctionsUnit.pas';</P>
<P>{ Global Variables }</P>
<P>const MAX_note=20;  // 一层神经元个数<BR>      MAX_layer_count=10;</P>
<P>var<BR>  yita,epsilon,min_yita,delta_yita:Extended;<BR>  layer_count,t,k,instance_count,total_time,ExtraCount:integer;<BR>    // t - 迭代次数,k - 学习实例序号,total_time - 总迭代次数<BR>  func:TFunctions;<BR>  n:array[1..MAX_layer_count] of integer; // 每层的神经元个数<BR>  instances:array[1..140] of record // 学习实例 <BR>    X,Y:array[1..MAX_note] of Extended;<BR>    end;</P>
<P>  W:array[1..MAX_layer_count-1] of array[1..MAX_note,1..MAX_note] of Extended;<BR>  IO_map:array[1..MAX_layer_count,1..MAX_note] of record<BR>    I,Extended;<BR>    end;<BR>  E:array[1..MAX_note] of Extended;  // E - 神经网络输出误差<BR>  delta:array[1..MAX_layer_count,1..MAX_note] of Extended;</P>
<P>{ Global Procedures }</P>
<P>  procedure LoadFromFile;<BR>  var F:TextFile;<BR>      FileName:String;<BR>      i,j:integer;<BR>  begin<BR>  AssignFile(F,'BP.in');<BR>  Reset(F);<BR>  Readln(F,FileName);</P>
<P>  func:=TFunctions.Create(FileName);</P>
<P>  Read(F,layer_count);</P>
<P>  for i:=1 to layer_count do<BR>    read(f,n);<BR>  Readln(F);</P>
<P>  Read(F,epsilon);<BR>  read(F,yita);<BR>  Read(F,instance_count);<BR>  Read(F,ExtraCount);<BR>  Read(F,total_time);<BR>  if total_time&gt;0 then Read(F,min_yita);<BR>  Readln(F);</P>
<P>  for i:=1 to instance_count do<BR>    begin<BR>    for j:=1 to n[1] do<BR>      read(f,instances.X[j]);<BR>    Readln(F);<BR>    for j:=1 to n[layer_count] do<BR>      read(F,Instances.Y[j]);<BR>    Readln(F);<BR>    end;<BR>  if ExtraCount&gt;0 then<BR>    for i:=instance_count+1 to ExtraCount+instance_count do<BR>      begin<BR>      for j:=1 to n[1] do<BR>        read(f,instances.X[j]);<BR>      Readln(F);<BR>      end;</P>
<P>  CloseFile(F);<BR>  end;</P>
<P>  procedure MapIO;forward;</P>
<P>  procedure WriteResultToFile;<BR>  var F:TextFile;<BR>      i,j,r:integer;<BR>  begin<BR>  AssignFile(F,'BP.out');<BR>  Rewrite(F);<BR>  Writeln(F,t-1);<BR>  //for k:=1 to instance_count do<BR>  k:=1;<BR>  while k&lt;=instance_count+ExtraCount do<BR>    begin<BR>    MapIO;<BR>    if n[1]&gt;1 then<BR>      for i:=1 to n[1]-1 do<BR>        write(F,Format('%8.8f,',[Instances[k].X]));<BR>    write(F,Format('%8.8f',[Instances[k].X[n[1]]]));<BR>    write(F,'   --&gt;   ');<BR>    if n[layer_count]&gt;1 then<BR>      for i:=1 to n[layer_count]-1 do<BR>        write(F,Format('%8.8f,',[IO_map[layer_count,i].O]));<BR>    writeln(F,Format('%8.8f',[IO_map[layer_count,n[layer_count]].O]));<BR>    k:=k+1;<BR>    end;<BR>  for i:=1 to layer_count-1 do<BR>    for j:=1 to n do<BR>      for r:=1 to n[i+1] do<BR>        Writeln(F,Format('w(%d,%d-&gt;%d,%d): %8.8f',[i,j,i+1,r,W[j,r]]));<BR>  CloseFile(F);<BR>  end;</P>
<P>  procedure Init;<BR>  var i,j,r:integer;<BR>  begin<BR>  // init W<BR>  for i:=1 to layer_count-1 do<BR>    for j:=1 to n do<BR>      for r:=1 to n[i+1] do<BR>        W[j,r]:=Random(100)/1000;<BR>  //init t,k<BR>  t:=1;<BR>  k:=1;<BR>  // init delta_yita<BR>  if total_time&gt;0 then<BR>    delta_yita:=(yita-min_yita)/total_time<BR>    else delta_yita:=0;<BR>  end;</P>
<P>  function computeIn(layer,q:integer):Extended;<BR>  { TEST OK }<BR>    // 计算layer层第q个神经元的输入<BR>  var j:integer;<BR>      a,b:Extended;<BR>  begin<BR>  if layer=1 then<BR>    begin<BR>    Result:=Instances[k].X[q];<BR>    Exit;<BR>    end;</P>
<P>  Result:=0;<BR>  for j:=1 to n[layer-1] do<BR>    begin<BR>    a:=IO_map[layer-1,j].O;<BR>    b:=W[layer-1][j,q];<BR>    Result:=Result+a*b;<BR>    end;<BR>  end;</P>
<P>  { MapIO 搞定所有神经元的输入输出值 }<BR>  procedure MapIO;<BR>  var i,j:integer;<BR>  begin<BR>  for i:=1 to layer_count do<BR>    for j:=1 to n do<BR>      begin<BR>      IO_map[i,j].I:=computeIn(i,j);<BR>      if i=1 then<BR>        IO_map[i,j].=func.layer1(IO_map[i,j].I)<BR>      else begin<BR>        if i=layer_count then<BR>          IO_map[i,j].=func.last_layer(IO_map[i,j].I)<BR>        else IO_map[i,j].=func.middle_layer(IO_map[i,j].I);<BR>        end;<BR>      end;<BR>  end;</P>
<P>  { computeE 计算神经网络的输出误差,在<BR>    调用该过程前要先MapIO }<BR>  procedure computeE;<BR>  var i:integer;<BR>  begin<BR>  for i:=1 to n[layer_count] do<BR>    E:=sqr(Instances[k].Y-IO_map[layer_count,i].O)/2;<BR>  end;</P>
<P>  procedure computeDelta;<BR>  { maybe test OK }<BR>  var i,j,r:integer;<BR>      x:Extended;<BR>  begin<BR>  for i:=1 to n[layer_count] do<BR>    delta[layer_count,i]:=(IO_map[layer_count,i].O-Instances[k].Y)*<BR>      func.d_last_layer(IO_map[layer_count,i].I);<BR>  for i:=layer_count-1 downto 1 do<BR>    for j:=1 to n do<BR>      begin<BR>      x:=0;<BR>      for r:=1 to n[i+1] do<BR>        x:=x+delta[i+1,r]*W[j,r];<BR>      if i&gt;1 then<BR>        // middle layer<BR>        x:=x*func.d_middle_layer(IO_map[i,j].I)<BR>        else // first layer<BR>        x:=x*func.d_layer1(IO_map[i,j].I);<BR>      delta[i,j]:=x;<BR>      end;<BR>  end;</P>
<P>  procedure makeWChange;<BR>  { maybe Test OK }<BR>  var deltaW:Extended;<BR>      i,j,r:integer;<BR>  begin<BR>  for i:=1 to layer_count-1 do<BR>    for j:=1 to n do<BR>      for r:=1 to n[i+1] do<BR>        begin<BR>        deltaW:=-yita*delta[i+1,r]*IO_map[i,j].O;<BR>        W[j,r]:=W[j,r]+deltaW;<BR>        end;<BR>  end;</P>
<P>  function isInRange:Boolean;<BR>  var i:integer;<BR>  begin<BR>  Result:=True;<BR>  for i:=1 to n[layer_count] do<BR>    if E&gt;epsilon then begin Result:=False; break; end;<BR>  end;</P>
<P>  function isAllInRange:Boolean;<BR>  var old_k:integer;<BR>  begin<BR>  MapIO;<BR>  computeE;<BR>  if not isInRange then<BR>    begin<BR>      Result:=False;<BR>      Exit;<BR>    end;</P>
<P>  old_k:=k;<BR>  Result:=True;</P>
<P>  //  while (k&lt;=instance_count)and(k&lt;&gt;old_k) do<BR>  for k:=1 to instance_count do<BR>    if k&lt;&gt;old_k then <BR>    begin<BR>    MapIO;<BR>    computeE;<BR>    if not isInRange then<BR>      begin<BR>      Result:=False;<BR>      break;<BR>      end;<BR>    end;</P>
<P>  k:=old_k;<BR>  end;</P>
<P>  procedure MainCompute;<BR>  begin<BR>  while true do<BR>    begin<BR>    if (total_time&gt;0) and (t&gt;total_time) then break;<BR>    if isAllInRange then Break;<BR>//    MapIO;   &lt;-- included in isAllInRange<BR>//    computeE;<BR>    computeDelta;<BR>    makeWChange;<BR>    t:=t+1;<BR>    k:=((k+1) mod instance_count)+1;<BR>    yita:=yita-delta_yita;<BR>    end;<BR>  end;</P>
<P>begin<BR>Randomize;<BR>LoadFromFile;</P>
<P>Init;<BR>MainCompute;</P>
<P>WriteResultToFile;</P>
<P>func.Free;<BR>end.<BR></P>
发表于 2005-10-19 19:30:11 | 显示全部楼层
<>高手!佩服!</P>
您需要登录后才可以回帖 登录 | 注-册-帐-号

本版积分规则

小黑屋|手机版|Archiver|数学建模网 ( 湘ICP备11011602号 )

GMT+8, 2024-11-27 06:23 , Processed in 0.060814 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表