Skip to content
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

progbar issue #1479

Closed
jobstdavid opened this issue Nov 30, 2024 · 2 comments
Closed

progbar issue #1479

jobstdavid opened this issue Nov 30, 2024 · 2 comments

Comments

@jobstdavid
Copy link

jobstdavid commented Nov 30, 2024

Hello,

running the following example code adapted with a (trival) custom loss function

library(keras)
library(keras3)
library(tensorflow)

CustomModel <- new_model_class(
  "CustomModel",
  train_step = function(data) {
    c(x, y = NULL, sample_weight = NULL) %<-% data
    
    with(tf$GradientTape() %as% tape, {
      y_pred <- self(x, training = TRUE)
      loss <- self$compute_loss(y = y, y_pred = y_pred,
                                sample_weight = sample_weight)
    })
    
    # Compute gradients
    trainable_vars <- self$trainable_variables
    gradients <- tape$gradient(loss, trainable_vars)
    
    # Update weights
    self$optimizer$apply(gradients, trainable_vars)
    
    # Update metrics (includes the metric that tracks the loss)
    for (metric in self$metrics) {
      if (metric$name == "loss")
        metric$update_state(loss)
      else
        metric$update_state(y, y_pred)
    }
    
    # Return a dict mapping metric names to current value
    metrics <- lapply(self$metrics, function(m) m$result())
    metrics <- setNames(metrics, sapply(self$metrics, function(m) m$name))
    metrics
  }
)


# Construct and compile an instance of CustomModel
inputs <- keras_input(shape = 32)
outputs <- layer_dense(inputs, 1)
model <- CustomModel(inputs, outputs)
custom_loss <- function(y_true, y_pred) {
  
  k <- keras::backend()
  
  # get location parameter
  location <- y_pred
  
  mean((y_true - location)^2)
  
}
model |> compile(optimizer = "adam", loss = custom_loss, metrics = "mae")


# Just use `fit` as usual
x <- random_normal(c(1000, 32))
y <- random_normal(c(1000, 1))
model |> fit(x, y, epochs = 3, verbose = 1)

yields to the following error message:

Error in py_get_attr(x, name, FALSE) :
AttributeError: module 'kerastools' has no attribute 'progbar'
Run `reticulate::py_last_error()` for details.
10.
stop(structure(list(message = "AttributeError: module 'kerastools' has no attribute 'progbar'\n\033[90mRun \033]8;;rstudio:run:reticulate::py_last_error()\a`reticulate::py_last_error()`\033]8;;\a for details.\033[39m",
call = py_get_attr(x, name, FALSE)), class = c("python.builtin.AttributeError",
"python.builtin.Exception", "python.builtin.BaseException", "python.builtin.object",
"error", "condition"), py_object = <environment>))

As far as I figured out, this error only happens, if a custom loss function is defined. In addition, following the advice from here , i.e. running

try(k_constant(1), silent = TRUE)
try(k_constant(1), silent = TRUE)

after the error message, solves the problem for the next try. However, thats no very elegant solution. Does anyone know how to fix this issue?

sessionInfo()
R version 4.3.3 (2024-02-29)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Sonoma 14.6.1

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Berlin
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] crch_1.1-2        tensorflow_2.16.0 keras3_1.2.0.9000 keras_2.15.0     

loaded via a namespace (and not attached):
 [1] sandwich_3.1-0         utf8_1.2.4             generics_0.1.3         lattice_0.22-5         magrittr_2.0.3         grid_4.3.3             eppverification_0.4.1 
 [8] scoringRules_1.1.1     fastmap_1.1.1          mvtnorm_1.2-4          jsonlite_1.8.8         Matrix_1.6-5           whisker_0.4.1          Formula_1.2-5         
[15] tfruns_1.5.3           mgcv_1.9-1             fansi_1.0.6            scales_1.3.0           permute_0.9-7          cli_3.6.2              rlang_1.1.3           
[22] splines_4.3.3          munsell_0.5.1          base64enc_0.1-3        vegan_2.6-4            tools_4.3.3            parallel_4.3.3         dplyr_1.1.4           
[29] colorspace_2.1-0       ggplot2_3.5.0          zeallot_0.1.0          forcats_1.0.0          Rfast_2.1.0            RcppZiggurat_0.1.6     reticulate_1.40.0.9000
[36] vctrs_0.6.5            R6_2.5.1               png_0.1-8              zoo_1.8-12             lifecycle_1.0.4        MASS_7.3-60.0.1        cluster_2.1.6         
[43] pcaPP_2.0-4            pkgconfig_2.0.3        RcppParallel_5.1.8     pillar_1.9.0           gtable_0.3.4           glue_1.7.0             Rcpp_1.0.13           
[50] xfun_0.43              tibble_3.2.1           tidyselect_1.2.1       rstudioapi_0.16.0      knitr_1.45             patchwork_1.2.0        nlme_3.1-164          
[57] compiler_4.3.3   
@t-kalinowski
Copy link
Member

Thanks for opening. A few notes:

  • No need to call library(keras) and library(keras3), just use keras3.
  • A custom loss function should return a rank-1 tensor that has the same batchsize as what came in.

After removing the library(keras) call and updating the custom loss function, the code snippet you provided works for me locally.

custom_loss <- function(y_true, y_pred) {
  op_mean(op_square(y_true - y_pred), axis = -1)
}

@jobstdavid
Copy link
Author

Thanks! That solved my issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants