Ошибка Keras "Вы должны указать значение для тензора-заполнителя" - PullRequest
0 голосов
/ 14 мая 2018

У меня есть простая модель seq2seq:

import seq2seq
import numpy as np
import keras.backend as K

from seq2seq.models import Seq2Seq
from keras.models import Model
from keras.models import Sequential
from keras.layers import Embedding, Input, TimeDistributed, Activation

BLOCK_LEN = 60
EVENTS_CNT = 462

input = Input((BLOCK_LEN,))
embedded = Embedding(input_dim=EVENTS_CNT+1, output_dim=200)(input)
emb_model = Model(input, embedded)

seq_model = Seq2Seq(batch_input_shape=(None, BLOCK_LEN, 200), hidden_dim=200, output_length=BLOCK_LEN, output_dim=EVENTS_CNT)
model = Sequential()
model.add(emb_model)
model.add(seq_model)
model.add(TimeDistributed(Activation('softmax')))

model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
model_1 (Model)              (None, 60, 200)           92600     
_________________________________________________________________
model_12 (Model)             (None, 60, 462)           1077124   
_________________________________________________________________
time_distributed_2 (TimeDist (None, 60, 462)           0         
=================================================================
Total params: 1,169,724
Trainable params: 1,169,724
Non-trainable params: 0
_________________________________________________________________

И я пытаюсь создать свою собственную метрику:

def symbol_acc(true, predicted):
    np_y_true = K.get_value(true)
    np_y_pred = K.get_value(predicted)
    return K.mean(np_y_true == np_y_pred)

И если я пытаюсь скомпилировать модель с этим показателем, я получаю сообщение об ошибке «Вы должны указать значение для тензора-заполнителя» со следующим сообщением:

InvalidArgumentError                      Traceback (most recent call last)
C:\Users\Anna\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _do_call(self, fn, *args)
   1322     try:
-> 1323       return fn(*args)
   1324     except errors.OpError as e:

C:\Users\Anna\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _run_fn(session, feed_dict, fetch_list, target_list, options, run_metadata)
   1301                                    feed_dict, fetch_list, target_list,
-> 1302                                    status, run_metadata)
   1303 

C:\Users\Anna\Anaconda3\lib\site-packages\tensorflow\python\framework\errors_impl.py in __exit__(self, type_arg, value_arg, traceback_arg)
    472             compat.as_text(c_api.TF_Message(self.status.status)),
--> 473             c_api.TF_GetCode(self.status.status))
    474     # Delete the underlying status object from memory otherwise it stays alive

InvalidArgumentError: You must feed a value for placeholder tensor 'time_distributed_2_target' with dtype float and shape [?,?,?]
     [[Node: time_distributed_2_target = Placeholder[dtype=DT_FLOAT, shape=[?,?,?], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

Но следующий код работает нормально (исключений нет):

def symbol_acc2(true, predicted):
    true = np.array(true)
    predicted = np.array(predicted)
    return K.variable((true == predicted).mean())

Не могли бы вы объяснить, что означает это исключение? Я думал, что symbol_acc и symbol_acc2 делают то же самое. Я новичок в NNs и Keras, так что, возможно, я не вижу некоторые очевидные вещи. Я видел похожие вопросы по stackoverflow, но не нашел подходящий ответ для моей ситуации.

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

В symbol_acc, нерабочая версия, tf.keras.backend.get_value() (K.get_value() в вашем коде) пойдет и извлечет значение переменной в виде массива Numpy.Затем эта строка K.mean(np_y_true == np_y_pred) сначала создает еще один (логический) массив Numpy , основанный на равенстве, и tf.keras.backend.mean() пытается обработать этот массив Numpy как тензор, и он просто так не работает.

Ошибка отображается, потому что во время создания графика true еще не имеет значения, не был передан.

symbol_acc2 не выдает ошибку, но также не будет работать, потому чтово время создания графа true и predicted являются просто пустыми тензорами.Numpy не изменит этого, но сравнение потерпит неудачу, взяв среднее значение, которое даст ноль, и вы просто создаете переменную со значением ноль.Рассмотрим этот код (проверено):

import keras.backend as K
import numpy as np

true = K.placeholder( ( 2, ) )
predicted = K.placeholder( ( 2, ) )
a = np.array( true )
b = np.array( predicted )
c = a == b
print( c, c.mean() )

выходы:

(False, 0.0)

независимо от данных (нет даже данныхв тензорах пока нет.)

Для того, чтобы добиться того, что вы хотите, то есть расчета точности ваших прогнозов, вы можете просто использовать

def symbol_acc( true, predicted ):
    return K.mean( K.cast_to_floatx( K.equal( true, predicted ) ) )

Или вы можете сделать свою собственную жизнь прощеи посмотрите на собственную метрику Кераса categorical_accuracy.

0 голосов
/ 14 мая 2018

Метрики, потери и вся модель являются «символическими» тензорами.

Это означает, что у них нет абсолютно никаких данных (или значений) до момента, когда вы начнете подбирать или прогнозировать.

Когда вы звоните K.get_value, вы пытаетесь получить значение, которое не существует.(Он будет существовать только при «подаче данных» в модель. То, что он называет заполнителем, - это пустой входной тензор, который ожидает получить данные при подборе или прогнозировании).

Решение вашей проблемы - просто не пытаться получить значения.(Вертикальная версия также не будет работать, значения не существуют на момент компиляции этой функции).

Вы должны сохранять все операции символическими, и они будут выполняться при подаче данных.

Итак:

def symbol_acc(true, predicted):
    isEqual = K.cast(K.equal(true,predicted),K.floatx())
    return K.mean(isEqual)
...