利用BP神经网络对语音数据进行分类

原创 2017年05月21日 11:19:01

最近给学院老师的一篇论文帮忙改进BP神经网络,由于最后要发表论文,神经网络必须自己手写,搞了几个晚上,总算把基础的BP神经网络写出来,接下来再把老师的改进算法实现就ok了。(当然那代码不能公开了)我这里用的是《MATLAB神经网络43个案例分析》这本书中的语音数据集。(PS:神经网络的学习笔记没时间整理,马上蓝桥杯国赛,比赛结束回学校又是课设,这学期为了机器学习专业课也就是上课听听,还要火线复习把不喜欢的嵌入式专业课给应付过去,估计只有暑假再整理写博客发表了!!!!!)


Python代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017/5/14 17:13
# @Author  : DaiPuWei
# @Site    : 计通303实验室
# @File    : BPNN.py
# @Software: PyCharm Community Edition

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from copy import deepcopy
from sklearn.preprocessing import MinMaxScaler

class BPNN:
    def __init__(self,Train_Data,Train_Label):
        """
        这是BPNN类的构造函数
        :param Train_Data:训练数据集
        :param Train_Label: 训练数据集标记
        :param Test_Label: 测试数据集标记
        """
        self.Train_Data = Train_Data                                                 #训练数据
        self.Train_Label = Train_Label                                               #训练数据标签
        self.input_n = np.shape(Train_Data)[1]                                       #输入层神经元个数
        self.hidden_n = self.input_n - 2                                             #隐含层神经元个数
        self.output_n = np.shape(Train_Label)[1]                                     #输出层神经元个数
        self.input_cells = np.zeros(self.input_n)                                    #输入层神经元
        self.hidden_cells = np.zeros(self.hidden_n)                                  #隐含层神经元
        self.hidden_cells_input = np.zeros(self.hidden_n)                            #隐含层的输入(不含阈值后进行sigmoid)
        self.output_cells = np.zeros(self.output_n)                                  #输出层神经元
        self.output_cells_input = np.zeros(self.hidden_n)                            #输出层的输入(不含阈值后进行sigmoid)
        self.input_weights = np.random.randn(self.input_n,self.hidden_n)             # 输入层与隐含层之间的权重
        self.hidden_weights = np.random.randn(self.hidden_n,self.output_n)           # 隐含层与输出层之间的权重
        self.hidden_threshold = np.random.randn(1, self.hidden_n)                    # 隐含层的阈值
        self.output_threshold = np.random.randn(1, self.output_n)                    # 输出层的阈值
        self.input_weights_copy = deepcopy(self.input_weights)                       #输入层与隐含层之间的权重备份
        self.hidden_weights_copy = deepcopy(self.hidden_weights)                     #隐含层与输出层之间的权重备份
        self.hidden_threshold_copy = deepcopy(self.hidden_threshold)                 #隐含层的阈值备份
        self.output_threshold_copy = deepcopy(self.output_threshold)                 #输出层的阈值备份

    def Print(self):
        print("训练数据集为:")
        print(self.Train_Data)
        print("训练数据集标记为:")
        print(self.Train_Label)
        print("测试数据集为:")
        print("输入层神经元个数:")
        print(self.input_n)
        print("隐含层神经元个数:")
        print(self.hidden_n)
        print("输出层神经元个数:")
        print(self.output_n)
        print("输入层与隐含层之间的权重的形状:")
        print(np.shape(self.input_weights))
        print(self.input_weights)
        print("隐含层与输出层之间的权重的形状:")
        print(np.shape(self.hidden_weights))
        print(self.hidden_weights)

    def predict(self,input):
        """
        这是BP神经网络向前学习传递的函数
        :param input: 输入神经元的数据
        :return: 更新相应的参数
        """
        #输入层输入数据
        self.input_cells = deepcopy(input)
        #隐含层输出
        self.hidden_cells_input = self.input_cells.dot(self.input_weights)
        self.hidden_cells = self.hidden_cells_input+self.hidden_threshold
        self.hidden_cells = Sigmoid(self.hidden_cells)
        #print("隐含层输出为:\n",self.hidden_cells)
        #输出层输出
        self.output_cells_input = self.hidden_cells.dot(self.hidden_weights)
        self.output_cells = self.output_cells_input+self.output_threshold
        self.output_cells = Sigmoid(self.output_cells)
        #print("输出层输出为:\n", self.output_cells)
        return self.output_cells

    def back_propagate(self,ideal_output,learn_rate):
        """
        这是向后误差传递函数,进行参数调整
        :param ideal_output: 理想输出
        :param learn_rate: 学习率
        """
        # 隐含层与输出层之间的权重的更新
        error = ideal_output - self.output_cells
        derivative = Sigmoid_Derivative(self.output_cells)
        g = derivative*error
        self.hidden_weights = self.hidden_weights + self.hidden_cells.T.dot(g)*learn_rate
        #输出层的阈值更新
        self.output_threshold = self.output_threshold - g*learn_rate
        #输入层与隐含层之 间的权重更新
        e = g.dot(self.hidden_weights.T)*Sigmoid_Derivative(self.hidden_cells)
        self.input_weights = self.input_weights + learn_rate*(self.input_cells.T.dot(e))
        #隐含层的阈值更新
        self.hidden_threshold = self.hidden_threshold - e*learn_rate

    def reset(self):
        """
        这是BPNN的重置函数,是在改变一次迭代过程后回复相关参数的初始值
        """
        self.input_weights = deepcopy(self.input_weights_copy)  # 输入层与隐含层之间的权重备份
        self.hidden_weights = deepcopy(self.hidden_weights_copy)  # 隐含层与输出层之间的权重备份
        self.hidden_threshold = deepcopy(self.hidden_threshold_copy)  # 隐含层的阈值备份
        self.output_threshold = deepcopy(self.output_threshold_copy)  # 输出层的阈值备份

    def train_batch(self,input,output,learn_rate):
        """
        这是对一次一组数据进行训练的函数
        :param input: 组输入数据
        :param output: 输入数据标记
        :param learn_rate: 学习率 
        """
        input = input.reshape(1, len(input))
        output = output.reshape(1, len(output))
        self.output_cells = self.predict(input)
        self.back_propagate(output,learn_rate)

    def train_dataset(self,inputs,outputs,learn_rate):
        """
        这是对一个数据集进行一次训练的函数
        :param input: 输入数据集
        :param output: 输入数据集对应的标记集 
        :param learn_rate: 学习率
        """
        for j in range(len(inputs)):
            self.train_batch(inputs[j],outputs[j],learn_rate)

    def train(self,limitation,learn_rate):
        """
        这是BP神经网络的训练函数
        :param limitaion: 迭代次数
        :param learn_rate: 学习率
        """
        for j in range(limitation):
            self.train_dataset(self.Train_Data,self.Train_Label,learn_rate)

    def test(self,Test_Data):
        """
        这是BP神经网络测试函数
        :param Test_Data: 测试数据
        """
        predict_labels = []
        for i in range(len(Test_Data)):
            input = Test_Data[i]
            predict_output = self.predict(input)
            #print("预测输出为:\n",predict_output)
            index = np.argmax(predict_output)
            #print(index)
            tmp = [0,0,0,0]
            #print("实际输出为:\n",outputs[i])
            tmp[index] = 1
            predict_labels.append(tmp)
        predict_labels = np.array(predict_labels)
        return predict_labels

def Load_Data(path):
    """
    这是导入数据的函数
    :param path: 数据文件的路径
    :return: 数据集
    """
    data = []
    label = []
    with open(path) as f:
        for line in f.readlines():
            str = line.strip().split("\t")
            tmp = []
            for i in range(1,len(str)):
                tmp.append(float(str[i]))
            data.append(tmp)
            if 1 == int(str[0]):
                label.append([1,0,0,0])
            elif 2 == int(str[0]):
                label.append([0,1,0,0])
            elif 3 == int(str[0]):
                label.append([0,0,1,0])
            else:
                label.append([0,0,0,1])
    data = np.array(data).reshape(len(data),len(data[0]))
    label = np.array(label)
    return data,label

def Sigmoid(x):
    """
    这是S型激活函数计算公式
    :param x: 需要进行计算的数据
    :return: S型激活函数的函数值
    """
    function = 1.0 / (1 + np.exp(-x))
    return function

def Sigmoid_Derivative(x):
    """
    这是S型激活函数的导数计算公式
    :param x: 需要进行计算的数据
    :return: S型激活函数的导数的函数值
    """
    f = Sigmoid(x)
    derivative = f*(1-f)
    return derivative

def run_main():
    """
    这是主函数
    """
    #导入数据
    path = "./data.txt"
    Data,Label = Load_Data(path)

    #数据归一化
    Data = MinMaxScaler().fit_transform(Data)

    #数据集分割成训练数据与测试数据
    Train_Data,Test_Data,Train_Label,Test_Label = train_test_split(Data,Label,test_size=1/4,random_state=10)

    #构建BPNN
    bpnn = BPNN(Train_Data,Train_Label)

    # 解决画图是的中文乱码问题
    mpl.rcParams['font.sans-serif'] = [u'simHei']
    mpl.rcParams['axes.unicode_minus'] = False

    #迭代次数增加,测试神经网络的准确性
    limitions = np.array([25,50,100,200,500,1000,1500,2000,2500,5000,10000,15000,20000])
    bpnn_accuracy = []
    bpnn_accuracy1 = []
    bpnn_accuracy2 = []
    bpnn_accuracy3 = []
    bpnn_accuracy4 = []
    Test_Data1 = Test_Data[np.where((Test_Label == np.array([1, 0, 0, 0])).all(1))]
    Test_Data2 = Test_Data[np.where((Test_Label == np.array([0, 1, 0, 0])).all(1))]
    Test_Data3 = Test_Data[np.where((Test_Label == np.array([0, 0, 1, 0])).all(1))]
    Test_Data4 = Test_Data[np.where((Test_Label == np.array([0, 0, 0, 1])).all(1))]
    Test_Label1 = Test_Label[np.where((Test_Label == np.array([1, 0, 0, 0])).all(1))]
    Test_Label2 = Test_Label[np.where((Test_Label == np.array([0, 1, 0, 0])).all(1))]
    Test_Label3 = Test_Label[np.where((Test_Label == np.array([0, 0, 1, 0])).all(1))]
    Test_Label4 = Test_Label[np.where((Test_Label == np.array([0, 0, 0, 1])).all(1))]
    for limition in limitions:
        bpnn.reset()
        bpnn.train(limition,0.1)
        print("迭代次数为limitation = ",limition)
        predict_outputs = bpnn.test(Test_Data)
        predict_outputs1 = bpnn.test(Test_Data1)
        predict_outputs2 = bpnn.test(Test_Data2)
        predict_outputs3 = bpnn.test(Test_Data3)
        predict_outputs4 = bpnn.test(Test_Data4)
        accuracy = accuracy_score(Test_Label,predict_outputs)
        accuracy1 = accuracy_score(Test_Label1, predict_outputs1)
        accuracy2 = accuracy_score(Test_Label2, predict_outputs2)
        accuracy3 = accuracy_score(Test_Label3, predict_outputs3)
        accuracy4 = accuracy_score(Test_Label4, predict_outputs4)
        bpnn_accuracy.append(accuracy)
        bpnn_accuracy1.append(accuracy1)
        bpnn_accuracy2.append(accuracy2)
        bpnn_accuracy3.append(accuracy3)
        bpnn_accuracy4.append(accuracy4)
        print("bpnn的数据总精度是:",accuracy)
        print("bpnn的第一类数据精度是:", accuracy1)
        print("bpnn的第二类数据精度是:", accuracy2)
        print("bpnn的第三类数据精度是:", accuracy3)
        print("bpnn的第四类数据精度是:", accuracy4)
    print("dfsiksdfcxvkgjsdaxckvhdsa")
    print(bpnn_accuracy)
    print(bpnn_accuracy1)
    print(bpnn_accuracy2)
    print(bpnn_accuracy3)
    print(bpnn_accuracy4)
    plt.plot(limitions,bpnn_accuracy)
    plt.xlabel("迭代次数")
    plt.ylabel("精度")
    plt.title("不同迭代次数下的精度")
    plt.grid(True)
    plt.savefig("不同迭代次数的精度")
    plt.show()
    plt.close()
    plt.plot(limitions, bpnn_accuracy1,label='第一类数据')
    plt.plot(limitions, bpnn_accuracy2,label='第二类数据')
    plt.plot(limitions, bpnn_accuracy3,label='第三类数据')
    plt.plot(limitions, bpnn_accuracy4,label='第四类数据')
    plt.xlabel("迭代次数")
    plt.ylabel("精度")
    plt.title("不同迭代次数各类数据的精度")
    plt.legend("best")
    plt.grid(True)
    plt.savefig("不同迭代次数下各类数据的精度")
    plt.show()
    plt.close()

    # 学习率增加,测试神经网络的准确性
    bpnn_accuracy = []
    bpnn_accuracy1 = []
    bpnn_accuracy2 = []
    bpnn_accuracy3 = []
    bpnn_accuracy4 = []
    learn_rates = np.array([0.001,0.005,0.01,0.05,0.1,0.2,0.3,0.5,0.7])
    for learn_rate in learn_rates:
        bpnn.reset()
        bpnn.train(5000,learn_rate)
        print("学习率为learn_rate = ", learn_rate)
        predict_outputs = bpnn.test(Test_Data)
        predict_outputs1 = bpnn.test(Test_Data1)
        predict_outputs2 = bpnn.test(Test_Data2)
        predict_outputs3 = bpnn.test(Test_Data3)
        predict_outputs4 = bpnn.test(Test_Data4)
        accuracy = accuracy_score(Test_Label,predict_outputs)
        accuracy1 = accuracy_score(Test_Label1, predict_outputs1)
        accuracy2 = accuracy_score(Test_Label2, predict_outputs2)
        accuracy3 = accuracy_score(Test_Label3, predict_outputs3)
        accuracy4 = accuracy_score(Test_Label4, predict_outputs4)
        bpnn_accuracy.append(accuracy)
        bpnn_accuracy1.append(accuracy1)
        bpnn_accuracy2.append(accuracy2)
        bpnn_accuracy3.append(accuracy3)
        bpnn_accuracy4.append(accuracy4)
        print("bpnn的数据总精度是:",accuracy)
        print("bpnn的第一类数据精度是:", accuracy1)
        print("bpnn的第二类数据精度是:", accuracy2)
        print("bpnn的第三类数据精度是:", accuracy3)
        print("bpnn的第四类数据精度是:", accuracy4)
    print("rdsxdsfcx")
    print(bpnn_accuracy)
    print(bpnn_accuracy1)
    print(bpnn_accuracy2)
    print(bpnn_accuracy3)
    print(bpnn_accuracy4)
    plt.plot(learn_rates,bpnn_accuracy)
    plt.xlabel("学习率")
    plt.ylabel("精度")
    plt.title("不同学习率下的精度")
    plt.grid(True)
    plt.savefig("limitation=5000"+"不同学习率下的精度")
    plt.show()
    plt.close()

    plt.plot(learn_rates, bpnn_accuracy1, label='第一类数据')
    plt.plot(learn_rates, bpnn_accuracy2, label='第二类数据')
    plt.plot(learn_rates, bpnn_accuracy3, label='第三类数据')
    plt.plot(learn_rates, bpnn_accuracy4, label='第四类数据')
    plt.xlabel("学习率")
    plt.ylabel("精度")
    plt.title("不同学习率下各类数据的精度")
    plt.legend("best")
    plt.grid(True)
    plt.savefig("不同学习率下各类数据的精度")
    plt.show()
    plt.close()

if __name__ == '__main__':
    run_main()

下面是不同迭代次数下总体分类误差:
这里写图片描述


下面是不同迭代次数下4类语音数据的分类误差:
图中的beset分别代表第一类数据,第二类数据,第三类数据,第四类数据。不知道为什么明明做好了标记但是图例会成这样
这里写图片描述


下面是迭代次数为5000是时不同学习率下总体分类误差:
这里写图片描述


下面是迭代次数为5000是时不同学习率下4类语音数据的分类误差:
图中的beset分别代表第一类数据,第二类数据,第三类数据,第四类数据。不知道为什么明明做好了标记但是图例会成这样
这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。若需转载,请注明http://blog.csdn.net/qq_30091945 举报

相关文章推荐

庆祝61

牛家庄幼儿园为庆祝61儿童节举办庆祝活动,庆祝活动中有一个节目是小朋友们围成一个圆圈跳舞。牛老师挑选出n个小朋友参与跳舞节目,已知每个小朋友的身高h_i。为了让舞蹈看起来和谐,牛老师需要让跳舞的圆圈队...

书籍切割之书脊边界直线检测算法小结(bookSpines Segmentation)

去年开始一直在做一个关于整理藏书的APP,有关于这方面的app目前国内的有一个‘晒书房’,但是没有用到图像处理的相关知识,只有一个扫ISBN码的入口,或者手动录入ISBN;国外有一个‘Shelfie’...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

致广大的程序媛

实习之前,我自认为还是个正常的女孩子,虽然算不上温柔乖巧吧,但在陌生人看起来至少也像个文静的淑女,然而实习之后呢,我的人生从此转型,这极度成功的转型也让我事后惊呼,如此这般,我是要上天么、、    ...

cannot restore segment prot after reloc: Permission denied

inux上安装有些东西时会出现 Permission denied 的情况:以下就是解决它的办法之一 编辑/etc/selinux/config,找到这段: # This file con...

基于DL的计算机视觉(9)--神经网络之动手实践

1.引言 前面8小节,算从神经网络的结构、简单原理、数据准备与处理、神经元选择、损失函数选择等方面把神经网络过了一遍。这个部分我们打算把知识点串一串,动手实现一个简单的2维平面神经网络分类器,去...

微微一笑

已经很久没写博客了,最近事情比较多,工作上的,生活上的,个人的,各种乱七八糟的事情,各种烦心的事情,此刻坐在电脑前,发着呆之余,真的好想静静的写一篇博客,一个人,安安静静的,不为其他,只为自己。 没...

模式识别(Pattern Recognition)学习笔记(三十三)-- Boosting方法之AdaBoost

Boosting最早被用在电力电子技术学科中的升压(Boost)变换器中,原本是想通过升压来提高功率,现在将这一提高功率的思想引入到模式识别方法中,它的含义就变成通过融合多个分类器,从而大大提高分类器...

论算法人的语言表达能力

从踏入技术的世界开始到现在,一路走来,碰到了很多技术人,有安卓开发,有ios开发,有后台,也有测试,当然还有我的同行—算法研发,在跟他们的共处过程中,我越来越发现一个突出的问题,那就是相对于非技术人而...

PHP中fgetcsv中文乱码的问题

1、今日一项目需要通过上传CSV文件是想批量导入,于是用到了fgetcsv() 函数,代码在本地测试一点都没问题,但传到服务器(Linux)上则会出现汉字乱码问题,花了好久时间,在网上终于找到了解决办...

组队竞赛

牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。 例如:...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)