第1章 BP神经网络的数据分类——语音特征信号的分类
2018-04-17 本文已影响165人
dc343001cf91
1.1 案例背景
1.1.1 BP神经网络概述
BP 神经网络是一种多层前馈神经网络,该网络的主要特点是信号前向传递,误差反向传
播。在前向传递中,输入信号从输入层经隐含层逐层处理,直至输出层. 每一层的神经元状态
只影响下一层神经元状态。如果输出层得不到期望输出,则转入反向传播, 根据预测误差调整
网络权值和阔值,从而使BP 神经网络预测输出不断逼近期望输出。BP 神经网络的拓扑结构
如图1 - 1 所示。
图1-1 BP 神经网络拓扑结构图
代码基本完成 还待完善
# 清空环境变量
rm(list = ls())
setwd("C:/Users/Administrator/Desktop/R语言神经网络43个案例分析/chapter1")
# 导入所有语音信号
library(data.table)
data <- fread("data.txt")
# 王小川的matlab代码里有导入4类语音信号我这里已经合并好放在txt文件里了
data <- as.matrix(data)
# 输入输出数据
input <- data[, -1]
output1 <- data[, 1]
# 设定每组输入输出信号(R语言只需要调用nnet包的class.ind)
library(nnet)
output <- class.ind(output1)
# 输入数据归一化
# matalb的归一化函数可以反归一,目前我只有自己写的这个,所以我先做了
mapminmax <- function(x){
x_max <- max(x)
x_min <- min(x)
x <- (x - x_min) / (x_max - x_min)
return(x)
} # 这个函数有bug的,不能针对常量进行标准化
inputn <- t(apply(input, 2, mapminmax))
# 从中随机抽取1500组(75%)数据作为训练数据,500组数据作为预测数据
n <- sample(nrow(data),0.75*nrow(data))
input_train <- t(input[n, ])
output_train <- t(output[n, ])
input_test <- t(input[-n, ])
output_test <- t(output[-n,])
# 1.3.3 BP 神经周络结椅却始化
# 根据语音特征信号特点确定BP 神经网络的结构为24-30-4,随机初始化BP神经网络
# 权值和阔值
# 网络结构
innum <- nrow(input_test)
midnum <- 25 # 隐藏层数量是要自己确定的
outnum <- ncol(output)
# 权值
w1 <- matrix(runif(innum*midnum), nrow = midnum)
b1 <- matrix(runif(midnum), ncol = 1)
w2 <- matrix(runif(outnum*midnum), nrow = midnum)
b2 <- matrix(runif(outnum), ncol = 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
loopNumber <- 1000
E <- NULL
I <- NULL
Iout <- NULL
FI <- NULL
db1 <- NULL
dw1 <- matrix(ncol = midnum, nrow = innum)
# 1.3.4 bp神经网络训练
# 用训练数据训练BP神经网络,在训练过程中根据网络预测误差调整网络的权值和阔值.
for (ii in 1:loopNumber){
xite <- loopNumber/100
E[ii] <- 0
for (i in 1:(0.75*nrow(data))){
# 选择本次训练数据
x <- matrix(inputn[, i], ncol = 1)
# 隐含层输出
for(j in 1:midnum){
I[j] <- t(x) %*% w1[j,] + b1[j]
Iout[j] <- 1 / (1 + exp(-I[j]))
}
I <- matrix(I, nrow = 1)
Iout <- matrix(Iout, nrow = 1)
# 输出层输出
yn = t(Iout %*% w2) + b2
# 权值阀值修正
# 计算误差
e = output_train[, i] - yn
E[ii] = E[ii] + sum(abs(e))
# 计算w2,b2调整量
dw2 <- e %*% Iout
db2 <- t(e)
# 计算w1,b1调整量
for (j in 1:midnum){
S = 1 / (1 + exp(- I[j]))
FI[j] = S * (1 - S)
}
for (k in 1:innum){
for (j in 1:midnum)
{
dw1[k,j] <- FI[j] * x[k] * sum(e * w2[j, ])
db1[j] <- FI[j] * sum(e * w2[j, ])
}
}
db1 <- matrix(db1, nrow = 1)
# 权值阈值更新
w1 <- w1_1 + xite * t(dw1)
b1 <- b1_1 + xite * t(db1)
w2 <- w2_1 + xite * t(dw2)
b2 <- b2_1 + xite * t(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
}
}
fore <- NULL
for (i in 1:(0.25*nrow(data))){
# 隐含层输出
for (j in 1:midnum){
I[j] <- sum(input_test[, i] %*% t(w1)) + b1[j]
Iout[j] <- 1 / (1 + exp(-I[j]))
}
fore <- cbind(fore, t(Iout %*% w2) + b2)
}
## 结果分析
# 根据网络输出找出数据属于哪类
output_force <- apply(fore, 2, which.max)
# BP网络预测误差
error <- output_force - output1[-n]
table(output_force, output1[-n])
数据集
链接:https://pan.baidu.com/s/1T_74Lkw8W4WqoYfhPCxX_g
密码:cny4
原书作者微博:@王小川_MATLAB
本人微博:@蒋小受的吴小胖