⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netunit.pas

📁 用Delphi写的车牌字符各种特征提取实验系统
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    for k:=0 to n1 do
    sum:=sum+conn[k,j]*l1[k];
    l2[j]:=squash(sum);
  end;
end;


procedure TNetForm.bpnn_output_error(var delta, target, output: D1Array;
  nj: integer);   //输出误差
var
  j:integer;
  o,t:double;
begin
  setlength(delta,nj+1);
  setlength(target,nj+1);
  setlength(output,nj+1);
  for j:=1 to nj do   //循环计算delta
  begin
    o:=output[j];
    t:=target[j];
    delta[j]:=o*(1.0-o)*(t-o);
  end;
end;

//随机初始化权值
procedure TNetForm.bpnn_randomize_weights(var w: D2Array; m, n: integer);
var
  i,j:integer;
begin
  setlength(w,m+1,n+1);
  for i:=0 to m do
    for j:=0 to n do
     w[i,j]:=Dpn1();
end;

procedure TNetForm.bpnn_zero_weights(var w: D2Array; m, n: integer);
var
  i,j:integer;
begin
  setlength(w,m+1,n+1);
  for i:=0 to m do
    for j:=0 to n do
      w[i,j]:=0.0;
end;

procedure TNetForm.BPTrain(Sender:TObject;var Data_in, Data_out: D2Array; n_in,
  n_hidden: integer; min_ex, momentum, eta: double; num: integer);
var
  i,k,n,l,n_out:integer;
  ex:double;
  input_unites,hidden_unites,output_unites:D1Array;
  output_deltas,hidden_deltas,target:D1Array;
  Showoutput_unites:D2Array;
  input_weights,hidden_weights:D2Array;
  input_prev_weights,hidden_prev_weights:D2Array;
  digitalcount:integer;
  E:WideString;
begin
  ex:=0;
  l:=0;
  n_out:=5;
  //为各个数据结构申请内存空间
  input_unites:= alloc_1d_dbl(n_in+1);
  hidden_unites:=alloc_1d_dbl(n_hidden+1);
  output_unites:=alloc_1d_dbl(n_out+1);
  output_deltas:=alloc_1d_dbl(n_hidden+1);
  hidden_deltas:=alloc_1d_dbl(n_out+1);
  target:=alloc_1d_dbl(n_out+1);
  input_weights:=alloc_2d_dbl(n_in+1,n_hidden+1);
  hidden_weights:=alloc_2d_dbl(n_in+1,n_hidden+1);
  input_prev_weights:=alloc_2d_dbl(n_hidden+1,n_out+1);
  hidden_prev_weights:=alloc_2d_dbl(n_hidden+1,n_out+1);
  //  为产生随机序列播种
  bpnn_initialize;
  //对各种权值进行初始化
  bpnn_randomize_weights(input_weights,n_in,n_hidden);
  bpnn_randomize_weights(hidden_weights,n_hidden,n_out);
  bpnn_zero_weights(input_prev_weights,n_in,n_hidden);
  bpnn_zero_weights(hidden_prev_weights,n_hidden,n_out);
  //开始对BP网络训练,设定最大迭代次数为15000次
   digitalcount:=num;
   Showoutput_unites:=alloc_2d_dbl(digitalcount+1,n_out+1,);
    bpnn_zero_weights(Showoutput_unites,digitalcount,n_out);
    for n:=1 to StrToInt(repeateNumEdit.text) do
    begin
  // data_in:=code(Sender,Img,digitalcount,16,20 );
   for l:=0 to 15000  do
   begin
    for k:=0 to num-1 do
    begin
    //将样本特征向量输送到输入层
      for i:=1 to n_in do
        input_unites[i]:=data_in[k,i-1];
    // 将预定的理想输出输入到BP网络的理想输出单元
        for i:=1 to n_out do
          target[i]:=data_out[k,i-1];
          target0edit.Text :=floattostr(data_out[k,n_out-1]);
          target1edit.Text :=floattostr(data_out[k,n_out-2]);
          target2edit.Text:=floattostr(data_out[k,n_out-3]);
          target3edit.Text :=floattostr(data_out[k,n_out-4]);
          target4edit.Text :=floattostr(data_out[k,n_out-5]);

    // 将数据由输入层传到隐含层
       bpnn_layerforward(input_unites,hidden_unites,input_weights,n_in,n_hidden);
    // 将隐含层的输出传到输出层
      bpnn_layerforward(hidden_unites,output_unites,hidden_weights,n_hidden,n_out);
    // 误差计算
       bpnn_output_error(output_deltas,target,output_unites,n_out);
       bpnn_hidden_error(hidden_deltas,n_hidden,output_deltas,n_out,
                         hidden_weights,hidden_unites);
    //权值调整
       bpnn_adjust_weights(output_deltas,n_out,hidden_unites,n_hidden,
                     hidden_weights,hidden_prev_weights,eta,momentum);
       bpnn_adjust_weights(hidden_deltas,n_hidden,input_unites,n_in,
                    input_weights,input_prev_weights,eta,momentum);
       //误差统计
       for i:=1 to n_out do
       begin
       ex:=ex+(output_unites[i]-data_out[k,i-1])*(output_unites[i]-data_out[k,i-1]);
      Showoutput_unites[k,i]:=output_unites[i]
       end;
  //每个字的解
    end;
     ex:=ex/(num*n_out);
   // 跳出循环
    if ex<min_ex then
      break;
     end;
       memo2.Lines .add('第'+inttostr(n)+'次五个结点的输出值:');
        for i:=0 to num-1 do
        memo2.Lines.Add(inttostr(i)+'的值:'+'   '+format('%5.3f',[showoutput_unites[i,1]])+'  '+
        format('%5.3f',[showoutput_unites[i,2]])+'  '+
        format('%5.3f',[showoutput_unites[i,3]])+'  '+
        format('%5.3f',[showoutput_unites[i,4]])+'  '+
        format('%5.3f',[showoutput_unites[i,5]])+'  '+#13);
       memo2.lines.add('迭代次数为:'+inttostr(l)+#13);

     //迭代次数控制
  //相关保存
    //输入层到隐含层的权值
  end;      //训练次数反复
        n_out0Edit.Text:=floattostr(output_unites[5]);
        n_out1Edit.Text:=floattostr(output_unites[4]);
        n_out2Edit.Text:=floattostr(output_unites[3]);
        n_out3Edit.Text:=floattostr(output_unites[2]);
        n_out4Edit.Text:=floattostr(output_unites[1]);
    w_weight(input_weights,n_in,n_hidden,Pchar(nhyschar+'输入层到隐含层.txt'));
    //隐含层到输出层的权值
    w_weight(hidden_weights,n_hidden,n_out,Pchar(nhyschar+'隐含层到输出层.txt'));
    //保存各层结点的数目
    w_num(n_in,n_hidden,n_out,Pchar('各层结点数.txt'));
    if ex<=min_ex then
      trainresult.Caption :=format('平均误差为%.4f',[ex]);
    if ex>min_ex then
      trainresult.Caption :=format('训练失败!迭代了%d次'+#13'平均误差为%.4f',[l,ex]);
    //释放内存空间
    setlength(input_unites,0);
    setlength(hidden_unites,0);
    setlength(output_unites,0);
    setlength(hidden_deltas,0);
    setlength(hidden_deltas,0);
    setlength(target,0);
    setlength(input_weights,0);
    setlength(hidden_weights,0);
    setlength(input_prev_weights,0);
    setlength(hidden_prev_weights,0);
end;

function TNetForm.code(Sender:Tobject;Img: TImage; num, imagewidth,
  imageHeight: integer): D2Array;
var
  i,k:integer;
  DataSum:Double;
  Data:D2Array;
  E:WideString;
  PathString:string;
//////////////////////////////////////////////////
//  smin,smax:integer;
//  minarray,maxarray,ytemp:array of integer;
//////////////////////////////////////////////////
begin
  Pathstring:=ExtractFilePath(Application.ExeName)+'\carNumber\'+nhyschar;
  E:= memo3.Text;
  setLength(data,num+1,201);
 for k:=0 to num-1 do
 begin
   if E <> '' then
   begin
  {   charImage.Picture:=NIL;
     CharImage.Canvas.Font.Name:='黑体';
     charimage.Canvas.Font.Color := clBlack;
     charimage.Canvas.Font.Size :=48;
     charimage.Canvas.TextOut(0, 0, E[k+1]+'    ') ;   }
     charimage.Picture.LoadFromFile(Pathstring+'\'+inttostr(k)+'.bmp');
////////////////////////////////////////////////////////////////////////////////

     if nhyschar<>'汉字' then TextForm.ClearSmall(Sender,CharImage,CharImage);
     GetRegion(CharImage.Picture.Bitmap);
     Zoom;
    // TextForm.Xihua1(NormalImage.Picture.Bitmap);
     TextForm.ImageTeZheng(NormalImage);
   //  ListBox1.Items.Add(IntToStr(k)+'  '+E[k+1]);
     Img.Picture:=NormalImage.Picture;
     for i:=1 to 32 do
     begin
    {   TenToTwo(MainUnit.LineSum[i],Tout);
       for j:=1 to 5 do
       begin
         if Tout[j]=1 then Data[k,(i-1)*5+j-1]:=0.9
         else Data[k,(i-1)*5+j-1]:=0.1;
       end;

       TenToTwo(MainUnit.RowSum[i],Tout);
       for j:=1 to 5 do
       begin
         if Tout[j]=1 then Data[k,(i-1)*5+j+160-1]:=0.9
         else Data[k,(i-1)*5+j+160-1]:=0.1;
       end;

       TenToTwo(MainUnit.LineColorJmpE[i]-MainUnit.LineColorJmpS[i],Tout);
       for j:=1 to 5 do
       begin
         if Tout[j]=1 then Data[k,(i-1)*5+j+320-1]:=0.9
         else Data[k,(i-1)*5+j+160-1]:=0.1;
       end;

       TenToTwo(MainUnit.RowColorJmpE[i]-MainUnit.RowColorJmpS[i],Tout);
       for j:=1 to 5 do
       begin
         if Tout[j]=1 then Data[k,(i-1)*5+j+480-1]:=0.9
         else Data[k,(i-1)*5+j+160-1]:=0.1;
       end;       }
        Data[k,i]:=MainUnit.LineSum[i]/DataDiv;
        Data[k,i+32]:=MainUnit.RowSum[i]/DataDiv;
        Data[k,i+64]:=MainUnit.LineColorJmpS[i]/DataDiv;
        Data[k,i+96]:=MainUnit.LineColorJmpE[i]/DataDiv;
        Data[k,i+128]:=MainUnit.RowColorJmpS[i]/DataDiv;
        Data[k,i+160]:=MainUnit.RowColorJmpE[i]/DataDiv;
      end;
      for i:=1 to 4 do
      begin
        Data[k,i+192]:=MainUnit.FourColorCenterx[i]/DataDiv;
        Data[k,i+196]:=MainUnit.FourColorCentery[i]/DataDiv;
      end;
    end;
 end;
////////////////////////////////////////////////////////////////////////////////
  result:=Data;
end;

// 进行识别,并将识别结果写出
procedure TNetForm.CodeRecognize(var Data_in:D1Array;
n_in,n_hidden,n_out:integer;resultlabel: TLabel);
var
  i:integer;
  input_unites,hidden_unites,output_unites:D1Array;
  input_weights,hidden_weights:D2Array;
  output_unites8421:D1Num;
begin
  input_unites:=alloc_1d_dbl(n_in+1) ;
  hidden_unites:=alloc_1d_dbl(n_hidden+1);
  output_unites:=alloc_1d_dbl(n_out+1);
  setlength(output_unites8421,6);
  input_weights:=alloc_2d_dbl(n_in+1,n_hidden+1);
  hidden_weights:=alloc_2d_dbl(n_hidden+1,n_out+1);
  if r_weight(input_weights,n_in,n_hidden,TextInput)          ////////////////////////////////
                                           =false then exit;   ///////////////////////////////////
  if r_weight(hidden_weights,n_hidden,n_out,TextCenter)
                                     =false then  exit;
  begin
    for i:=1 to n_in do
      input_unites[i]:=data_in[i-1];
    //前向激活
     bpnn_layerforward(input_unites,hidden_unites,input_weights,n_in,n_hidden);
     bpnn_layerforward(hidden_unites,output_unites,hidden_weights,n_hidden,n_out);
             for i:=1 to 5 do
          begin
            if output_unites[i]>0.55 then
                    output_unites8421[i-1]:=1
           else
                    output_unites8421[i-1]:=0;
         end;
        n_out0Edit.Text:=floattostr(output_unites[4]);
        n_out1Edit.Text:=floattostr(output_unites[3]);
        n_out2Edit.Text:=floattostr(output_unites[2]);
        n_out3Edit.Text:=floattostr(output_unites[1]);
        n_out4Edit.Text:=floattostr(output_unites[0]);
  //根据输出结果进行识别
  //显示识别产生的输出码
  if  nhyschar='数字' then
  begin
    if (output_unites8421[4]=0) and (output_unites8421[3]=0) and (output_unites8421[2]=0) and  (output_unites8421[1]=0)
                    and(output_unites8421[0]=0 ) then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -