Related
I am building a model with a custom attention layer as implemented in Tensorflow's nmt tutorial. I used the same layer code with a few changes which I found as suggestions in order to solve my problem.
The problem is that I cannot load the model from file after I save it when I have this custom layer. This is the layer class:
class BahdanauAttention(layers.Layer):
def __init__(self, output_dim=30, **kwargs):
super(BahdanauAttention, self).__init__(**kwargs)
self.W1 = tf.keras.layers.Dense(output_dim)
self.W2 = tf.keras.layers.Dense(output_dim)
self.V = tf.keras.layers.Dense(1)
def call(self, inputs, **kwargs):
query = inputs[0]
values = inputs[1]
query_with_time_axis = tf.expand_dims(query, 1)
score = self.V(tf.nn.tanh(
self.W1(query_with_time_axis) + self.W2(values)))
attention_weights = tf.nn.softmax(score, axis=1)
context_vector = attention_weights * values
context_vector = tf.reduce_sum(context_vector, axis=1)
return context_vector, attention_weights
def get_config(self):
config = super(BahdanauAttention, self).get_config()
config.update({
'W1': self.W1,
'W2': self.W2,
'V': self.V,
})
return config
I am saving the model with keras' ModelCheckpoint callback:
path = os.path.join(self.dir, 'model_{}'.format(self.timestamp))
callbacks.append(ModelCheckpoint(path, save_best_only=True, monitor='val_loss', mode='min'))
Later, I am loading the model like so:
self.model = load_model(path, custom_objects={'BahdanauAttention': BahdanauAttention, 'custom_loss': self.custom_loss})
This is the error message I am getting:
raise TypeError(error_message, kwarg)
TypeError: ('Keyword argument not understood:', 'W1')
and full traceback:
Traceback (most recent call last):
File "models/lstm.py", line 49, in load_model
'dollar_mape_loss': self.dollar_mape_loss})
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/save.py", line 187, in load_model
return saved_model_load.load(filepath, compile, options)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 121, in load
path, options=options, loader_cls=KerasObjectLoader)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/saved_model/load.py", line 633, in load_internal
ckpt_options)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 194, in __init__
super(KerasObjectLoader, self).__init__(*args, **kwargs)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/saved_model/load.py", line 130, in __init__
self._load_all()
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 215, in _load_all
self._layer_nodes = self._load_layers()
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 315, in _load_layers
layers[node_id] = self._load_layer(proto.user_object, node_id)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 341, in _load_layer
obj, setter = self._revive_from_config(proto.identifier, metadata, node_id)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 359, in _revive_from_config
self._revive_layer_from_config(metadata, node_id))
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 417, in _revive_layer_from_config
generic_utils.serialize_keras_class_and_config(class_name, config))
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/layers/serialization.py", line 175, in deserialize
printable_module_name='layer')
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/utils/generic_utils.py", line 360, in deserialize_keras_object
return cls.from_config(cls_config)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 697, in from_config
return cls(**config)
File "models/lstm.py", line 310, in __init__
super(BahdanauAttention, self).__init__(**kwargs)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/training/tracking/base.py", line 457, in _method_wrapper
result = method(self, *args, **kwargs)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 318, in __init__
generic_utils.validate_kwargs(kwargs, allowed_kwargs)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/utils/generic_utils.py", line 778, in validate_kwargs
raise TypeError(error_message, kwarg)
TypeError: ('Keyword argument not understood:', 'W1')
Similar questions suggest that the code is using different versions of Keras and TensorFlow. I am only using TensorFlow's Keras. These are the imports
from tensorflow.keras.models import load_model
from tensorflow.keras.callbacks import EarlyStopping, CSVLogger, ModelCheckpoint
from tensorflow.keras import layers
Following keras' documentation on custom layers, They recommend that any weights should not be initialized in __init__() but in build(). This way the weights do not need to be added to the config and the error will be resolved.
This is the updated custom layer class:
class BahdanauAttention(tf.keras.layers.Layer):
def __init__(self, units=30, **kwargs):
super(BahdanauAttention, self).__init__(**kwargs)
self.units = units
def build(self, input_shape):
self.W1 = tf.keras.layers.Dense(self.units)
self.W2 = tf.keras.layers.Dense(self.units)
self.V = tf.keras.layers.Dense(1)
def call(self, inputs, **kwargs):
query = inputs[0]
values = inputs[1]
query_with_time_axis = tf.expand_dims(query, 1)
score = self.V(tf.nn.tanh(
self.W1(query_with_time_axis) + self.W2(values)))
attention_weights = tf.nn.softmax(score, axis=1)
context_vector = attention_weights * values
context_vector = tf.reduce_sum(context_vector, axis=1)
return context_vector, attention_weights
def get_config(self):
config = super(BahdanauAttention, self).get_config()
config.update({
'units': self.units,
})
return config
I also have this problem.
I've tried a lot of methods and found that this method can be used.
first,build model
model = TextAttBiRNN(maxlen, max_features, embedding_dims).get_model()
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
second, load weights:
I solved the problem with this:
model_file = "/content/drive/My Drive/dga/output_data/model_lstm_att_test_v6.h5"
model.load_weights(model_file)
then,we will find the modle can be use.
in this way,I avoided the previous questions.
I am loading a pretrained attention model in Keras using load_model() .
My Attention class is defined as below.
# attention class
from keras.engine.topology import Layer
from keras import initializers, regularizers, constraints
from keras import backend as K
class Attention(Layer):
def __init__(self, step_dim, w_regularizer=None, b_regularizer=None,
w_constraint=None, b_constraint=None, bias=True, **kwargs):
self.supports_masking = True
# weight initializer
self.init = initializers.get('glorot_uniform')
self.w_regularizer = regularizers.get(w_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.w_constraint = constraints.get(w_constraint)
self.b_constraint = constraints.get(b_constraint)
self.bias = bias
self.step_dim = step_dim
self.features_dim = 0
super(Attention, self).__init__(**kwargs)
def build(self, input_shape):
assert len(input_shape) == 3
self.w = self.add_weight(shape=(input_shape[-1],),
initializer=self.init, name='{}_w'.format(self.name),
regularizer=self.w_regularizer,
constraint=self.w_constraint)
self.features_dim = input_shape[-1]
if self.bias:
self.b = self.add_weight(shape=(input_shape[1],),
initializer='zero', name='{}_b'.format(self.name),
regularizer=self.b_regularizer,
constraint=self.b_constraint)
else:
self.b = None
self.built = True
def compute_mask(self, input, input_mask=None):
return None
def call(self, x, mask=None):
features_dim = self.features_dim
step_dim = self.step_dim
eij = K.reshape(K.dot(K.reshape(x, (-1, features_dim)),
K.reshape(self.w, (features_dim, 1))), (-1, step_dim))
if self.bias:
eij += self.b
eij = K.tanh(eij)
a = K.exp(eij)
if mask is not None:
a *= K.cast(mask, K.floatx())
a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())
a = K.expand_dims(a)
weighted_input = x * a
return K.sum(weighted_input, axis=1)
def compute_output_shape(self, input_shape):
return input_shape[0], self.features_dim
def get_config(self):
config = {
'step_dim': self.step_dim,
'w_regularizer': self.w_regularizer,
'w_constraint': self.w_constraint,
'b_regularizer': self.b_regularizer,
'b_constraint': self.b_constraint,
'bias': self.bias
}
base_config = super(Attention, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
The model is called in test_loadmod.py as
from attention import Attention
from keras.models import load_model
model = load_model('attention_wo_cval.h5', custom_objects={'Attention': Attention})
print(model)
The custom Attention model is made available using load_model() and custom_objects is passed into it as described here.
However it doesnt seem to find the step_dim attribute. Throws up the below error. Any idea how to get this going ? Thanks for your time and help.
Error while loading
TypeError: __init__() missing 1 required positional argument: 'step_dim'
File "test_loadmod.py", line 4, in <module>
model = load_model('attention_wo_cval.h5', custom_objects={'Attention': Attention})
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\saving.py", line 492, in load_wrapper
return load_function(*args, **kwargs)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\saving.py", line 584, in load_model
model = _deserialize_model(h5dict, custom_objects, compile)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\saving.py", line 274, in _deserialize_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\saving.py", line 627, in model_from_config
return deserialize(config, custom_objects=custom_objects)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\layers\__init__.py", line 165, in deserialize
return deserialize_keras_object(config,
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\utils\generic_utils.py", line 144, in deserialize_keras_object
return cls.from_config(
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\network.py", line 1056, in from_config
process_layer(layer_data)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\network.py", line 1041, in process_layer
layer = deserialize_layer(layer_data,
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\layers\__init__.py", line 165, in deserialize
return deserialize_keras_object(config,
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\utils\generic_utils.py", line 149, in deserialize_keras_object
return cls.from_config(config['config'])
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\base_layer.py", line 1179, in from_config
return cls(**config)
TypeError: __init__() missing 1 required positional argument: 'step_dim'
The get_config method is the right solution, but you have to pay attention to save the model when this method is updated.
So:
First add the get_config method
Save the model (with this method)
Load the method
I am trying to implement a Faster-RCNN model for object detection written by Yinghan Xu. After I have trained and saved the model with model_all.save('filename.h5'), I am trying to freeze the Keras model as TensorFlow graph (as .pb) for inference using keras_to_tensorflow.py written by Amir Abdi. But when I try to convert it, I get a ValueError: Unknown layer: roipoolingconv due to a custom RoiPoolingConv layer:
class RoiPoolingConv(Layer):
'''ROI pooling layer for 2D inputs.
See Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition,
K. He, X. Zhang, S. Ren, J. Sun
# Arguments
pool_size: int
Size of pooling region to use. pool_size = 7 will result in a 7x7 region.
num_rois: number of regions of interest to be used
# Input shape
list of two 4D tensors [X_img,X_roi] with shape:
X_img:
`(1, rows, cols, channels)`
X_roi:
`(1,num_rois,4)` list of rois, with ordering (x,y,w,h)
# Output shape
3D tensor with shape:
`(1, num_rois, channels, pool_size, pool_size)`
'''
def __init__(self, pool_size, num_rois, **kwargs):
self.dim_ordering = K.image_dim_ordering()
self.pool_size = pool_size
self.num_rois = num_rois
super(RoiPoolingConv, self).__init__(**kwargs)
def build(self, input_shape):
self.nb_channels = input_shape[0][3]
def compute_output_shape(self, input_shape):
return None, self.num_rois, self.pool_size, self.pool_size, self.nb_channels
def call(self, x, mask=None):
assert(len(x) == 2)
# x[0] is image with shape (rows, cols, channels)
img = x[0]
# x[1] is roi with shape (num_rois,4) with ordering (x,y,w,h)
rois = x[1]
input_shape = K.shape(img)
outputs = []
for roi_idx in range(self.num_rois):
x = rois[0, roi_idx, 0]
y = rois[0, roi_idx, 1]
w = rois[0, roi_idx, 2]
h = rois[0, roi_idx, 3]
x = K.cast(x, 'int32')
y = K.cast(y, 'int32')
w = K.cast(w, 'int32')
h = K.cast(h, 'int32')
# Resized roi of the image to pooling size (7x7)
rs = tf.image.resize_images(img[:, y:y+h, x:x+w, :], (self.pool_size, self.pool_size))
outputs.append(rs)
final_output = K.concatenate(outputs, axis=0)
# Reshape to (1, num_rois, pool_size, pool_size, nb_channels)
# Might be (1, 4, 7, 7, 3)
final_output = K.reshape(final_output, (1, self.num_rois, self.pool_size, self.pool_size, self.nb_channels))
# permute_dimensions is similar to transpose
final_output = K.permute_dimensions(final_output, (0, 1, 2, 3, 4))
return final_output
def get_config(self):
config = {'pool_size': self.pool_size,
'num_rois': self.num_rois}
base_config = super(RoiPoolingConv, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
I have looked at most of the resources out there and almost all of them suggest to comment out this layer. But since this layer is important for object detection, I was wondering if a workaround is possible or not.
The complete traceback of error (note: I've saved filename as freezekeras.py, contents are same as keras_to_tensorflow.py):
Using TensorFlow backend.
Traceback (most recent call last):
File "freezekeras.py", line 181, in <module>
app.run(main)
File "/usr/local/lib/python3.5/dist-packages/absl/app.py", line 300, in run
_run_main(main, args)
File "/usr/local/lib/python3.5/dist-packages/absl/app.py", line 251, in _run_main
sys.exit(main(argv))
File "freezekeras.py", line 127, in main
model = load_model(FLAGS.input_model, FLAGS.input_model_json, FLAGS.input_model_yaml)
File "freezekeras.py", line 105, in load_model
raise wrong_file_err
File "freezekeras.py", line 62, in load_model
model = keras.models.load_model(input_model_path)
File "/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py", line 419, in load_model
model = _deserialize_model(f, custom_objects, compile)
File "/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py", line 225, in _deserialize_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py", line 458, in model_from_config
return deserialize(config, custom_objects=custom_objects)
File "/usr/local/lib/python3.5/dist-packages/keras/layers/__init__.py", line 55, in deserialize
printable_module_name='layer')
File "/usr/local/lib/python3.5/dist-packages/keras/utils/generic_utils.py", line 145, in deserialize_keras_object
list(custom_objects.items())))
File "/usr/local/lib/python3.5/dist-packages/keras/engine/network.py", line 1022, in from_config
process_layer(layer_data)
File "/usr/local/lib/python3.5/dist-packages/keras/engine/network.py", line 1008, in process_layer
custom_objects=custom_objects)
File "/usr/local/lib/python3.5/dist-packages/keras/layers/__init__.py", line 55, in deserialize
printable_module_name='layer')
File "/usr/local/lib/python3.5/dist-packages/keras/utils/generic_utils.py", line 138, in deserialize_keras_object
': ' + class_name)
ValueError: Unknown layer: RoiPoolingConv
Try to specify the custom layer explicitly:
model = load_model('my_model.h5', custom_objects={'RoiPoolingConv': RoiPoolingConv})
Obviously, you have to re-write the keras_to_tensorflow.py script. See Handling custom layers (or other custom objects) in saved models section under Keras FAQ.
Solution
specify custom layer while loading model in keras_to_tensorflow.py
model = keras.models.load_model(input_model_path, custom_objects={'RoiPoolingConv':RoiPoolingConv})
import RoiPoolingConv.py to keras_to_tensorflow project
specify default pool_size, num_rois for RoiPoolingConv
def __init__(self, pool_size = 7, num_rois = 32, **kwargs):
I am trying to implement Graph Convolution Layer using Keras custom layer that is mentioned in the following paper: GCNN.
When I am trying to train my model, It gives me the following error:
Traceback (most recent call last):
File "main.py", line 35, in <module>
model.fit(train_images, train_labels, validation_data=(test_images, test_labels), epochs=50, batch_size=32)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1010, in fit
self._make_train_function()
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 509, in _make_train_function
loss=self.total_loss)
File "/usr/local/lib/python2.7/dist-packages/keras/legacy/interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/keras/optimizers.py", line 256, in get_updates
grads = self.get_gradients(loss, params)
File "/usr/local/lib/python2.7/dist-packages/keras/optimizers.py", line 91, in get_gradients
raise ValueError('An operation has `None` for gradient. '
ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.
I don't know how to get rid of this problem.
Can someone explain me briefly what should I do?
I have gone through Keras official documentation about writing custom layer but it didn't specify about it. Link
Following is the code for my custom layer.
class GraphConvolutionalLayer(Layer):
def __init__(self, A, num_input_features, num_output_features, **kwargs):
self.A = A
self.num_input_features = num_input_features
self.num_output_features = num_output_features
self.num_vertices = A.get_shape().as_list()[0]
self.input_spec = (self.num_vertices, num_input_features)
super(GraphConvolutionalLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.k0 = self.add_weight(name='k0',
shape=(self.num_output_features, self.num_input_features),
initializer='uniform',
trainable=True)
self.k1 = self.add_weight(name='k1',
shape=(self.num_output_features, self.num_input_features),
initializer='uniform',
trainable=True)
self.H = tf.einsum('ab,cd->abcd', tf.convert_to_tensor(self.k0, dtype=tf.float32), tf.eye(self.num_vertices))
self.built = True
def call(self, Vin):
Vin2 = tf.reshape(tf.transpose(Vin, [0, 2, 1]), [Vin.get_shape().as_list()[1] * Vin.get_shape().as_list()[2], -1])
H_tmp = tf.reshape(tf.transpose(self.H, [0, 2, 1, 3]), [ self.num_output_features, self.num_vertices, self.num_vertices * self.num_input_features])
Vout = tf.transpose(K.dot(H_tmp, Vin2), [2, 1, 0])
return Vout
def compute_output_shape(self, input_shape):
return (self.num_vertices, self.num_output_features)
Following is the code for the main file.
main_input = Input(shape=train_images[0].shape)
Vout1 = GraphConvolutionalLayer(A, 1, 4)(main_input)
Vout2 = GraphConvolutionalLayer(A, 4, 8)(Vout1)
Vout3 = Flatten()(Vout2)
Vout4 = Dense(10, activation='sigmoid')(Vout3)
print(train_images.shape, train_labels.shape)
model = Model(inputs=main_input, outputs=Vout4)
print(model.summary())
model.compile(optimizer='rmsprop', loss='binary_crossentropy')
model.fit(train_images, train_labels, validation_data=(test_images, test_labels), epochs=50, batch_size=32)
Here, I take uniform as an initializer. When I changed it, I didn't get any error. I don't know why this happened but I could be able to solve my error just changing that line.
As error states, some of your function is non-differentiable. It' not easy to say why exactly it happens. For example, take a look
List of Differentiable Ops in Tensorflow
How to make sure your computation graph is differentiable
Edit: Consider example, where I use standard cifar10 data.
class GraphConvolutionalLayer(layers.Layer):
def __init__(self, A, num_input_features, num_output_features, **kwargs):
#self.A = A
self.num_input_features = num_input_features
self.num_output_features = num_output_features
self.num_vertices = A
self.input_spec = (self.num_vertices, num_input_features)
super(GraphConvolutionalLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.k0 = self.add_weight(name='k0',
shape=(self.num_output_features, self.num_input_features),
initializer='uniform',
trainable=True)
self.H = tf.einsum('ab,cd->abcd', tf.convert_to_tensor(self.k0, dtype=tf.float32), tf.eye(self.num_vertices))
self.H = tf.reshape(self.H, [32*32, 3])
self.built = True
def call(self, Vin):
Vin2 = tf.reshape(Vin, [Vin.get_shape().as_list()[1] * Vin.get_shape().as_list()[1],Vin.get_shape().as_list()[-1]])
Vin2 = tf.transpose(Vin2)
Vout = tf.matmul(self.H, Vin2)
return Vout
def input_fn():
train, test = tf.keras.datasets.cifar10.load_data()
dataset = tf.data.Dataset.from_tensor_slices((train[0], train[1]))
dataset = dataset.batch(1)
return dataset
main_input = layers.Input(shape=[32, 32, 3])
Vout1 = GraphConvolutionalLayer(32, 3, 1)(main_input)
Vout3 = layers.Flatten()(Vout1)
Vout4 = layers.Dense(10, activation='sigmoid')(Vout3)
model = Model(inputs=main_input, outputs=Vout4)
model.compile(optimizer='rmsprop', loss='binary_crossentropy')
model.fit(input_fn(), epochs=50, steps_per_epoch=10)
In this case gradients are computed. So the problem clearly is not in how you construct GraphConvolutionalLayer but in some internal operation, which depends on data. You need to check every op one by one with your data shapes.
P.S. You can try substituting einsum with matmul, cause the former is simply a syntactic wrap for the latter.
I want to apply Spatial Pyramid Pooling before the Dense layer in a CNN.
I used Keras for implementation.
Tensorflow was used as a backend.
However, I got an error.
What's wrong with my code? Thank you.
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
model.add(SpatialPyramidPooling(pooling_regions, input_shape=Input(shape = (None,None,None,3))))
File "C:\Program Files\Python36\lib\site-packages\spp\SpatialPyramidPooling.py", line 33, in __init__
super(SpatialPyramidPooling, self).__init__(**kwargs)
File "C:\Program Files\Python36\lib\site-packages\keras\engine\topology.py", line 311, in __init__
batch_input_shape = (batch_size,) + tuple(kwargs['input_shape'])
File "C:\Program Files\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 439, in __iter__
"Tensor objects are not iterable when eager execution is not "
TypeError: Tensor objects are not iterable when eager execution is not enabled. To iterate over this tensor use tf.map_fn.
Here is the code:
from keras.engine.topology import Layer
from keras.models import Sequential
import keras.backend as K
import numpy as np
model = Sequential()
model.add(SpatialPyramidPooling((1,2,4), Input(shape=(None, None, None, 3))))
class SpatialPyramidPooling(Layer):
def __init__(self, pool_list, **kwargs):
self.dim_ordering = K.image_dim_ordering()
assert self.dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.pool_list = pool_list
self.num_outputs_per_channel = sum([i * i for i in pool_list])
super(SpatialPyramidPooling, self).__init__(**kwargs)
def call(self, x, mask=None):
input_shape = K.shape(x)
print(input_shape)
print(K.eval(input_shape))
outputs = K.variable(value=np.random.random((3,4)))
return outputs
I'm pretty sure you should be using input_shape=(None,None,None,3) instead of input_shape=Input(shape = (None,None,None,3))
Also, you cannot use any function that demands the presence of data in the call method. You're using K.shape and K.eval, both will bring you errors in compilation.
If you need information about the input shape, you have to do it in the def build(self, input_shape): method.