作者:于英富
本文将借助R语言为工具,进一步了解神经网络的原理与运用.
神经网络工作的主要原理
第一步 . 创建网络结构
第二步. 初始化参数
第三步. 前向传播
第四步. 计算误差
第五步. 逆向反馈 / 梯度下降
重复 3-5步
第一步.
下面将构造一个2个输入节点,2个隐藏层,1一个输出节点的神经网络
先定义神经元的激活函数
sigmoid = function(x) {
1 / (1 + exp(-x))
}
XOR
X <- data.frame(A = c(0,0,1,1), B = c(0,1,1,0))
Y <- data.frame(Y = c(0,1,0,1))
b <- data.frame(b = c(1,1))
X
Y
b
神经网络结构如下
wts.in <- c(1,1,1,1,1,1,1,1,1)
struct <- c(2,2,1) #two inputs, two hidden, one output
plot.nnet(wts.in,struct=struct)
weights <- plot.nnet(wts.in,struct=struct, wts.only=T)
weights
第二步.
随机函数初始化参数
set.seed(342)
wts.in <- round(runif(9, 0, 1), digits = 2)
plot.nnet(wts.in,struct=struct)
weights <- plot.nnet(wts.in,struct=struct, wts.only=T)
weights
第三步. 前向传播: 隐藏层
#利用权重和输入节点 计算隐藏节点值
第一个隐藏节点值
H1_a <- weights$`hidden 1 1` * I[1,]
#求和
H1_b <- sum(H1_a)
# 激活参数输出
H1_c <- sigmoid(H1_b)
#第二个隐藏节点值
H2_a <- weights$`hidden 1 2` * I[1,]
#求和
H2_b <- sum(H2_a)
#激活函数输出
H2_c <- sigmoid(H2_b)
隐藏层的值
H <- data.frame(b = 1, H1 = H1_c, H2 = H2_c)
H
第三步. 前向传播之: 输出层
#利用权重和隐藏层的值 计算输出层的值
O1_a <- weights$`out 1` * H
#求和
O1_b <- sum(O1_a)
#运用激活函数输出
O1_c <- sigmoid(O1_b)
print(O1_c)
第四步. 计算残差
MSE <- 0.5*(O1_c - Y[1,])^2
MSE
第五步. 逆向反馈: 输出层 反馈到隐藏层
# 更新权重
weights$`out 1`
# 提升模型
wOb <- weights$`out 1`[1]
wOH1 <- weights$`out 1`[2]
wOH2 <- weights$`out 1`[3]
计算残差对三个权重的偏导
.
梯度下降
根据 能够计算出学习率 . 下面令
((O1_c - Y[1,]) + O1_c*(1-O1_c) + H[1,1])*0.3
$wOB^+ = 0.43 - 0.5888215623 = -0.1588215623$
重复反馈 ,梯度下降学习 wOH1 和 wOH2.
借用R语言包 进行神经网络模型训练
利用iris数据集 进行训练模型
head(iris)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
输入节点为:Sepal.Length Sepal.Width Petal.Length Petal.Width 四个节点
隐藏层:这里设置为3
输出层:为3 (setosa versicolor virginica 三种花的品类)
训练模型
X=data.frame(iris[,-5])
Y=data.frame(iris[,5])
b=data.frame(b=c(1,1,1,1))
test=sample(length(Y[,1]), length(Y[,1])*0.2, replace = FALSE, prob =NULL)
nnetGrid <- expand.grid(size = seq(from = 3, to = 3, by = 1),
decay = seq(from = 0.1, to = 0.3, by = 0.1))
Y=as.factor(as.matrix(make.names(Y[,1])))
nnetFit <- train(x=X[-c(test),],
y=Y[-c(test)],
method = "nnet",
metric = "LogLoss",
maximize = FALSE,
trControl = ctrl,
type = "Classification",
tuneGrid = nnetGrid,
verbose = FALSE)
输出模型的结果:27个权重值
nnetFitwts
[1] 0.20758258 0.37641741 1.17133396 -1.93620236 -0.88095565 2.20289698 1.81073473 2.08188073
[9] -2.90472414 -3.20650526 -0.20834478 -0.32335381 -0.94003857 1.37434281 0.73064675 -0.04939097
[17] 3.20299969 1.01741494 -2.94838942 -1.41771866 -2.94171307 3.86796547 0.82027531 1.46689381
[25] -0.26129214 -4.88532282 2.12818341
模型检验
library(RSNNS)
plot(nnetFit$results$LogLoss,type='l')
par(mar=c(0.1,0.1,1,0.1),mfrow=c(2,2))
par(mar=c(0.1,0.1,1,0.1),mfrow=c(2,2))
irisTargets<- decodeClassLabels(Y[test])
prediction_nn <- predict(nnetFit, newdata = X[test,],type="prob")
for(i in 1:3)
{
k=roc(irisTargets[,i],as.numeric(prediction_nn[[i]]),plot=T,col=i);
title(main=paste("roc",colnames(irisTargets)[i],collapse =" "))
}
#loss
prediction_nn <- predict(nnetFit, newdata = X[test,])
table(prediction_nn, Y[test])
ROC曲线
混淆矩阵
table(prediction_nn, Y[test])
prediction_nn setosa versicolor virginica
setosa 9 0 0
versicolor 0 11 0
virginica 0 1 9
结束
神经网络,是由多个神经元组成的一个具有某种分类 回归的功能的黑箱。