[置顶] 利用BP神经网络对语音数据进行分类
2017-05-21 11:19
471 查看
最近给学院老师的一篇论文帮忙改进BP神经网络,由于最后要发表论文,神经网络必须自己手写,搞了几个晚上,总算把基础的BP神经网络写出来,接下来再把老师的改进算法实现就ok了。(当然那代码不能公开了)我这里用的是《MATLAB神经网络43个案例分析》这本书中的语音数据集。(PS:神经网络的学习笔记没时间整理,马上蓝桥杯国赛,比赛结束回学校又是课设,这学期为了机器学习专业课也就是上课听听,还要火线复习把不喜欢的嵌入式专业课给应付过去,估计只有暑假再整理写博客发表了!!!!!)
Python代码:
下面是学习率为0.1时不同迭代次数下总体分类误差:
下面是学习率为0.1时不同迭代次数下4类语音数据的分类误差:
下面是迭代次数为5000是时不同学习率下总体分类误差:
下面是迭代次数为5000是时不同学习率下4类语音数据的分类误差:
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 #迭代次数增加,测试神经网络的准确性 limitations = np.ones(100000) print(limitations) Limitations = np.cumsum(limitations) print(Limitations) 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 i in range(len(limitations)): limitation = int(limitations[i]) bpnn.train(limitation,0.1) print("迭代次数为limitation = ",int(Limitations[i])) 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) plt.plot(Limitations,bpnn_accuracy) plt.xlabel("迭代次数") plt.ylabel("精度") plt.title("不同迭代次数下的精度") plt.grid(True) plt.savefig("learn_rate=0.1不同迭代次数的精度.jpg") #plt.show() #plt.close() plt.subplot(221) plt.plot(Limitations, bpnn_accuracy1) plt.ylabel("精度") plt.title("第一类数据精度") plt.grid(True) plt.subplot(222) plt.plot(Limitations, bpnn_accuracy2) plt.title("第二类数据精度") plt.grid(True) plt.subplot(223) plt.plot(Limitations, bpnn_accuracy3) plt.ylabel("精度") plt.xlabel("迭代次数") plt.title("第三类数据精度") plt.grid(True) plt.subplot(224) plt.plot(Limitations, bpnn_accuracy4) plt.xlabel("迭代次数") plt.title("第四类数据精度") plt.grid(True) plt.subplots_adjust(hspace=0.3) plt.savefig("learn_rate=0.1不同迭代次数的各类数据精度.jpg") # 学习率增加,测试神经网络的准确性 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) plt.plot(learn_rates,bpnn_accuracy) plt.xlabel("学习率") plt.ylabel("精度") plt.title("不同学习率下的精度") plt.grid(True) plt.savefig("limitation=15000"+"不同学习率下的精度.jpg") #plt.show() plt.close() plt.subplot(221) plt.plot(learn_rates, bpnn_accuracy1) plt.ylabel("精度") plt.title("第一类数据精度") plt.grid(True) plt.subplot(222) plt.plot(learn_rates, bpnn_accuracy2) plt.title("第二类数据精度") plt.grid(True) plt.subplot(223) plt.plot(learn_rates, bpnn_accuracy3) plt.xlabel("学习率") plt.ylabel("精度") plt.title("第三类数据精度") plt.grid(True) plt.subplot(224) plt.plot(learn_rates, bpnn_accuracy4) plt.xlabel("学习率") plt.title("第四类数据精度") plt.grid(True) plt.subplots_adjust(hspace=0.3) plt.savefig("limitation=5000" + "不同学习率下的各类数据精度.jpg") if __name__ == '__main__': run_main()
下面是学习率为0.1时不同迭代次数下总体分类误差:
下面是学习率为0.1时不同迭代次数下4类语音数据的分类误差:
下面是迭代次数为5000是时不同学习率下总体分类误差:
下面是迭代次数为5000是时不同学习率下4类语音数据的分类误差:
相关文章推荐
- 利用DecisionTree对titanic数据进行分类
- 利用DM工具Weka进行数据挖掘(分类)的完整过程
- BP神经网络的数据分类—语音特征信号识别
- 利用SVC(Support Vector Classifier)对digits数据进行分类
- 案例2:数据挖掘---BP神经网络的数据分类—语音特征信号分类
- 利用python实现对分类变量与数值变量混合的数据进行聚类分析
- 利用神经网络进行音频数据分类
- [置顶] 【Android】利用Fiddler进行抓包详解教程。抓取接口以及数据,可以抓真实安卓手机或者模拟器。
- Caffe python利用classify.py实现对单通道(灰度图)的数据进行分类
- [置顶] 利用Python进行数据分析第二版之group basic
- 跪求!利用深度信念网络工具箱对凯斯西出大学轴承数据进行分类错误率无法降低怎么办
- [置顶] 基于R语言利用QQ群进行数据挖掘案例整理
- 在ENVI进行的土地利用分类数据,需要做景观指数分析,如何将其转换成GRID格式呀
- 利用XSL对XML数据进行加密和大小写转换
- 使用sql语句进行数据分类汇总
- 初谈ADO.NET中利用DataAdapter进行数据操作
- 利用VB进行SQL2000的数据备份和恢复
- 利用VB进行SQL2000的数据备份和恢复
- 利用数组进行数据查找
- 利用存储过程进行批量数据添加