我正在尝试调整首先在这里使用的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的形状与损失函数之间存在形状不匹配的问题,显然是在长度上,我无法解决。
答案 0 :(得分:0)
我不了解此问题的详细信息,但是我在weibull_loglik_continuous
中看到了一个基本问题:
y_true = k_reshape(y_true, c(1, 2))
y_pred = k_reshape(y_pred, c(1, 2))
您正在强制将y_true
和y_pred
的重塑成批处理大小为1的东西。
要保持批量大小,您需要:
y_true = k_reshape(y_true, c(-1, 2))
y_pred = k_reshape(y_pred, c(-1, 2))
现在,如果y_true
和y_pred
来自weibull_activate
,并且您的数据实际上是2D的,我相信它们已经具有所需的形状。 (在这种情况下,您根本不需要在weibull_loglik_continuous
中进行重塑)
但是您必须修复weibull_activate
:
a = k_reshape(a, c(-1, 1))
b = k_reshape(b, c(-1, 1))
值-1
是对可变尺寸尺寸进行整形的正确方法。函数length
(可能是R函数)不适用于张量流Tensor
,因为张量没有用于长度的数据。