∑je( yje- y^je)2 est en effet convexe dans . Mais si il peut ne pas être convexe dans , ce qui est le cas avec la plupart des modèles non linéaires, et nous nous soucions en fait de la convexité dans parce que c'est ce que nous optimisons le fonction de coût terminée. y i=f(xi;θ)θθy^jey^je= f( xje; θ )θθ
Par exemple, considérons un réseau avec 1 couche cachée de unités et une couche de sortie linéaire: notre fonction de coût est
où et (et j'omets les termes de biais pour plus de simplicité). Ce n'est pas nécessairement convexe lorsqu'il est considéré comme une fonction de (selon : si une fonction d'activation linéaire est utilisée, alors elle peut toujours être convexe). Et plus notre réseau s'approfondit, moins les choses sont convexes.g ( α , W ) = ∑ i ( y i - α i σ ( W x i ) ) 2 x i ∈ R p W ∈ R N × p ( α , W ) σN
g(α,W)=∑i(yi−αiσ(Wxi))2
xi∈RpW∈RN×p(α,W)σ
Définissez maintenant une fonction par où est avec réglé sur et réglé sur . Cela nous permet de visualiser la fonction de coût car ces deux poids varient. h ( u , v ) = g ( α , W ( u , v ) ) W ( u , v ) W W 11 u W 12 vh:R×R→Rh(u,v)=g(α,W(u,v))W(u,v)WW11uW12v
La figure ci-dessous montre cela pour la fonction d'activation sigmoïde avec , et (donc une architecture extrêmement simple). Toutes les données ( et ) sont iid , de même que les pondérations qui ne varient pas dans la fonction de tracé. Vous pouvez voir le manque de convexité ici.p = 3 N = 1 x y N ( 0 , 1 )n=50p=3N=1xyN(0,1)
Voici le code R que j'ai utilisé pour faire cette figure (bien que certains paramètres soient à des valeurs légèrement différentes maintenant que lorsque je l'ai fait, ils ne seront donc pas identiques):
costfunc <- function(u, v, W, a, x, y, afunc) {
W[1,1] <- u; W[1,2] <- v
preds <- t(a) %*% afunc(W %*% t(x))
sum((y - preds)^2)
}
set.seed(1)
n <- 75 # number of observations
p <- 3 # number of predictors
N <- 1 # number of hidden units
x <- matrix(rnorm(n * p), n, p)
y <- rnorm(n) # all noise
a <- matrix(rnorm(N), N)
W <- matrix(rnorm(N * p), N, p)
afunc <- function(z) 1 / (1 + exp(-z)) # sigmoid
l = 400 # dim of matrix of cost evaluations
wvals <- seq(-50, 50, length = l) # where we evaluate costfunc
fmtx <- matrix(0, l, l)
for(i in 1:l) {
for(j in 1:l) {
fmtx[i,j] = costfunc(wvals[i], wvals[j], W, a, x, y, afunc)
}
}
filled.contour(wvals, wvals, fmtx,plot.axes = { contour(wvals, wvals, fmtx, nlevels = 25,
drawlabels = F, axes = FALSE,
frame.plot = FALSE, add = TRUE); axis(1); axis(2) },
main = 'NN loss surface', xlab = expression(paste('W'[11])), ylab = expression(paste('W'[12])))