【问题标题】:Reshaping tensors to train with a Weibull distribution in R Keras在 R Keras 中重塑张量以使用 Weibull 分布进行训练
【发布时间】:2019-10-12 14:34:35
【问题描述】:

我正在尝试调整此处首先使用的 Weibull 分布: https://github.com/daynebatten/keras-wtte-rnn

在这里解决了将其翻译成 R 的类似问题,但这并没有让我找到我的解决方案:https://github.com/rstudio/keras/issues/354

我的情况如下。也就是说,它是生存数据,有故障时间或迄今为止的生存时间,但每个案例只有一行,不符合上述任何一种情况(例如,原始的喷气发动机是著名的喷气发动机)故障数据,并且每个引擎都有多行包含随时间推移的多轮测量数据。)


library(keras)
library(tidyverse)

weibull_activate = function(ab) {
  a = k_exp(ab[, 1])
  b = k_softplus(ab[, 2])

  a = k_reshape(a, c(length(a), 1))
  b = k_reshape(b, c(length(b), 1))

  return(k_concatenate(list(a, b)))
}

weibull_loglik_continuous <- function(y_true, y_pred) {
  y_true = k_reshape(y_true, c(1, 2))
  y_pred = k_reshape(y_pred, c(1, 2))

  y_ = y_true[, 1]
  u_ = y_true[, 2]
  a_ = y_pred[, 1]
  b_ = y_pred[, 2]

  ya = (y_ + 1e-35) / a_
  return(-1 * k_mean(u_ * (k_log(b_) + b_ * k_log(ya)) - k_pow(ya, b_)))
}

set.seed(2019)

(data <- tibble(
  failure_time = runif(6),
  still_going  = sample(c(0, 1), 6, replace = TRUE),
  predictor    = jitter(failure_time)
))
#> # A tibble: 6 x 3
#>   failure_time still_going predictor
#>          <dbl>       <dbl>     <dbl>
#> 1       0.770            1    0.769 
#> 2       0.713            0    0.712 
#> 3       0.303            0    0.304 
#> 4       0.618            1    0.619 
#> 5       0.0505           0    0.0492
#> 6       0.0432           1    0.0438

model <-
  keras_model_sequential() %>%
  layer_dense(units       = 5,
              input_shape = 1) %>%
  layer_dense(2) %>%
  layer_activation(activation = weibull_activate) %>%
  compile(loss      = weibull_loglik_continuous,
          optimizer = "rmsprop")

fit(model,
    data %>% select(predictor) %>% as.matrix(),
    data %>% select(-predictor) %>% as.matrix(),
    batch_size = 3,
    epochs     = 1)
#> Error in py_call_impl(callable, dots$args, dots$keywords): InvalidArgumentError: Input to reshape is a tensor with 6 values, but the requested shape has 2
#>   [[Node: loss/activation_loss/Reshape = Reshape[T=DT_FLOAT, Tshape=DT_INT32, _device="/job:localhost/replica:0/task:0/device:GPU:0"](_arg_activation_target_0_1/_25, loss/activation_loss/Reshape/shape)]]
#>   [[Node: loss/mul/_29 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_386_loss/mul", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]
#> 
#> Detailed traceback: 
#>   File "C:\Users\DHW\AppData\Local\conda\conda\envs\R-TENS~1\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1348, in fit
#>     validation_steps=validation_steps)
#>   File "C:\Users\DHW\AppData\Local\conda\conda\envs\R-TENS~1\lib\site-packages\tensorflow\python\keras\engine\training_arrays.py", line 253, in fit_loop
#>     outs = f(ins_batch)
#>   File "C:\Users\DHW\AppData\Local\conda\conda\envs\R-TENS~1\lib\site-packages\tensorflow\python\keras\backend.py", line 2897, in __call__
#>     fetched = self._callable_fn(*array_vals)
#>   File "C:\Users\DHW\AppData\Local\conda\conda\envs\R-TENS~1\lib\site-packages\tensorflow\python\client\session.py", line 1454, in __call__
#>     self._session._session, self._handle, args, status, None)
#>   File "C:\Users\DHW\AppData\Local\conda\conda\envs\R-TENS~1\lib\site-packages\tensorflow\python\framework\errors_impl.py", line 519, in __exit__
#>     c_api.TF_GetCode(self.status.status))

reprex package (v0.3.0) 于 2019 年 10 月 12 日创建

我认为这意味着损失函数只能有 1 行硬编码(在第二个链接中,有人尝试使其与批量大小和/或每个实体的行数相同,例如发动机)。但是无论我做什么,我都会遇到某种错误,无论是在模型编译还是拟合中。我尝试了一些不同的方法,包括调整批量大小以及是否在训练 y 矩阵中包含 still_going 列,但无论哪种方式,形状似乎都已关闭。一个例外是,如果批量大小为 1,它确实会编译和训练,而且训练甚至似乎是有意义的(即损失是一个实数),但是,当然,我不想做在线学习,我想要一个大批量的稳定模型。所以,基本上,训练 y 的形状和损失函数之间存在一些形状不匹配,显然在长度上,我无法解决。

【问题讨论】:

  • 如果下面的答案不能解决问题,请将每个张量的K_int_shape打印出来并贴出来。
  • y_trueK_int_shape 是:[[1]] NULL 和 y_predK_int_shape 是:[[1]] [1] 2 BTW,我得到了这些在weibull_loglik_continuous 的开头插入browser()。此外,两个张量的基本print 输出表明y_pred 的形状为(2,),而y_true 的形状为shape=(?,)
  • abab在reshape之前的形状是什么,ab在reshape之后的形状和weibull_activate的结果是什么?
  • ab[[1]] NULL [[2]] [1] 2ab 在 reshape 之前和 1 之后都是 NULL。但是,在k_concatenate() 之后返回的形状为 2。我将它们理解为 Weibull 分布的两个参数 - 每个观察值的一组值。但是,当然,问题是这些应该在何时何地成为整批预测参数,以及如何相应地重塑长度。
  • (实际上,当值对是那些参数以及何时是时间-死亡值对时,我可能会感到困惑。)

标签: r tensorflow keras


【解决方案1】:

这个问题的细节我不明白,但是在weibull_loglik_continuous这里看到一个基本的问题:

  y_true = k_reshape(y_true, c(1, 2))
  y_pred = k_reshape(y_pred, c(1, 2))

您正在强制将 y_truey_pred 重塑为批量大小为 1 的东西。

为了保持批量大小,您需要:

  y_true = k_reshape(y_true, c(-1, 2))
  y_pred = k_reshape(y_pred, c(-1, 2))

现在,我相信 y_truey_pred 已经具有所需的形状,如果它们来自 weibull_activate 并且您的数据实际上是二维的。 (在这种情况下,您根本不需要 weibull_loglik_continuous 中的重塑)

但你必须修复weibull_activate

a = k_reshape(a, c(-1, 1))
b = k_reshape(b, c(-1, 1))

-1 是为可变尺寸维度重塑形状的正确方法。函数 length,可能是一个 R 函数,将无法与 tensorflow Tensor 一起使用,因为张量没有具有长度的数据。

【讨论】:

  • 用这些长度替换 1 给了我:Error in py_call_impl(callable, dots$args, dots$keywords): RuntimeError: Evaluation error: ValueError: Cannot reshape a tensor with 2 elements to shape [2,2] (4 elements) for 'loss/activation_loss/Reshape_1' (op: 'Reshape') with input shapes: [2], [2] and with input tensors computed as partial shapes: input[1] = [2,2]. 这显然是在重塑 y_pred 时发生的。也许问题出在激活函数上。请注意,此错误发生在compile(),而不是fit()
  • 数据确实只是二维的,就像在这个例子中一样 - 每行都是一个单独的观察值,有一个“生存”时间,加上“死亡”的布尔值和预测值。所以批量大小仅用于训练,我猜如果我将批量大小设置为 3 并且训练矩阵的长度为 10,这些将会改变。回复:最后一个轴,你认为 k_concatenate() 可以在某处有所帮助还有这里?检查它的 R 帮助文件,因为它有一个 axis 选项。
  • 成功了!我怀疑 R Keras 最近才实现了一些与 -1 相关的功能和/或省略的索引,如 [,2] 没有事先(重新)整形,我只是假设这行不通。谢谢!!现在我只需要担心这段代码是否准确地体现了连续 Weibull 分布对数似然... ;)
猜你喜欢
  • 1970-01-01
  • 2020-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2019-07-22
  • 1970-01-01
相关资源
最近更新 更多