softmax 输出无法收敛的神经网络
Neural Net with softmax output failing to converge
我一直在学习 Stamford 的深度学习教程,但其中一个练习有问题,即具有 softmax 输出层的神经网络。这是我在 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中,我们selectmax(0, value)
。具体来说,在这种情况下,我们对矩阵 a
.
的每个元素执行此操作
因此代码将如下所示:
# XW + b
hidden.layer <- sweep(X %*% W ,1, b, '+', check.margin = F)
# max for each element in maxtir
hidden.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))
编辑 : 我在 here.
中写了一篇关于如何使用 R 构建 DNN 的博客
我一直在学习 Stamford 的深度学习教程,但其中一个练习有问题,即具有 softmax 输出层的神经网络。这是我在 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中,我们selectmax(0, value)
。具体来说,在这种情况下,我们对矩阵 a
.
因此代码将如下所示:
# XW + b
hidden.layer <- sweep(X %*% W ,1, b, '+', check.margin = F)
# max for each element in maxtir
hidden.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))
编辑 : 我在 here.
中写了一篇关于如何使用 R 构建 DNN 的博客