Search code examples
pythontensorflowneural-networkkerasmetrics

Keras error "You must feed a value for placeholder tensor"


I have simple seq2seq model:

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
_________________________________________________________________

And I'm trying to create my own metric:

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)

And if I try to compile model with this metric I get an error "You must feed a value for placeholder tensor" with the following message:

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"]()]]

But the following code is working fine (doesn't produce any exceptions):

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

Can you please explain me what does that exception mean? I thought symbol_acc and symbol_acc2 are doing the same thing. I'm new in NNs and keras so maybe I don't see some obvious things. I saw similar questions on stackoverflow but didn't find the fit answer for my situation.


Solution

  • Metrics, losses, and the entire model are "symbolic" tensors.

    This means, they have absolutely no data (or value) until the moment you start fitting or predicting.

    When you call K.get_value you're trying to get a value that doesn't exist. (It will only exist when you "feed the data" to the model. What it calls a placeholder is an empty input tensor that is expecting to receive the data when fitting or predicting).

    The solution to your problem is simply not trying to get the values. (The numpy version will not work either, the values don't exist at the moment this function is compiled).

    You gotta keep all operations symbolic, and they will be performed when you feed the data.

    So:

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