Lasso Regression com o {torch}

Tava aprendendo {torch} e resolvi tentar adaptar a loss de um modelo simples pra ficar igual ao critério do LASSO. Ao comparar com a saída do {glmnet} eu encontrei divergência entre as estimativas: 9.62 versus 9.12.

Parece que está funcionando, mas achei que o resultado deveria dar exatamente igual. Qual seria o motivo do código abaixo estar retornando estimativas com essa diferença?

library(torch)

torch_manual_seed(1)
N <- 100
x <- torch_randn(N, 1)
y <- 0 + 10 * x + torch_randn(N,1)

lin <- nn_linear(1,1)
criterion <- nn_mse_loss()
opt <- torch::optim_adam(lin$parameters, lr = 0.2)
lambda <- 1
losses <- c()

for(i in 1:200) {
    opt$zero_grad()
    pred <- lin(x)
    loss <- criterion(y, pred) + lambda*torch_norm(lin$parameters$weight, p = 1)
    losses <- c(losses, as.numeric(loss))
    loss$backward()
    opt$step()
}

# comparação entre glmnet e torch
as.numeric(lin$parameters$bias)
#> [1] -0.0508424
as.numeric(lin$parameters$weight)
#> [1] 9.626606
coef(glmnet::glmnet(cbind(as.matrix(x), 1), as.matrix(y), nlambda = 1, lambda = lambda, alpha = 1))
#> 3 x 1 sparse Matrix of class "dgCMatrix"
#>                     s0
#> (Intercept) -0.1358597
#> V1           9.1273235
#> V2           .

# plot das losses
plot(1:length(losses), losses)

Created on 2020-12-01 by the reprex package (v0.3.0)

1 Curtida

Acho que a diferença está apenas no método de otimização! O glmnet usa isso aqui:

The glmnet algorithms use cyclical coordinate descent, which successively optimizes the objective function over each parameter with others fixed, and cycles repeatedly until convergence.

1 Curtida