Изменение формы тензоров для обучения с распределением Вейбулла в R Keras - PullRequest
1 голос
/ 12 октября 2019

Я пытаюсь адаптировать дистрибутив 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))

Создано в 2019-10-12 пакетом Представить (v0.3.0)

Я думаю, это будет означать, что функция потерь может иметь только 1 строку с жестким кодированием (при втором соединении есть попытки сделать его таким же, как пакетразмер и / или количество строк на объект, например, двигатель). Но независимо от того, что я делаю, я получаю какую-то ошибку, либо при компиляции модели, либо при подгонке. Я пробовал несколько разных вещей, включая настройку размера пакета и включение столбца still_going в обучающую матрицу y, но в любом случае форма кажется неправильной. Единственное исключение состоит в том, что выполняет компиляцию и обучение, если размер пакета равен 1, и обучение даже, кажется, имеет смысл (т. Е. Потеря - это реальное число), но, конечно, я не хочучтобы делать онлайн-обучение, я хочу стабильную модель с большим размером партии. Так что, по сути, существует некоторое несоответствие формы между формой тренировки y и функцией потерь, по-видимому, по длине, которую я не могу разрешить.

1 Ответ

0 голосов
/ 16 октября 2019

Я не понимаю деталей этой проблемы, но я вижу основную проблему здесь в 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, потому что тензор не имеет данных для того, чтобы иметь длину.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...