zoukankan      html  css  js  c++  java
  • BP的matlab实现

    %2015.04.26 Kang Yongxin ----v 2.0
    %完成作业中BP算法,采用批量方式更新权重
    %%
    %输入数据格式
    %x 矩阵 : 样本个数*特征维度 
    %y 矩阵 :样本个数*类别个数(用01000形式表示)
    close all;
    clear all;
    clc ;
    load data.mat;%
    x_test=x(1:3:30,:);%从原始数据中留出一部分 作为测试样本
    y_test=y(1:3:30,:);
    x_train=[x(2:3:30,:);x(3:3:30,:)];%x(1:2:30,:);%[x(11:25,:);x(26:30,:);x(1:10,:)];
    y_train=[y(2:3:30,:);y(3:3:30,:)];%%[y(11:25,:);y(26:30,:);y(1:10,:)];
    %%
    %定义变量名称,初始化网络
    d=size(x_train,2);%特征维度,也是输入层节点个数
    num_trains=size(x_train,1);%训练样本个数
    n_class=size(y_train,2);%样本类别数
    node_layer=[d 4 n_class];%每层的节点个数 %[d 3 5 n_class];%构建更多层的网络
    num_layer=size(node_layer,2)-1;%网络层数
    for i=1:1:num_layer-1
        f_name{i}='sigmoid';%对应每层的激活函数
    end
    f_name{num_layer}='tanh';%'sigmoid';%最后一层的激活函数
    eta=0.08;%学习率
    theta=10e-4;%终止条件
    W=cell(num_layer,1);%初始化权重矩阵,都设曾1,
    for i=1:1:num_layer
        W{i}=rand(node_layer(i),node_layer(i+1));
    end
    W_init=W;
    %开始循环
    item=1;
    while item>0 && item<1500
      %%
      %初始化权值增量
       for layer=1:1:num_layer
            delta_sum{layer}=zeros(size(W{layer})) ;
       end
       %%
        for k=1:1:num_trains
            %对于每个样本的循环
           %%%%%%%%%%%%%%%%%%%
            %前向计算
            x_in=x_train(k,:);
            for layer=1:1:num_layer
                %对于每一层进行前向计算,并且保存输出值y_out
                y_out{layer}=forward(x_in,W{layer},f_name{layer});%批量更新时候W要跟随外层循环
                x_in=y_out{layer};
            end
            %%%%%%%%%%%%%%%
            %%%%%%%%%%%%%% 
            %反向传播,最后一层要单算,因为只有一个输出 
            delta_out{layer}=y_train(k,:)-y_out{layer};%输出与真值的差
            J(k)=0.5*sum(delta_out{layer}.^2);%均方误
            delta_error{layer}=delta_out{layer}.*d_function(y_out{layer},f_name{num_layer});%从指向节点收集到的误差
            delta_w{layer}=eta*(y_out{layer-1})'*delta_error{layer};%本层的权重变化量
            while layer>1
               %反向传播误差,保存delta_w
               layer=layer-1;
               delta_error{layer}=delta_error{layer+1}*(W{layer+1})'.*d_function(y_out{layer},f_name{layer});%从指向节点收集到的误差并使用之前的权重进行加权
               if layer~=1
                   %如果没到第一层,就用layer-1层的输出作为输入
                   delta_w{layer}=eta*(y_out{layer-1})'*delta_error{layer};%本层的权重变化量
               else
                   %如果是第一层就用本次训练的x作为输入   
                   delta_w{layer}=eta*(x_train(k,:))'*delta_error{layer};%本层的权重变化量
               end
            end  
           %%%%%%%%%%%%%%%
           %%%%%%%%%%%%%%%%%
           %批量更新,要对所有样的贡献进行加和
           for layer=1:1:num_layer
                delta_sum{layer}=delta_sum{layer}+delta_w{layer} ;
           end
        end%k个样本对权重 变化量的贡献计算完毕
        %%
        
        figure(1);
        JW(item)=sum(J);
        if item>10
            Delta_JW=abs(JW(item)-JW(item-1));
            if Delta_JW<theta
                 break;%循环终止条件
            end
        end
        plot(item,JW(item),'.')
        hold on;
        item=item+1;
        
      %更新权重
        for layer=1:1:num_layer
            %对于每一层更新权重,这个更新放的位置决定是进行批量更新还是每次更新
           W{layer}=W{layer}+delta_sum{layer};%批量更新
        end
    end
    %%
    %计算准确率
    x_in=x_test;
    for layer=1:1:num_layer
        %对于每一层进行前向计算,并且保存输出值y_out
        y_out{layer}=forward(x_in,W{layer},f_name{layer});%批量更新时候W要跟随外层循环
        x_in=y_out{layer};
    end
    [C,I]=max(y_out{layer},[],2);        
    [C,I_true]=max(y_test,[],2);
    Trues=find((I-I_true)==0);
    Precision=size(Trues,1)/size(y_test,1)
    
    function [ y ] = forward( x,w,f_name )
    %FORWARD 前向计算得到输出值
    %   输入 x:输入向量1*m
    %        w:权重矩阵m*n
    %        f_name:函数名称(暂时支持'sigmoid''tanh')
    %   输出 y:输出向量1*n 公式为  y=f(x*w)
    if strcmp(f_name,'sigmoid')
        y=sigmoid(x*w);
    else if strcmp(f_name,'tanh')
            y=tanh(x*w);%matlab 自带
        else
           disp('wrong function name ');
        end
    end
    end
    function [d_f ] = d_function( y,f_name )
    %D_FOUNCTION 对相关函数进行求导数
    %   输入是该层的输出值y 
    if strcmp(f_name,'sigmoid')
        d_f=y.*(1-y);
    else if strcmp(f_name,'tanh')
            d_f=1-y.^2;%matlab 自带
        else
           disp('wrong function name at d_function');
        end
    end
    end
    
    
    function [ y ] = sigmoid( x )
    %MY_SIGMOID 
    %   输入向量x,输出
    y=1./(1+exp(-x));
    end
    
    
  • 相关阅读:
    IXmlSerializable With WCFData Transfer in Service Contracts
    Difference Between XmlSerialization and BinarySerialization
    Using XmlSerializer (using Attributes like XmlElement , XmlAttribute etc ) Data Transfer in Service Contracts
    Introducing XML Serialization
    Version Tolerant Serialization
    Which binding is bestWCF Bindings
    Data Transfer in Service Contracts
    DataContract KnownTypeData Transfer in Service Contracts
    Using the Message ClassData Transfer in Service Contracts
    DataContract POCO SupportData Transfer in Service Contracts
  • 原文地址:https://www.cnblogs.com/simayuhe/p/5437083.html
Copyright © 2011-2022 走看看