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.
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)