-
-
Notifications
You must be signed in to change notification settings - Fork 8
tensor size errors for bce_with_logits loss / net which outputs 1d tensor #373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for this question! There are in principle two solutions:
library(mlr3torch)
#> Loading required package: mlr3
#> Loading required package: mlr3pipelines
#> Loading required package: torch
# currently requires adding class "nn_loss" because as_torch_loss only has a method for this class
nn_bce_loss2 = nn_module(c("nn_bce_with_logits_loss2", "nn_loss"),
initialize = function(weight = NULL, reduction = "mean", pos_weight = NULL) {
self$loss = nn_bce_with_logits_loss(weight, reduction, pos_weight)
},
forward = function(input, target) {
# EDIT: added the -1 after comment by tdhock
self$loss(input$reshape(-1), target$to(dtype = torch_float()) - 1)
}
)
loss = nn_bce_loss2()
loss(torch_randn(10, 1), torch_randint(0, 1, 10))
#> torch_tensor
#> 0.500878
#> [ CPUFloatType{} ]
task = tsk("sonar")
graph = po("torch_ingress_num") %>>%
nn("linear", out_features = 1) %>>%
po("torch_loss", loss = nn_bce_loss2) %>>%
po("torch_optimizer") %>>%
po("torch_model_classif",
epochs = 1, batch_size = 32
)
glrn = as_learner(graph)
glrn$train(task)
# this does not work, because the targets are still loaded as ints but bce_loss expects floats
graph2 = po("torch_ingress_num") %>>%
nn("linear", out_features = 1) %>>%
nn("flatten", start_dim = 1) %>>%
po("torch_loss", loss = nn_bce_loss) %>>%
po("torch_optimizer") %>>%
po("torch_model_classif",
epochs = 1, batch_size = 32
)
glrn2 = as_learner(graph2)
glrn2$train(task)
#> A lit of torch error backtrace
#> This happened PipeOp torch_model_classif's $train() Created on 2025-04-02 with reprex v2.1.1 |
I confirm this works for me, thanks for the advice! |
Keeping this open as this is at least a TODO for documentation |
by the way, for others who are trying to do this, the code above runs without error, but does not learn, because the bce_with_logits_loss needs values in 0,1, but R labels are 1,2. nn_bce_loss3 = nn_module(c("nn_bce_with_logits_loss3", "nn_loss"),
initialize = function(weight = NULL, reduction = "mean", pos_weight = NULL) {
self$loss = nn_bce_with_logits_loss(weight, reduction, pos_weight)
},
forward = function(input, target) {
self$loss(input$reshape(-1), target$to(dtype = torch_float())-1)
}
) |
Thanks! I updated the code snippet |
This is now solved as torch classification learners are expected to output 1 column for binary classification problems |
Hi! @sebffischer
I am trying to implement a neural network with a custom loss function for binary classification.
It works just like the standard
torch::nn_bce_with_logits_loss
-- https://torch.mlverse.org/docs/reference/nn_bce_with_logits_losscriterion(output, target)
where both output and target are 1d tensors.Here is a MRE.
I tried the code above, and I observe a tensor size error,
in the output above we see that
loss=torch::nn_cross_entropy_loss
works without error, butloss=torch::nn_bce_with_logits_loss
gives a tensor size error.I guess this is because MLP learner is always outputing a matrix with 2 columns? (even for the binary case where it could output 1 column or just a 1d tensor instead)
Is it possible in mlr3torch to have a neural network that outputs a 1d tensor instead?
I tried using graph learner code below, with nn_linear layer that has
out_features=1
.I observe two different errors for the two different loss functions:
So I guess this means that it is not currently supported?
for positive control, I tried changing
out_features=2
in the code above, and in that case I observe the same result as MLP learner (cross entropy loss works, error for bce_with_logits_loss).The text was updated successfully, but these errors were encountered: