📄 netunit.pas
字号:
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 + -