神经网络的softmax输出层未能收敛

我在学习斯坦福的深度学习教程时,遇到一个练习中的问题,即带有softmax输出层的neural网络。以下是我在R语言中的实现:

train <- function(training.set, labels, costFunc, activationFunc, outputActivationFunc, activationDerivative, hidden.unit.count = 7, learningRate = 0.3, decayRate=0.02, momentumRate=0.02, samples.count, batch.size, verbose=F, debug=F){  #initialize weights and biases  w1 <- matrix( rnorm(hidden.unit.count * input.unit.count, sd=0.5), nrow=hidden.unit.count, ncol=input.unit.count)  b1 <- matrix(-1, nrow=hidden.unit.count, ncol=1)  w2 <- matrix(rnorm(output.unit.count * hidden.unit.count, sd=0.5), nrow=output.unit.count, ncol=hidden.unit.count)  b2 <- matrix(-1, nrow=output.unit.count, ncol=1)  cost.list<- matrix(rep(seq(1:floor(samples.count / batch.size)), each=2), byrow=T, ncol=2)  cost.list[, 2] <- 0  i <- 1  while(i < samples.count){    z2 <- w1 %*% training.set[, i: (i + batch.size - 1)] + matrix(rep(b1, each=batch.size), ncol=batch.size,byrow=T)    a2 <- activationFunc(z2)    z3 <- w2 %*% a2 + matrix(rep(b2, each=batch.size), ncol=batch.size,byrow=T)    h  <- outputActivationFunc(z3)    #calculate error    output.error <- (h - labels[, i: (i + batch.size - 1)])     hidden.error <- (t(w2) %*% output.error) * sigmoidPrime(z2)    # calculate gradients for both layers    gradW2 <- hidden.error %*% t(training.set[ ,i: (i + batch.size - 1)]) - momentumRate * gradW2.prev - decayRate * w1    gradw2 <- output.error %*% t(a2) - momentumRate * gradw2.prev - decayRate * w2    gradW2.prev <- gradW2    gradw2.prev <- gradw2    #update weights and biases    w1 <- w1 - learningRate * gradW2 / batch.size    w2 <- w2 - learningRate * gradW3 / batch.size    b1 <- b1 - learningRate * rowSums(gradW2) / batch.size    b2 <- b2 - learningRate * rowSums(gradW3) / batch.size    i <- i + batch.size  }  return (list(w1, w2, b1, b2, cost.list))}

这是我在输出层使用的softmax函数,以及我与softmax一起使用的成本函数:

softmax <- function(a){  a <- a - apply(a, 1, function(row){       return (max(row))  })  a <- exp(a)  return (sweep(a, 2, colSums(a), FUN='/'))}softmaxCost <- function(w, b, x, y, decayRate, batch.size){  a <- w %*% x + matrix(rep(b, each=dim(x)[2]), byrow = T, ncol=dim(x)[2])  h <- softmax(a)  cost <- -1/batch.size * (sum(y * log(h))) + decayRate/2 * sum((w * w))  return (cost)}

我已经将程序计算的梯度与数值梯度进行了对比,发现它们是不同的。然而,我无法找到梯度计算错误的来源。

此外,我在MNIST数据集上使用sigmoid激活函数在输出层成功地使用了这个网络,而使用softmax层则完全不起作用(准确率为11%)。这让我认为问题出在我的softmax实现上。


回答:

如果我理解正确的话,我认为问题出在你的代码中的max部分(ReLu)。在softmax的DNN中,我们选择max(0, value)。具体来说,在这种情况下,我们对矩阵a的每个元素执行此操作。

所以代码看起来会像这样:

# XW + bhidden.layer <- sweep(X %*% W ,1, b, '+', check.margin = F)# max for each element in maxtirhidden.layer <- pmax(hidden.layer, 0)

顺便提一下,你可以使用sweep来将b添加到矩阵中,而不是重复T行,这会浪费大量内存。这里展示了三种方法,详见这里

注意下面的代码,y应该是0/1,正确标签为1,其他为0,这样你可以通过sum(y * log(h))获得正确的损失值。

cost <- -1/batch.size * (sum(y * log(h))) + decayRate/2 * sum((w * w))

编辑:我写了一篇关于如何用R构建DNN的博客,详见这里

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注