keras-applications
keras-applications copied to clipboard
Keras Lambda making a custom simple layer, tuple TypeError
Here's the task: I've got 2 Keras layers, encode_p_neck & encode_g_neck. They are of the same dimension. I want to calculate the distance between these 2 vectors, and if the distance is greater than a threshold, then I predict this pair of 2 vectors as negative. If the distance is smaller than a threshold, then I predict this pair of 2 vectors as positive. At last, I want to calculate AUC and output this prediction. The responsible code is as follows:
distance = Subtract()([encode_p_neck, encode_g_neck])
def getOutput(X):
distance = tf.norm(X, axis = 1)
output = K.cast(tf.less_equal(distance, threshold), tf.float32)
return output
output = Lambda(getOutput)(distance)
because the output for Keras model has to be a layer, so I did this. But error shows:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-197-18acac9c7a3b> in <module>
74 return output
75
---> 76 output = Lambda(getOutput)(distance)
77
78
~\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in __call__(self, inputs, *args, **kwargs)
661 kwargs.pop('training')
662 inputs, outputs = self._set_connectivity_metadata_(
--> 663 inputs, outputs, args, kwargs)
664 self._handle_activity_regularization(inputs, outputs)
665 self._set_mask_metadata(inputs, outputs, previous_mask)
~\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in _set_connectivity_metadata_(self, inputs, outputs, args, kwargs)
1706 kwargs.pop('mask', None) # `mask` should not be serialized.
1707 self._add_inbound_node(
-> 1708 input_tensors=inputs, output_tensors=outputs, arguments=kwargs)
1709 return inputs, outputs
1710
~\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in _add_inbound_node(self, input_tensors, output_tensors, arguments)
1793 """
1794 inbound_layers = nest.map_structure(lambda t: t._keras_history.layer,
-> 1795 input_tensors)
1796 node_indices = nest.map_structure(lambda t: t._keras_history.node_index,
1797 input_tensors)
~\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\util\nest.py in map_structure(func, *structure, **kwargs)
513
514 return pack_sequence_as(
--> 515 structure[0], [func(*x) for x in entries],
516 expand_composites=expand_composites)
517
~\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\util\nest.py in <listcomp>(.0)
513
514 return pack_sequence_as(
--> 515 structure[0], [func(*x) for x in entries],
516 expand_composites=expand_composites)
517
~\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in <lambda>(t)
1792 `call` method of the layer at the call that created the node.
1793 """
-> 1794 inbound_layers = nest.map_structure(lambda t: t._keras_history.layer,
1795 input_tensors)
1796 node_indices = nest.map_structure(lambda t: t._keras_history.node_index,
AttributeError: 'tuple' object has no attribute 'layer'
Why? How to fix this?
import tensorflow as tf
from keras.models import Model
from keras.layers import Subtract, Lambda, Dense, Input, Flatten
from keras import backend as K
from keras.datasets import mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train.reshape((-1, 784))
x_test = x_test.reshape((-1, 784))
inputs = Input(shape=(784,))
x1 = Dense(64, activation='relu')(inputs)
x2 = Dense(64, activation='relu')(x1)
predictions = Dense(10, activation='softmax')(x2)
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='rmsprop',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train)
## And yours
threshold = 30
distance = Subtract()([x1, x2])
def getOutput(X):
distance = tf.norm(X, axis = 1)
output = K.cast(tf.less_equal(distance, threshold), tf.float32)
return output
output = Lambda(getOutput)(distance)
model_i = Model(inputs=inputs, outputs=output)
predicted_i = model_i.predict(x_test)
import numpy as np
print(np.unique(predicted_i, return_counts=True))
# And this gives following:
>>> (array([0., 1.], dtype=float32), array([ 4, 9996]))
I couldn't reproduce your error, it worked just fine as you intended. And by the way, this kind of question is better to be asked in Stackoverflow I guess, since it seems like it's not an issue or a bug of the project. :)