zhbrest 发表于 2006-3-23 16:46

[求助]求高手指点 bp神经网络

我想做一个2层的bp神经网络<BR>有自己的用户界面<BR>数据为excel<BR>求高手指点<BR>1.怎么直接在界面下像安装软件一样选择文件路径以及文件。<BR>2.数据中第一行、列的汉字调入后怎么才不会出错。(删除?)<BR>3.我要做的是预测和评价,应该怎么选择训练、学习函数。<BR>4.结果输出到excel或记事本的语句怎么写阿。<BR><BR>???????<BR>谢谢高手指点<BR><BR>

happy 发表于 2006-3-24 08:14

回复:(zhbrest)[求助]求高手指点 bp神经网络

以下是引用zhbrest在2006-3-23 16:46:27的发言:
我想做一个2层的bp神经网络
有自己的用户界面
数据为excel
求高手指点
1.怎么直接在界面下像安装软件一样选择文件路径以及文件。
这个要用Gui实现

2.数据中第一行、列的汉字调入后怎么才不会出错。(删除?)
你用什么读入的?用xlsread的话,自动会忽略

3.我要做的是预测和评价,应该怎么选择训练、学习函数。
这个和的具体问题有关,相关matlab实现可以看《Matlab神经网络应用设计》

4.结果输出到excel或记事本的语句怎么写阿。
保存成excel文件比较麻烦,下面再回复
保存成txt,用fprintf就能实现,具体看帮助


???????
谢谢 高手指点

happy 发表于 2006-3-24 08:15

回复:(zhbrest)[求助]求高手指点 bp神经网络

如何将matlab求出的矩阵保存在EXCEL表格中<BR>
<P>转贴Genial分享程序</P>
<P><FONT color=#ff3300>function xlswrite(m,header,colnames,filename);<BR></FONT>% xlswrite   Easily create an Excel spreadsheet from MATLAB<BR>%<BR>%xlswrite(m,header,colnames,filename) creates a Microsoft Excel spreadsheet using<BR>%the MATLAB ActiveX interface.Microsoft Excel is required.<BR>%<BR>%Inputs:<BR>%    m          Matrix to write to file<BR>% (Optional):<BR>%    header   String of header information.Use cell array for multiple lines<BR>%                  DO NOT USE multiple row character arrays!!<BR>%    colnames   (Cell array of strings) Column headers.One cell element per column<BR>%    filename   (string) Name of Excel file.If not specified, contents will<BR>%                  be opened in Excel.<BR>%<BR>% ex:<BR>%   m = rand(100,4);<BR>%   header = \'my data\';<BR>%   %header{1} = \'first line\';      %This will give<BR>%   %header{2} = \'second line\';   % 2 header lines<BR>%   colnames = {\'Ch1\',\'Ch2\',\'Ch3\',\'Ch4\'};<BR>%<BR>%   xlswrite(m,header,colnames,\'myfile.xls\');<BR>%      will save the spreadsheet as myfile.xls.The user<BR>%         will never see Excel<BR>%   xlswrite(m,header,colnames);<BR>%      will open Excel with these contents in a new spreadsheet.<BR>%      <BR><BR><BR>% Scott Hirsch<BR>% The MathWorks<BR>% This is provided free, no warranty, ...<BR><BR>% Copied from ActiveX example in documentation<BR><BR> = size(m);<BR>if nc&gt;256<BR>    error(\'Matrix is too large.Excel only supports 256 columns\');<BR>end;<BR><BR>% Open Excel, add workbook, change active worksheet, <BR>% get/put array, save.<BR>% First, open an Excel Server.<BR>Excel = actxserver(\'Excel.Application\');<BR><BR><BR>%If the user does not specify a filename, we\'ll make Excel visible<BR>%If they do, we\'ll just save the file and quit Excel without ever making<BR>% it visible<BR>if nargin&lt;4<BR>    set(Excel, \'Visible\', 1);      %You might want to hide this if you autosave the file<BR>end;<BR><BR>% Insert a new workbook.<BR>Workbooks = Excel.Workbooks;<BR>Workbook = invoke(Workbooks, \'Add\');<BR><BR>% Make the first sheet active.<BR>Sheets = Excel.ActiveWorkBook.Sheets;<BR>sheet1 = get(Sheets, \'Item\', 1);<BR>invoke(sheet1, \'Activate\');<BR><BR>% Get a handle to the active sheet.<BR>Activesheet = Excel.Activesheet;<BR><BR>%Write header<BR>if nargin&lt;2 | isempty(header)<BR>    nhr=0;<BR>elseif iscell(header)<BR>    nhr = length(header);       %Number header rows<BR>    for ii=1:nhr<BR>      ActivesheetRange = get(Activesheet,\'Range\',[\'A\' num2str(ii)],[\'A\' num2str(ii)]);<BR>      set(ActivesheetRange, \'Value\', header{ii});<BR>    end;<BR>else<BR>    nhr = 1;                  %Number header rows<BR>    ActivesheetRange = get(Activesheet,\'Range\',\'A1\',\'A1\');<BR>    set(ActivesheetRange, \'Value\', header);<BR>end;<BR><BR><BR>%Add column names<BR>if nargin&gt;2 &amp; ~isempty(colnames)<BR>    nhr = nhr + 1;      %One extra column name<BR>    ncolnames = length(colnames);<BR>    for ii=1:ncolnames<BR>      colname = localComputLastCol(\'A\',ii);<BR>      %    cellname = ;<BR>      cellname = ;<BR>      ActivesheetRange = get(Activesheet,\'Range\',cellname,cellname);<BR>      set(ActivesheetRange, \'Value\', colnames{ii});<BR>    end;<BR>end;<BR><BR><BR>% Put a MATLAB array into Excel.<BR>FirstRow = nhr+1;         %You can change the first data row here.I start right after the headers<BR>LastRow = FirstRow+nr-1;<BR>FirstCol = \'A\';         %You can change the first column here<BR>LastCol = localComputLastCol(FirstCol,nc);<BR>ActivesheetRange = get(Activesheet,\'Range\',,);<BR>set(ActivesheetRange, \'Value\', m);<BR><BR>% If user specified a filename, save the file and quit Excel<BR>if nargin==4<BR>    invoke(Workbook, \'SaveAs\', );<BR>    invoke(Excel, \'Quit\');<BR>    <BR>    = fileparts(filename);<BR>    disp([\'Excel file \' name \'.xls has been created.\']);<BR>end;<BR><BR>%Delete the ActiveX object<BR>delete(Excel)<BR><BR></P>
<P><FONT color=#f73809>function LastCol = localComputLastCol(FirstCol,nc);</FONT><BR>% Comput the name of the last column where we will place data<BR>%Input<BR>%FirstCol(string) name of first column<BR>%nc      total number of columns to write<BR><BR>%Excel\'s columns are named:<BR>% A B C ... A AA AB AC AD .... BA BB BC ...<BR>FirstColOffset = double(FirstCol) - double(\'A\');    %Offset from column A<BR>if nc&lt;=26-FirstColOffset       %Easy if single letter<BR>    %Just convert to ASCII code, add the number of needed columns, and convert back<BR>    %to a string<BR>    LastCol = char(double(FirstCol)+nc-1);<BR>else<BR>    ng = ceil(nc/26);       %Number of groups (of 26)<BR>    rm = rem(nc,26)+FirstColOffset;      %How many extra in this group beyond A<BR>    LastColFirstLetter = char(double(\'A\') + ng-2);<BR>    LastColSecondLetter = char(double(\'A\') + rm-1);<BR>    LastCol = ;<BR>end;</P>
<P><FONT color=#ff0000>使用方法:</FONT></P>
<P>&gt;&gt; m = rand(100,4);<BR>&gt;&gt; header = \'my data\';<BR>&gt;&gt; colnames = {\'Ch1\',\'Ch2\',\'Ch3\',\'Ch4\'};<BR>&gt;&gt;xlswrite(m,header,colnames,\'myfile.xls\');<BR>Excel file myfile.xls has been created.</P>

happy 发表于 2006-3-24 08:18

回复:(zhbrest)[求助]求高手指点 bp神经网络

方法二<BR><BR>
<P>来自simwe liuxc0206 分享</P><PRE><FONT color=#ff0000>function eOut = table2excel(varargin)</FONT>
%        TABLE2EXCEL is a special function is used to insert data to excell
%        files.
%         inputs :
%                 1. argument should be either a filename or
%                 2. argument is a struct of cell arrays or a string
%                                                         
%         Example:
%         xtable.Data = {'a','b','c'};
%         xtable.Labels = {'label1','label2','label3'};
%         xtable.SeparationStr = '%%%'; % Can be empty
%         xtable.MergeWidth = 2;
%         xtable.Group      = 'Table 1';
%         %For Initializing the excel you can use also
%         % excel = TABLE2EXCEL('foo.xls','open'); this inserts no table.
%         excel = TABLE2EXCEL('foo.xls',xtable); %if Fails it opens a new workbook
%         %Then Insert another column to the same workbook
%         TABLE2EXCEL(excel,xtable); %etc
%         %Then Close it
%         TABLE2EXCEL(excel,'close');
%         In Excel you see following pattern
%               Table is constructed from A to I Yo can Extend this range
%               by changing eColEnd variable. The Excel is visible when you
%               add some data this behavior can be made off by commented
%               out the lines containing such command 'excel.Visible = 1'.
%               A       B       C       D       E       F       G       H       I   
% Separation 1   %%%   %%%   %%%   %%%   %%%   %%%   %%%   %%%   %%%
% Group      2                                  Table 1                                       
%         3   label1      a               a
%         4   label2      b               b
%         5   label3      c               c
%         
%         From B2 to I2 are merged. A2(the cell before group names) should be
%         an char(187) for some reason.

%         Author: Ibrahim ONARAN
%         Date:   07 March 2004 Tuesday
%         Time:   17:24


if nargin&lt;1
    error('Should be at least 1 argument');
end
% First, open an Excel Server.
excel                         = varargin{1};

if isa(excel,'COM.excel.application') %It is handle
    eWB = excel.ActiveWorkbook;
    if(~isempty(eWB)) %It has a active workbook
      %Closes And Saves The Excel
      if eWB.ReadOnly
            eWB.Close;
            Quit(excel);
            delete(excel);
            error('This File Is Already Open.');
      end
      if nargin &gt; 1 &amp; isstr(varargin{2}) &amp; strfind(lower(varargin{2}),'cl')
            %For Safely Close Excel Handles
            % Now, save the workbook.
            Save(eWB);
            % To avoid saving the workbook and being prompted to do so
            set(eWB, 'Saved', 1);
            % Note: Make sure that you always close any workbooks that you add
            % in Excel. This can prevent potential memory leaks.
            Close(eWB);
            % Quit Excel and delete the server.
            Quit(excel);
            delete(excel);
            return
      end
    else                          %It is not opened before then open a fresh one
      eWB   = excel.Workbooks.Add;
      % Default Name is Book 1 look if this name exist if so advanced the
      % last digit by 1 to become Book2 etc
      if isempty(eWB.Path)
            new_excel_dir = excel.DefaultFilePath;
      else
            new_excel_dir = eWB.Path;
      end
      new_excel_dir = dir(new_excel_dir);
      new_excel_dir = {new_excel_dir.name};
      i = 1;
      new_excel_name = 'Book%d.xls';
      while(strmatch(sprintf(new_excel_name,i),new_excel_dir))
            i = i + 1;
      end
      new_excel_name = sprintf(new_excel_name,i);
      eWB.SaveAs(new_excel_name); %No File Name Given So Save it As it is
      eWB.Saved = 1;
    end
else
    %recieved a filename to open
    excel = actxserver('excel.application');
    = fileparts(varargin{1});
    if isempty(dir_file)
      dir_file = pwd;
    end
    if isempty(ext_file)
      ext_file = '.xls';
    end
    filename = ;
    try
      eWB= excel.Workbooks.Open(filename);
      if eWB.ReadOnly
            eWB.Close;
            Quit(excel);
            delete(excel);
            error('This File Is Already Open');
      end
    catch
      if ishandle(excel)
            eWB   = excel.Workbooks.Add;      %if file doesn't exist create a new file
            eWB.SaveAs(filename);
            eWB.Saved = 1;
      else
            rethrow(lasterror); %For handling eWB.ReadOnly Part
      end
    end
    if nargin &gt; 1 &amp; isstr(varargin{2}) &amp; strfind(lower(varargin{2}),'op')
      eOut = excel;
      return
    end
end

% Get a handle to the active sheet.
eAS       = excel.ActiveSheet;
% Get a handle to the active Workbook.
eAWB = excel.ActiveWorkbook;
eColEnd = 'I' - 'A' + 1;
%Font Name
fontName           = 'Courier New';
CharPerRow      = 8; %Depends on font size and column width
NoElementStr    = '---';
char187         = char(187);
char160         = char(160);

if length(varargin) &lt; 2
    Fields = [];
else
    Fields = varargin{2};
end

if(~isfield(Fields,'Labels'))                  
    Labels= {'Label1';'Label2'};
else       
    Labels= Fields.Labels(:);         %Make it Column
end

if(~isfield(Fields,'MergeWidth'))       
    MergeWidth        = 2;
else       
    MergeWidth         = Fields.MergeWidth;
end

if(~isfield(Fields,'Data'))                       
    Data= {'Data 1';'Data 2'};
else       
    Data= Fields.Data(:); %First make it column and reshape
end
idt   = length(Data);
ilb   = length(Labels);
if(idt&lt;ilb)
    Labels(end-) = []; % No data Avaliable So No Label Required
else
    Data = Data(1:floor(idt/ilb)*ilb);
    Data = reshape(Data,ilb,floor(idt/ilb));
end


if(~isfield(Fields,'Group'))               
    Group = 'DEFAULT GROUP';
else       
    Group                 = Fields.Group;        
end
Group = ; %This make group name unique

if(~isfield(Fields,'SeparationStr'))               
    SeparationStr        = {'***'};
else       
    SeparationStr        = Fields.SeparationStr;        
end

if isfield(Fields,'SheetName')
    SheetName        = Fields.SheetName;        
    SheetName(find()) = '|';
    SheetName(find(SheetName == ':' )) = ';';
    if(SheetName(end)=='|')
      SheetName(end) = [];
    end
    if(length(SheetName&gt;31))
      SheetName = ;
    end
    % Try to find sheet with name SheetName
    if ~strcmp(SheetName,eAS.Name)
      try
            i = 1;
            while(1)
                if strcmp(eAWB.Sheets.Item(i).Name,SheetName)
                  %Sheet found, Activate it
                  eAWB.Sheets.Item(i).Activate;
                  eAS       = excel.ActiveSheet;
                  break;
                end
                i = i+1;
            end
      catch %Can not find the sheet=&gt;Add new sheet and rename it.
            eAWB.Sheets.Add;
            eAS = excel.ActiveSheet;
            eAS.Name = SheetName;
            
      end
    end
end


%eFG = Find Group
%eFE = Find Empty
%eR= Temporary Range

while ~isempty(Data)
    %Try to Find Group
    eR = eAS.UsedRange;    %Used Range
    eFG = eR.Find(Group);%Find Group
    insert_new_table = 1;
    if(~isempty(eFG)) %If find a group name
      eFG = FindPrevious(eR,eFG);                        %Find Last Occurance Of Label
      eR= getrange(eAS,1,eFG.Row+1,eColEnd,eFG.Row+1);%Find An Empty Space To Insert New Data
      eFE = Find(eR,'');                                  %Find An Empty Space To Insert New Data
      if ~isempty(eFE) &amp; (eFE.Column + MergeWidth &lt; eColEnd+2)                                 
            %If Empty Space Found and Column Index does not Exceed Limits
            insert_new_table = 0;
      end
    end
   
    if insert_new_table
      %Find An Empty Space To Insert Table
      eR = eAS.UsedRange;    %Used Range
      nRow    = eR.Rows.Count;
      if nRow == 1
            eR       = getrange(eAS,1,1,1,1); %New WorkSheet
            set(eR,'VerticalAlignment',2,'WrapText',1);                % 2 Center
            set(eR,'Value',char187,'HorizontalAlignment',3);   % 3 Center
            set(get(eR,'font'),'name',fontName,'bold',1);            % Set Field Bold
            eR       = getrange(eAS,1,1,eColEnd,1); %New WorkSheet
      else
            eR       = getrange(eAS,1,eR.Row+nRow-1,eColEnd,eR.Row+nRow-1); %Go To End of used range
      end            

      %Insert Seperation String
      if(~isempty(SeparationStr))
            Insert(eR,3);
            eR          = getrange(eAS,1,eR.Row-1,1,eR.Row-1);
            eR.Value    = char187;
            eR = getrange(eAS,2,eR.Row,eColEnd,eR.Row);
            eR.Value    = SeparationStr;
            eR = getrange(eAS,1,eR.Row,eColEnd,eR.Row);
            set(eR,'VerticalAlignment',2,'WrapText',1);                % 2 Center
            set(eR,'HorizontalAlignment',3);   % 3 Center
            set(get(eR,'font'),'name',fontName,'bold',1);            % Set Field Bold
            % If Separtion Inserted then advanced the row
            eR      = getrange(eAS,1,eR.Row+1,eColEnd,eR.Row+1);      
      end
      
      %Insert Group Name
      Insert(eR,3); %Inserts A Row
      if(isempty(SeparationStr))
            eR          = getrange(eAS,1,eR.Row-1,1,eR.Row-1);
            eR.Value    = char187;
            eR          = getrange(eAS,2,eR.Row,eColEnd,eR.Row);
      else
            eR          = getrange(eAS,2,eR.Row-1,eColEnd,eR.Row-1);
      end
      Merge(eR);
      eR.Value = Group;
      eR          = getrange(eAS,1,eR.Row,eColEnd,eR.Row);
      set(eR,'VerticalAlignment',2,'WrapText',1);      % 2 Center
      set(eR,'HorizontalAlignment',3);   % 3 Center
      set(get(eR,'font'),'name',fontName,'bold',1);      % Set Field Bold
      eFG   = eR;         %Store the group name for further usage
      
      %Write Labels
      %First Remove Labels With No Corresponding Data
      k = 0;
      for i=1:length(Labels)
         if strcmp(Data{i-k,1},NoElementStr)
               Data(i-k,:) = [];
               Labels(i-k) = [];
               k = k+1;
         end
      end
      eR      = getrange(eAS,1,eFG.Row+1,1,eFG.Row+length(Labels));
      Insert(eR,3);   %Inserts Rows
      eR      = getrange(eAS,1,eFG.Row+1,1,eFG.Row+length(Labels));
      set(eR,'Value',Labels,'HorizontalAlignment',3);    % 3 Center
      
      %Store Empty Cell
      eFE   = getrange(eAS,2,eFG.Row+1,2,eFG.Row+1);
      eR      = getrange(eAS,2,eFG.Row+1,eColEnd,eFG.Row+length(Labels));
      %When inserting new cells it copies the format of first upper cells
      %to the inserted cells. But we don't want data to be bold.
      eR.font.bold = 0;
      if(eFE.Column+MergeWidth &gt; eColEnd)
            MergeWidth = eColEnd - eFE.Column; %Make Full Table Width
      end
    else
      %This part handles the new inserted labels (always does this check even if labels are same)
      %Find Old Labels
      eR      = eAS.UsedRange;
      eRowEnd = eR.Rows.Count + eR.Row;
      eR      = getrange(eAS,1,eFG.Row+1,1,eRowEnd);
      eF      = eR.Find(char187); %Key Point, The Left Cell of a Group Name Should always Be char187
      eR      = getrange(eAS,1,eFG.Row+1,1,eF.Row-1);
      oldLabels = eR.Value; %Be careful always when getting a value from excel
      %It may not be a cell
      if ~iscell(oldLabels) oldLabels = {oldLabels};end
      %It may not be a cell str
      for i = 1:length(oldLabels)
            if isnumeric(oldLabels{i})
                oldLabels{i} = num2str(oldLabels{i});
                %         elseif ~isstr(oldLabels{i})
                %               I don't know else ???    numeric,string,... ?
            end
      end
      newLabels = oldLabels;
      newData   = repmat({NoElementStr},length(oldLabels),size(Data,2));
      %Insert New Labels Reorder Data And Labels
      for i = 1:length(Labels)
            iLabelx = strmatch(Labels{i},oldLabels,'exact');
            if(isempty(iLabelx)) % A New Label!
                newLabels(end+1) = Labels(i);
                newData(end+1,:) = Data(i,:);
                %Insert New Line
                iRow    = eFG.Row+length(newLabels);
                eINS    = getrange(eAS,1,iRow,eColEnd,iRow);
                Insert(eINS);
                eRsource= getrange(eAS,2,iRow-1,eFE.Column-1,iRow-1);
                eR      = getrange(eAS,2,iRow,eFE.Column-1,iRow);
                eRsource.Copy(eR);
                eR.Value= NoElementStr;
                eR      = getrange(eAS,1,iRow,1,iRow);
                eR.Value= newLabels{end};
            else
                newData(iLabelx,:) = Data(i,:);
            end
      end
      Data    = newData;
      Labels= newLabels;
    end
    %Write Datas
    for j = 1:size(Data,2)
      k = j*MergeWidth + eFE.Column -1;
      if eColEnd &lt; k | isempty(Data)
            break; %Break Loop And Insert New Table
      end
      %Control Old Labels
      for i = 1:size(Data,1)
            eR = getrange(eAS,k-MergeWidth+1,eFG.Row+i,k,eFG.Row+i);
            Merge(eR);
            set(eR,'Value',Data(i,1),'HorizontalAlignment',3);    % 3 Center
      end
      Data(:,1) = [];
    end
end   

if nargout == 1 | isa(excel,'COM.excel.application');
    %Don't Save Workbook since we will continue to use it
    if(~excel.Visible)
      set(excel, 'Visible', 1);
    end
    if nargout == 1
      eOut = excel;
    end
end
</PRE>

happy 发表于 2006-3-24 08:19

回复:(zhbrest)[求助]求高手指点 bp神经网络

<P><FONT color=#ff0000>function eRange = getrange(eAS,c1,r1,c2,r2)</FONT><BR>%Assume both c,r are start from1 and numeric all is supplied<BR>x = ('Z' - 'A' +1);<BR>if c1&gt;=1&amp;c2&gt;=1<BR>    ch0 = floor((c1-1)/x);ch1 = char(rem(c1-1,x) + 'A');<BR>    if(~ch0) ch0 = '';else ch0 = char(ch0 +'A' -1);end <BR>    c1 = ;<BR>    ch0 = floor((c2-1)/x);ch1 = char(rem(c2-1,x) + 'A');<BR>    if(~ch0) ch0 = '';else ch0 = char(ch0 +'A' -1);end <BR>    c2 = ;<BR>else<BR>    c1='';c2='';<BR>end<BR>if r1&gt;=1&amp;r2&gt;=1<BR>    r1 = int2str(r1);r2 = int2str(r2);<BR>else<BR>    r1='';r2='';<BR>end<BR>if ~isempty(r1) | ~isempty(c1)<BR>    eRange   = ;<BR>else<BR>    eRange = 'A1:A1';<BR>end<BR>eRange = Range(eAS,eRange);<BR><BR></P>
<P><FONT color=#f73809>Example:<BR></FONT>%         xtable.Data = {\'a\',\'b\',\'c\'};<BR>%         xtable.Labels = {\'label1\',\'label2\',\'label3\'};<BR>%         xtable.SeparationStr = \'%%%\'; % Can be empty<BR>%         xtable.MergeWidth = 2;<BR>%         xtable.Group      = \'Table 1\';<BR>%         %For Initializing the excel you can use also <BR>%         % excel = TABLE2EXCEL(\'foo.xls\',\'open\'); this inserts no table.<BR>%         excel = TABLE2EXCEL(\'foo.xls\',xtable); %if Fails it opens a new workbook<BR>%         %Then Insert another column to the same workbook<BR>%         TABLE2EXCEL(excel,xtable); %etc<BR>%         %Then Close it<BR>%         TABLE2EXCEL(excel,\'close\');<BR>%         In Excel you see following pattern<BR>%               Table is constructed from A to I Yo can Extend this range<BR>%               by changing eColEnd variable. The Excel is visible when you<BR>%               add some data this behavior can be made off by commented<BR>%               out the lines containing such command \'excel.Visible = 1\'.<BR>%               A       B       C       D       E       F       G       H       I   <BR>% Separation 1   %%%   %%%   %%%   %%%   %%%   %%%   %%%   %%%   %%%<BR>% Group      2                                  Table 1                                       <BR>%         3   label1      a               a<BR>%         4   label2      b               b<BR>%         5   label3      c               c<BR>%         <BR>%         From B2 to I2 are merged. A2(the cell before group names) should be <BR>%         an char(187) for some reason. <BR><BR>%         Author: Ibrahim ONARAN<BR>%         Date:   07 March 2004 Tuesday<BR>%         Time:   17:24<BR><BR><BR></P>
页: [1]
查看完整版本: [求助]求高手指点 bp神经网络