IndexedSlicesValue возвращает больше элементов, чем dens_shape после вычисления градиентов
Я пытаюсь использовать tenorflow 1.1 на процессоре с python 3.5 для вычисления чувствительности (градиентов) моделирования Монте-Карло. Точный код довольно сложен, но суть его довольно проста:
- У меня есть заполнитель, представляющий кривую процентной ставки (векторный размер 1500). Обратите внимание, что тенор баллы (индексы каждого курса) являются постоянными. Например, простая кривая 4 процентных ставок может быть [0,01, 0,02, 0,023, 0,021] с фиксированными тенорными точками [0,25, 0,5, 1, 2], представляющими ставки через 3 месяца, 6 месяцев, 1 и 2 года соответственно.
- У меня есть процесс симуляции, который генерирует тензор размером 82,1500,2000, представляющий, как выглядит кривая в разные будущие моменты времени (82 здесь) и по 2000 симуляций в каждой.
- Чтобы создать тензор симуляции, я использую команду сбора, чтобы интерполировать точки тенора кривой к правильной будущей сетке времени (82 временные точки, упомянутые ранее)
Код содержит что-то вроде этого (tnr - это фиксированные точки тенора, tnr_d - это первое отличие tnr - обе имеют ту же форму, что и заполнитель):
alpha_1 = (ten_tv - tnr[ten_t])/tnr_d[ten_t]
fwd1 = alpha_1*tf.gather(tensor,ten_t + 1) + (1 - alpha_1)*tf.gather(tensor, ten_t)
ten_tv и ten_t являются матрицами формы (82,1500), представляющими (обязательные) будущие точки тенора и ближайший индекс в заполнителе в момент времени t для точки тенора i соответственно. Например, ten_t может выглядеть так:
array([[ 0, 1, 2, ..., 1497, 1498, 1499],
[ 1, 1, 2, ..., 1497, 1498, 1499],
[ 2, 2, 3, ..., 1497, 1498, 1499],
...,
[ 645, 645, 646, ..., 1499, 1499, 1499],
[ 657, 658, 659, ..., 1499, 1499, 1499],
[ 669, 670, 670, ..., 1499, 1499, 1499]])
наконец, тензор - это заполнитель формы (1500), представляющий входную кривую.
Затем запускается симуляция Монте-Карло, и я получаю правильный ответ:
out = (1.0-r)*tf.reduce_sum(0.5*(pv_exposure[1:]+pv_exposure[:-1])*pd,axis=0)
grad_out = tf.gradients(out, placeholder_curve)
Но я получаю странный ответ для grad_out:
IndexedSlicesValue(values=array([ 0. , 0. , 0. , ...,
461803.6875 , 153901.359375 , 462.78277588], dtype=float32), indices=array([ 1, 2, 3, ..., 645, 657, 669], dtype=int64), dense_shape=array([1500]))
Я проверил онлайн, и согласился, что IndexedSlicesValue возвращается из tf.gradients, если используется операция сбора.
Но вот в чем дело - и значения, и индексы, возвращаемые в разреженном тензоре IndexedSlicesValue, имеют размер 253380.
Как это возможно? И что еще более важно, как получить градиенты? Суммирую ли я их? Средний их? Мне просто нужен вектор размером 1500 (который является плотной формой результата)
Благодарю.