神经网络(R语言)

作者:于英富
本文将借助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
image.png

第二步.

随机函数初始化参数

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 三种花的品类)

image.png

训练模型

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曲线

image.png

混淆矩阵

table(prediction_nn, Y[test])
prediction_nn setosa versicolor virginica
setosa 9 0 0
versicolor 0 11 0
virginica 0 1 9

结束

神经网络,是由多个神经元组成的一个具有某种分类 回归的功能的黑箱。

你可能感兴趣的:(神经网络(R语言))