BP神经网络分类以及对算法进行改进—MATLAB实现

一 BP神经网络介绍

  BP神经网络是一种具有三层或三层以上的多层前馈神经网络,每一层都由若干个神经元组成,如下图所示,它的左、右各层之间各个神经元实现全连接,即左层的每一个神经元与右层的每个神经元都有连接,而上下各神经元之间无连接。BP神经网络按有导师学习方式进行训练,当一对学习模式提供给网络后,其神经元的激活值将从输入层经各隐含层向输出层传播,在输出层的各神经元输出对应于输入模式的网络响应。
  该网络的主要特点是信号前向传递,误差反向传播。在前向传递中,输入信号从输人层经隐含层逐层处理,直至输出层。每一层的神经元状态只影响下一层神经元状态。如果输出层得不到期望输出,则转入反向传播,根据预测误差调整网络权值和阔值,从而使BP神经网络预测输出不断逼近期望输出。
在这里插入图片描述
  上图中, X 1 , X 2 , ⋅ ⋅ ⋅ , X n X_1,X_2,···,X_n X1,X2,,Xn是BP神经网络的输入值, Y 1 , Y 2 , ⋅ ⋅ ⋅ , Y m Y_1,Y_2,···,Y_m Y1,Y2,,Ym是BP神经网络的预测值, ω i j 和 ω j k \omega_{ij}和\omega_{jk} ωijωjk为BP神经网络权值。从上图可以看出,BP神经网络可以看成一个非线性函数,网络输入值和预测值分别为该函数的自变量和因变量。当输入节点数为n、输出节点数为m时,BP神经网络就表达了从n个自变量到m个因变量的函数映射关系。
  BP神经网络预测前首先要训练网络,通过训练使网络具有联想记忆和预测能力。BP神
经网络的训练过程包括以下几个步骤。

  1. 网络初始化。根据系统输人输出序列( X X X, Y Y Y)确定网络输入层节点数 n n n、隐含层节点数 l l l,输出层节点数 m m m,初始化输入层、隐含层和输出层神经元之间的连接权值 ω i j 和 ω j k \omega_{ij}和\omega_{jk} ωijωjk初始化隐含层阔值 a a a,输出层國值 b b b,给定学习速率和神经元激励函数。

  2. 隐含层输出计算。根据输入变量 X X X,输入层和隐含层间连接权值 ω i j \omega_{ij} ωij,以及隐含层國值 a a a,计算隐含层输出 H H H
    H j = f ( ∑ i = 1 n ω i j x i − a j )         j = 1 , 2 ⋅ ⋅ ⋅ , l (1-1) H_j = f(\sum\limits_{i=1}^n\omega_{ij}x_i-a_j)~~~~~~~j=1,2···,l\tag{1-1} Hj=f(i=1nωijxiaj)       j=1,2,l(1-1)
    式中, l l l为隐含层节点数; f f f为隐含层激励函数,该函数有多种表达形式,本文所选函数为:
    f ( x ) = 1 1 + e − x (1-2) f(x) = \frac{1}{1+e^{-x}}\tag{1-2} f(x)=1+ex1(1-2)

  3. 输出层输出计算。根据隐含层输出 H H H,连接权值 ω j k \omega_{jk} ωjk和阈值 b b b,计算BP神经网络
    预测输出 O O O
    O k = ∑ k = 1 l H j ω j k − b k         k = 1 , 2 ⋅ ⋅ ⋅ , m (1-3) O_k = \sum\limits_{k=1}^lH_j\omega_{jk}-b_k~~~~~~~k=1,2···,m\tag{1-3} Ok=k=1lHjωjkbk       k=1,2,m(1-3)

  4. 误差计算。根据网络预测输出 O O O和期望输出 Y Y Y,计算网络预测误差 e e e
    e k = Y k − O k         k = 1 , 2 ⋅ ⋅ ⋅ , m (1-4) e_k = Y_k-O_k~~~~~~~k=1,2···,m\tag{1-4} ek=YkOk       k=1,2,m(1-4)

  5. 权值更新。根据网络预测误差 e e e更新网络连接权值 ω i j , ω j k \omega_{ij},\omega_{jk} ωij,ωjk
    ω i j = ω i j + η H j ( 1 − H j ) ∑ k = 1 m ω j k e k         i = 1 , 2 , ⋅ ⋅ ⋅ , n ; j = 1 , 2 ⋅ ⋅ ⋅ , l ω j k = ω j k + η H j e k         j = 1 , 2 , ⋅ ⋅ ⋅ , l ; k = 1 , 2 , ⋅ ⋅ ⋅ , m \omega_{ij} = \omega_{ij} + \eta H_j(1-H_j)\sum\limits_{k=1}^m\omega_{jk}e_k~~~~~~~i = 1,2,···,n;j=1,2···,l\\ \omega_{jk} = \omega_{jk} + \eta H_je_k~~~~~~~j =1,2,···,l;k = 1,2,···,m ωij=ωij+ηHj(1Hj)k=1mωjkek       i=1,2,,n;j=1,2,lωjk=ωjk+ηHjek       j=1,2,,l;k=1,2,,m
    式中, η \eta η为学习速率。

  6. 阈值更新。根据网络预测误差 e e e更新网络节点國值 a , b a,b a,b
    a j = a j + η H j ( 1 − H j ) ∑ k = 1 m ω j k e k         j = 1 , 2 ⋅ ⋅ ⋅ , l b k = b k + e k         k = 1 , 2 , ⋅ ⋅ ⋅ , m a_j = a_j + \eta H_j(1-H_j)\sum\limits_{k=1}^m\omega_{jk}e_k~~~~~~~j=1,2···,l\\ b_k =b_k + e_k~~~~~~~k = 1,2,···,m aj=aj+ηHj(1Hj)k=1mωjkek       j=1,2,lbk=bk+ek       k=1,2,,m

  7. 判断算法迭代是否结束,若没有结束,返回步骤2。

二 案例应用—语音特征信号识别

2.1 案例说明

  语音特征信号识别是语音识别研究领域中的一个重要方面,一般采用模式匹配的原理解决。语音识别的运算过程为:首先,待识别语音转化为电信号后输人识别系统,经过预处理后用数学方法提取语音特征信号,提取出的语音特征信号可以看成该段语音的模式;然后,将该段语音模型同已知参考模式相比较,获得最佳匹配的参考模式为该段语音的识别结果。语音识别流程如下图所示。

在这里插入图片描述
  本案例选取了民歌、古筝、摇滚和流行四类不同音乐,用BP神经网络实现对这四类音乐的有效分类。每段音乐都用倒谱系数法提取500组24维语音特征信号(相关数据放在最后),提取出的语音特征信号如下图所示。
在这里插入图片描述
  基于BP神经网络的语音特征信号分类算法建模包括BP神经网络构建、BP 神经网络训
练和BP神经网络分类三步,算法流程如下图所示。
在这里插入图片描述
  BP神经网络构建根据系统输入输出数据特点确定BP神经网络的结构,由于语音特征输入信号有24维,待分类的语音信号共有4类,所以BP神经网络的结构为24-25-4,即输入层有24个节点,隐含层有25个节点,输出层有4个节点。
  BP神经网络训练用训练数据训练BP神经网络。共有2000组语音特征信号,从中随机选择1500组数据作为训练数据训练网络,500组数据作为测试数据测试网络分类能力。
  BP神经网络分类用训练好的神经网络对测试数据所属语音类别进行分类。

2.2 MATLAB实现

2.2.1 数据归一化

  数据归一化方法是神经网络预测前对数据常做的一种处理方法。数据归一化处理把所有数据都转化为[0,1]之间的数,其目的是取消各维数据间数量级差别,避免因为输入输出数据数量级差别较大而造成网络预测误差较大。数据归一化的方法主要有以下两种。
  1)最大最小法。函数形式如下
x k = x k − x m i n x m a x − x m i n x_k = \frac{x_k - x_{min}}{x_{max} - x{min}} xk=xmaxxminxkxmin
式中, x m i n x_{min} xmin为数据序列中的最小数; x m a x x_{max} xmax为序列中的最大数。
  2)平均数方差法。函数形式如下:
x k = x k − x m e a n x v a r x_k = \frac{x_k - x_{mean}}{x_{var}} xk=xvarxkxmean
式中, x m e a n x_{mean} xmean为数据序列的均值; x v a r x_{var} xvar为数据的方差。
  本案例采用第一种数据归一化方法,归一化函数采用MATLAB自带函数mapminmax,该函数有多种形式,常用的方法如下:

%input_train,output_train分别是训练输入、输出数据
[inputn,inputps]=mapminmax(input_train);
[outputn,outputps]=mapminmax(output_train);

  input_train,output_train 是训练输人、输出原始数据;;inputn,outputn是归一化后的数据,inputps,outputps为数据归一化后得到的结构体,里面包含了数据最大值、最小值和平均值等信息,可用于测试数据归一化和反归一化。测试数据归一化和反归一化程序如下:

inputn_test = mapminmax('apply', input_test, inputps); %测试输入数据归一化
BPoutput = mapminmax('reverse', an, outputps);%网络预测数据反归一化

  input_test是预测输人数据;inputn_test是归一化后的预测数据;'apply’表示根据inputps的值对input_test进行归一化。an是网络预测结果;outputps是训练输出数据归一化得到的结构体;BPoutput是反归一化之后的网络预测输出;'reverse’表示对数据进行反归一化。

2.2.2 编程实现

2.2.2.1数据选择和归一化

  首先根据倒谱系数法提取四类音乐语音特征信号,不同的语音信号分别用1,2,3,4标识,提取出的信号分别存储于datal.mat, data2.mat,data3.mat,,data4.mat数据库文件中,每组数据为25维,第1维为类别标识,后24维为语音特征信号。然后把四类语音特征信号合为一组,从中随机选取1500组数据作为训练数据,500组数据作为测试数据,并对训练数据进行归一化处理。根据语音类别标识设定每组语音信号的期望输出值,如标识类为1时,期望输出向量为[1 0 0 0]。

%% 清空环境变量
clc
clear

%% 训练数据预测数据提取及归一化

%下载四类语音信号
load data1 c1
load data2 c2
load data3 c3
load data4 c4

%四个特征信号矩阵合成一个矩阵
data(1:500,:)=c1(1:500,:);
data(501:1000,:)=c2(1:500,:);
data(1001:1500,:)=c3(1:500,:);
data(1501:2000,:)=c4(1:500,:);

%12000间随机排序
k=rand(1,2000);
[m,n]=sort(k);

%输入输出数据
input=data(:,2:25);
output1 =data(:,1);

%把输出从1维变成4维
output=zeros(2000,4);
for i=1:2000
    switch output1(i)
        case 1
            output(i,:)=[1 0 0 0];
        case 2
            output(i,:)=[0 1 0 0];
        case 3
            output(i,:)=[0 0 1 0];
        case 4
            output(i,:)=[0 0 0 1];
    end
end

%随机提取1500个样本为训练样本,500个样本为预测样本
input_train=input(n(1:1500),:)';
output_train=output(n(1:1500),:)';
input_test=input(n(1501:2000),:)';
output_test=output(n(1501:2000),:)';

%输入数据归一化
[inputn,inputps]=mapminmax(input_train);

2.2.2.2 BP神经网络结构初始化

  根据语音特征信号特点确定BP神经网络的结构为24-25-4,随机初始化BP神经网络
权值和阔值。

%% 网络结构初始化
innum=24;
midnum=25;
outnum=4;
 

%权值初始化
w1=rands(midnum,innum);
b1=rands(midnum,1);
w2=rands(midnum,outnum);
b2=rands(outnum,1);

w2_1=w2;w2_2=w2_1;
w1_1=w1;w1_2=w1_1;
b1_1=b1;b1_2=b1_1;
b2_1=b2;b2_2=b2_1;

%学习率
xite=0.1;
alfa=0.01;
loopNumber=10;
I=zeros(1,midnum);
Iout=zeros(1,midnum);
FI=zeros(1,midnum);
dw1=zeros(innum,midnum);
db1=zeros(1,midnum);
2.2.2.3 BP神经网络训练

  用训练数据训练BP神经网络,在训练过程中根据网络预测误差调整网络的权值和阈值。

%% 网络训练
E=zeros(1,loopNumber);
for ii=1:loopNumber
    E(ii)=0;
    for i=1:1:1500
       %% 网络预测输出 
        x=inputn(:,i);
        % 隐含层输出
        for j=1:1:midnum
            I(j)=inputn(:,i)'*w1(j,:)'+b1(j);
            Iout(j)=1/(1+exp(-I(j)));
        end
        % 输出层输出
        yn=w2'*Iout'+b2;
        
       %% 权值阀值修正
        %计算误差
        e=output_train(:,i)-yn;     
        E(ii)=E(ii)+sum(abs(e));
        
        %计算权值变化率
        dw2=e*Iout;
        db2=e';
        
        for j=1:1:midnum
            S=1/(1+exp(-I(j)));
            FI(j)=S*(1-S);
        end      
        for k=1:1:innum
            for j=1:1:midnum
                dw1(k,j)=FI(j)*x(k)*(e(1)*w2(j,1)+e(2)*w2(j,2)+e(3)*w2(j,3)+e(4)*w2(j,4));
                db1(j)=FI(j)*(e(1)*w2(j,1)+e(2)*w2(j,2)+e(3)*w2(j,3)+e(4)*w2(j,4));
            end
        end
           
        w1=w1_1+xite*dw1';
        b1=b1_1+xite*db1';
        w2=w2_1+xite*dw2';
        b2=b2_1+xite*db2';
        
        w1_2=w1_1;w1_1=w1;
        w2_2=w2_1;w2_1=w2;
        b1_2=b1_1;b1_1=b1;
        b2_2=b2_1;b2_1=b2;
    end
end
2.2.2.4 BP神经网络分类

  用训练好的BP神经网络分类语音特征信号,根据分类结果分析BP神经网络分类能力。

%% 语音特征信号分类
inputn_test=mapminmax('apply',input_test,inputps);
fore=zeros(4,500);
for ii=1:1
    for i=1:500%1500
        %隐含层输出
        for j=1:1:midnum
            I(j)=inputn_test(:,i)'*w1(j,:)'+b1(j);
            Iout(j)=1/(1+exp(-I(j)));
        end
        
        fore(:,i)=w2'*Iout'+b2;
    end
end
2.2.2.5 结果分析
%% 结果分析
%根据网络输出找出数据属于哪类
output_fore=zeros(1,500);
for i=1:500
    output_fore(i)=find(fore(:,i)==max(fore(:,i)));
end

%BP网络预测误差
error=output_fore-output1(n(1501:2000))';

%画出预测语音种类和实际语音种类的分类图
figure(1)
plot(output_fore,'r')
hold on
plot(output1(n(1501:2000))','b')
legend('预测语音类别','实际语音类别')

%画出误差图
figure(2)
plot(error)
title('BP网络分类误差','fontsize',12)
xlabel('语音信号','fontsize',12)
ylabel('分类误差','fontsize',12)

%print -dtiff -r600 1-4

k=zeros(1,4);  
%找出判断错误的分类属于哪一类
for i=1:500
    if error(i)~=0
        [b,c]=max(output_test(:,i));
        switch c
            case 1 
                k(1)=k(1)+1;
            case 2 
                k(2)=k(2)+1;
            case 3 
                k(3)=k(3)+1;
            case 4 
                k(4)=k(4)+1;
        end
    end
end

%找出每类的个体和
kk=zeros(1,4);
for i=1:500
    [b,c]=max(output_test(:,i));
    switch c
        case 1
            kk(1)=kk(1)+1;
        case 2
            kk(2)=kk(2)+1;
        case 3
            kk(3)=kk(3)+1;
        case 4
            kk(4)=kk(4)+1;
    end
end

%正确率
rightridio=(kk-k)./kk;
disp('正确率')
disp(rightridio);

结果如下:
在这里插入图片描述
BP神经网络分类误差如下图所示:
在这里插入图片描述
BP神经网络分类正确率如下表所示:

语音信号类别第一类第二类第三类第四类
识别正确率0.78231.00000.81950.8837

  从BP神经网络分类结果可以看出,基于BP神经网络的语音信号分类算法具有较高的准确性,能够准确识别出语音信号所属类别。

2.3 算法改进

  BP神经网络的隐含层节点数对BP神经网络预测精度有较大的影响:节点数太少,网络不能很好地学习,需要增加训练次数,训练的精度也受影响;节点数太多,训练时间增加,网络容易拟合。最佳隐含层节点数选择可参考如下公式:
l < n − 1 l < ( m + n ) + a l = log ⁡ 2 n \begin{aligned} l&<n-1\\ l&<\sqrt{(m+n)} + a\\ l &= \log_2n \end{aligned} lll<n1<(m+n) +a=log2n
式中, n n n为输入层节点数; l l l为隐含层节点数; m m m为输出层节点数; a a a为0~10之间的常数。在实际问题中,隐含层节点数的选择首先是参考公式来确定节点数的大概范围,然后用试凑法确定最佳的节点数。对于某些问题来说,隐含层节点数对输出结果影响较小,如对于本案例来说,分类误差同隐含层节点数的关系如下图所示。
在这里插入图片描述
  从上图可以看出,本案例中BP神经网络的分类误差随着隐含层节点数的增加呈现先减少后增加的趋势。也符合一般问题的情况。

2.3.1 附加动量方法

  BP神经网络的采用梯度修正法作为权值和阔值的学习算法,从网络预测误差的负梯度方向修正权值和阈值,没有考虑以前经验的积累,学习过程收敛缓慢。对于这个问题,可以采用附加动量方法来解决,带附加动量的权值学习公式为:
ω ( k ) = ω ( k − 1 ) + △ ω ( k ) + a [ ω ( k − 1 ) − ω ( k − 2 ) ] \omega(k) = \omega(k-1) +\triangle \omega(k) + a[\omega(k-1) - \omega(k-2)] ω(k)=ω(k1)+ω(k)+a[ω(k1)ω(k2)]
式中, ω ( k ) , ω ( k − 1 ) , ω ( k − 2 ) \omega(k),\omega(k-1),\omega(k-2) ω(k),ω(k1),ω(k2)分别为 k , k − 1 , k − 2 k,k-1,k-2 k,k1,k2时刻的权值; a a a为动量学习率。
程序如下:

%% 该代码为基于带动量项的BP神经网络语音识别
%% 清空环境变量
clc
clear

%% 训练数据预测数据提取及归一化

%下载四类语音信号
load data1 c1
load data2 c2
load data3 c3
load data4 c4

%四个特征信号矩阵合成一个矩阵
data(1:500,:)=c1(1:500,:);
data(501:1000,:)=c2(1:500,:);
data(1001:1500,:)=c3(1:500,:);
data(1501:2000,:)=c4(1:500,:);

%12000间随机排序
k=rand(1,2000);
[m,n]=sort(k);

%输入输出数据
input=data(:,2:25);
output1 =data(:,1);

%把输出从1维变成4维
output=zeros(2000,4);
for i=1:2000
    switch output1(i)
        case 1
            output(i,:)=[1 0 0 0];
        case 2
            output(i,:)=[0 1 0 0];
        case 3
            output(i,:)=[0 0 1 0];
        case 4
            output(i,:)=[0 0 0 1];
    end
end

%随机提取1500个样本为训练样本,500个样本为预测样本
input_train=input(n(1:1500),:)';
output_train=output(n(1:1500),:)';
input_test=input(n(1501:2000),:)';
output_test=output(n(1501:2000),:)';

%输入数据归一化
[inputn,inputps]=mapminmax(input_train);

%% 网络结构初始化
innum=24;
midnum=25;
outnum=4;
 
%权值初始化
w1=rands(midnum,innum);
b1=rands(midnum,1);
w2=rands(midnum,outnum);
b2=rands(outnum,1);

w2_1=w2;w2_2=w2_1;
w1_1=w1;w1_2=w1_1;
b1_1=b1;b1_2=b1_1;
b2_1=b2;b2_2=b2_1;

%学习率
xite=0.1;
alfa=0.01;
loopNumber=10;
I=zeros(1,midnum);
Iout=zeros(1,midnum);
FI=zeros(1,midnum);
dw1=zeros(innum,midnum);
db1=zeros(1,midnum);

%% 网络训练
E=zeros(1,loopNumber);
for ii=1:10
    E(ii)=0;
    for i=1:1:1500
       %% 网络预测输出 
        x=inputn(:,i);
        % 隐含层输出
        for j=1:1:midnum
            I(j)=inputn(:,i)'*w1(j,:)'+b1(j);
            Iout(j)=1/(1+exp(-I(j)));
        end
        % 输出层输出
        yn=w2'*Iout'+b2;
        
       %% 权值阀值修正
        %计算误差
        e=output_train(:,i)-yn;     
        E(ii)=E(ii)+sum(abs(e));
        
        %计算权值变化率
        dw2=e*Iout;
        db2=e';
        
        for j=1:1:midnum
            S=1/(1+exp(-I(j)));
            FI(j)=S*(1-S);
        end      
        for k=1:1:innum
            for j=1:1:midnum
                dw1(k,j)=FI(j)*x(k)*(e(1)*w2(j,1)+e(2)*w2(j,2)+e(3)*w2(j,3)+e(4)*w2(j,4));
                db1(j)=FI(j)*(e(1)*w2(j,1)+e(2)*w2(j,2)+e(3)*w2(j,3)+e(4)*w2(j,4));
            end
        end
           
        w1=w1_1+xite*dw1'+alfa*(w1_1-w1_2);
        b1=b1_1+xite*db1'+alfa*(b1_1-b1_2);
        w2=w2_1+xite*dw2'+alfa*(w2_1-w2_2);
        b2=b2_1+xite*db2'+alfa*(b2_1-b2_2);
        
        w1_2=w1_1;w1_1=w1;
        w2_2=w2_1;w2_1=w2;
        b1_2=b1_1;b1_1=b1;
        b2_2=b2_1;b2_1=b2;
    end
end
 

%% 语音特征信号分类
inputn_test=mapminmax('apply',input_test,inputps);
fore=zeros(4,500);
for ii=1:1
    for i=1:500%1500
        %隐含层输出
        for j=1:1:midnum
            I(j)=inputn_test(:,i)'*w1(j,:)'+b1(j);
            Iout(j)=1/(1+exp(-I(j)));
        end
        
        fore(:,i)=w2'*Iout'+b2;
    end
end



%% 结果分析
%根据网络输出找出数据属于哪类
output_fore=zeros(1,500);
for i=1:500
    output_fore(i)=find(fore(:,i)==max(fore(:,i)));
end

%BP网络预测误差
error=output_fore-output1(n(1501:2000))';

%画出预测语音种类和实际语音种类的分类图
figure(1)
plot(output_fore,'r')
hold on
plot(output1(n(1501:2000))','b')
legend('预测语音类别','实际语音类别')

%画出误差图
figure(2)
plot(error)
title('BP网络分类误差','fontsize',12)
xlabel('语音信号','fontsize',12)
ylabel('分类误差','fontsize',12)

%print -dtiff -r600 1-4

k=zeros(1,4);  
%找出判断错误的分类属于哪一类
for i=1:500
    if error(i)~=0
        [b,c]=max(output_test(:,i));
        switch c
            case 1 
                k(1)=k(1)+1;
            case 2 
                k(2)=k(2)+1;
            case 3 
                k(3)=k(3)+1;
            case 4 
                k(4)=k(4)+1;
        end
    end
end

%找出每类的个体和
kk=zeros(1,4);
for i=1:500
    [b,c]=max(output_test(:,i));
    switch c
        case 1
            kk(1)=kk(1)+1;
        case 2
            kk(2)=kk(2)+1;
        case 3
            kk(3)=kk(3)+1;
        case 4
            kk(4)=kk(4)+1;
    end
end

%正确率
rightridio=(kk-k)./kk;
disp('正确率')
disp(rightridio);

结果如下:
在这里插入图片描述
BP神经网络分类误差如下图所示:
在这里插入图片描述
BP神经网络分类正确率如下表所示:

语音信号类别第一类第二类第三类第四类
识别正确率0.70831.00000.96210.9469

2.3.2 变学习率学习方法

  BP神经网络学习率 η \eta η的取值在[0,1]之间,学习率 η \eta η越大,对权值的修改越大,网络学习速度越快。但过大的学习速率 η \eta η将使权值学习过程产生震荡,过小的学习概率使网络收敛过慢,权值难以趋于稳定。变学习率方法是指学习概率 η \eta η在BP神经网络进化初期较大,网络收敛迅速,随着学习过程的进行,学习率不断减小,网络趋于稳定。变学习率计算公式为:
η ( t ) = η m a x − t ( η m a x − η m i n ) / t m a x \eta(t) = \eta_{max} - t(\eta_{max} - \eta_{min})/t_{max} η(t)=ηmaxt(ηmaxηmin)/tmax
式中, η m a x \eta_{max} ηmax为最大学习率; η m i n \eta_{min} ηmin为最小学习率; t m a x t_{max} tmax为最大迭代次数; t t t为当前迭代次数。
代码如下:

%% 该代码为基于变学习率BP网络的语言识别

%% 清空环境变量
clc
clear

%% 训练数据预测数据提取及归一化

%下载四类语音信号
load data1 c1
load data2 c2
load data3 c3
load data4 c4

%四个特征信号矩阵合成一个矩阵
data(1:500,:)=c1(1:500,:);
data(501:1000,:)=c2(1:500,:);
data(1001:1500,:)=c3(1:500,:);
data(1501:2000,:)=c4(1:500,:);

%12000间随机排序
k=rand(1,2000);
[m,n]=sort(k);

%输入输出数据
input=data(:,2:25);
output1 =data(:,1);

%把输出从1维变成4维
output=zeros(2000,4);
for i=1:2000
    switch output1(i)
        case 1
            output(i,:)=[1 0 0 0];
        case 2
            output(i,:)=[0 1 0 0];
        case 3
            output(i,:)=[0 0 1 0];
        case 4
            output(i,:)=[0 0 0 1];
    end
end

%随机提取1500个样本为训练样本,500个样本为预测样本
input_train=input(n(1:1500),:)';
output_train=output(n(1:1500),:)';
input_test=input(n(1501:2000),:)';
output_test=output(n(1501:2000),:)';

%输入数据归一化
[inputn,inputps]=mapminmax(input_train);

%% 网络结构初始化
innum=24;
midnum=15;
outnum=4;
 

%权值初始化
w1=rands(midnum,innum);
b1=rands(midnum,1);
w2=rands(midnum,outnum);
b2=rands(outnum,1);

w2_1=w2;w2_2=w2_1;
w1_1=w1;w1_2=w1_1;
b1_1=b1;b1_2=b1_1;
b2_1=b2;b2_2=b2_1;

%学习率
xite=0.1;
xite2 = 0.9;
alfa=0.01;
loopNumber=10;
I=zeros(1,midnum);
Iout=zeros(1,midnum);
FI=zeros(1,midnum);
dw1=zeros(innum,midnum);
db1=zeros(1,midnum);

%% 网络训练
E=zeros(1,loopNumber);
for ii=1:loopNumber
    E(ii)=0;
    for i=1:1:1500
       %% 网络预测输出 
        x=inputn(:,i);
        % 隐含层输出
        for j=1:1:midnum
            I(j)=inputn(:,i)'*w1(j,:)'+b1(j);
            Iout(j)=1/(1+exp(-I(j)));
        end
        % 输出层输出
        yn=w2'*Iout'+b2;
        
       %% 权值阀值修正
        %计算误差
        e=output_train(:,i)-yn;     
        E(ii)=E(ii)+sum(abs(e));
        
        %计算权值变化率
        dw2=e*Iout;
        db2=e';
        
        for j=1:1:midnum
            S=1/(1+exp(-I(j)));
            FI(j)=S*(1-S);
        end      
        for k=1:1:innum
            for j=1:1:midnum
                dw1(k,j)=FI(j)*x(k)*(e(1)*w2(j,1)+e(2)*w2(j,2)+e(3)*w2(j,3)+e(4)*w2(j,4));
                db1(j)=FI(j)*(e(1)*w2(j,1)+e(2)*w2(j,2)+e(3)*w2(j,3)+e(4)*w2(j,4));
            end
        end
           
        w1=w1_1+(xite2 - ii*(xite2-xite)/loopNumber)*dw1';
        b1=b1_1+(xite2 - ii*(xite2-xite)/loopNumber)*db1';
        w2=w2_1+(xite2 - ii*(xite2-xite)/loopNumber)*dw2';
        b2=b2_1+(xite2 - ii*(xite2-xite)/loopNumber)*db2';
        
        w1_2=w1_1;w1_1=w1;
        w2_2=w2_1;w2_1=w2;
        b1_2=b1_1;b1_1=b1;
        b2_2=b2_1;b2_1=b2;
    end
end
 

%% 语音特征信号分类
inputn_test=mapminmax('apply',input_test,inputps);
fore=zeros(4,500);
for ii=1:1
    for i=1:500%1500
        %隐含层输出
        for j=1:1:midnum
            I(j)=inputn_test(:,i)'*w1(j,:)'+b1(j);
            Iout(j)=1/(1+exp(-I(j)));
        end
        
        fore(:,i)=w2'*Iout'+b2;
    end
end

%% 结果分析
%根据网络输出找出数据属于哪类
output_fore=zeros(1,500);
for i=1:500
    output_fore(i)=find(fore(:,i)==max(fore(:,i)));
end

%BP网络预测误差
error=output_fore-output1(n(1501:2000))';

%画出预测语音种类和实际语音种类的分类图
figure(1)
plot(output_fore,'r')
hold on
plot(output1(n(1501:2000))','b')
legend('预测语音类别','实际语音类别')

%画出误差图
figure(2)
plot(error)
title('BP网络分类误差','fontsize',12)
xlabel('语音信号','fontsize',12)
ylabel('分类误差','fontsize',12)

%print -dtiff -r600 1-4

k=zeros(1,4);  
%找出判断错误的分类属于哪一类
for i=1:500
    if error(i)~=0
        [b,c]=max(output_test(:,i));
        switch c
            case 1 
                k(1)=k(1)+1;
            case 2 
                k(2)=k(2)+1;
            case 3 
                k(3)=k(3)+1;
            case 4 
                k(4)=k(4)+1;
        end
    end
end

%找出每类的个体和
kk=zeros(1,4);
for i=1:500
    [b,c]=max(output_test(:,i));
    switch c
        case 1
            kk(1)=kk(1)+1;
        case 2
            kk(2)=kk(2)+1;
        case 3
            kk(3)=kk(3)+1;
        case 4
            kk(4)=kk(4)+1;
    end
end

%正确率
rightridio=(kk-k)./kk;
disp('正确率')
disp(rightridio);

结果如下:
在这里插入图片描述
BP神经网络分类误差如下图所示:
在这里插入图片描述
BP神经网络分类正确率如下表所示:

语音信号类别第一类第二类第三类第四类
识别正确率0.81671.00000.92920.9250

  可以发现两种改进过后的BP神经网络的结果较于未改进的BP神经网络有了改善。说明此两种改进方法是可行的。

全部代码:
链接:https://pan.baidu.com/s/1KjsNDDJTUrkLNGghKL65Yg
提取码:6666
  
  
  
  

喜欢的小伙伴麻烦点个赞奥,谢谢啦🙏🙏

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱听雨的犬猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值