Batch-size dimension not honored when composing models
I have a Keras model that I defined during training as:
img = keras.Input(shape=[65, 65, 2])
bnorm = keras.layers.BatchNormalization()(img)
...
model = keras.Model(img, outputprob)
During serving, though, my inputs come differently. Therefore, I defined an input layer (verifying that the to_img
shape comes out to be also (65, 65, 2)
) and tried to do model composition using:
to_img = keras.layers.Lambda(...)(json_input)
model_output = model(to_img)
serving_model = keras.Model(json_input, model_output)
However, I get this error:
tensorflow.python.framework.errors_impl.InvalidArgumentError:
Shape must be rank 4 but is rank 3 for
'model/batch_normalization/cond/FusedBatchNorm' (op:
'FusedBatchNorm') with input shapes: [65,65,2],
[2], [2], [0], [0].
This seems to indicate the batch-dimension didn't make it through. Why?
EDIT:
Things I have tried:
(1) Explicitly set trainable=False
in all the layers but that didn't seem to make any difference:
model_core = model
for layer in model_core.layers:
layer.trainable = False
model_output = model_core(to_img)
(2) Tried expanding the result of the preproc:
to_img = keras.layers.Lambda(
lambda x : preproc(x))(json_input)
to_img = keras.layers.Lambda(
lambda x : tf.expand_dims(x, axis=0) )(to_img)
This results in an error: AttributeError: 'Model' object has no attribute '_name'
on the line serving_model = keras.Model(json_input, model_output)
(3) Changed the lambda layer to do a map_fn to process the data individually:
to_img = keras.layers.Lambda(
lambda items: K.map_fn(lambda x: preproc, items))(json_input)
This caused a shape error that indicates that the preproc function is getting [65,2] items instead of [65,65,2]. This suggests that the Lambda layer applies the function to examples one at a time.
(4) Here's the full code for the model:
img = keras.Input(shape=[height, width, 2])
# convolutional part of model
cnn = keras.layers.BatchNormalization()(img)
for layer in range(nlayers):
nfilters = nfil * (layer + 1)
cnn = keras.layers.Conv2D(nfilters, (ksize, ksize), padding='same')(cnn)
cnn = keras.layers.Activation('elu')(cnn)
cnn = keras.layers.BatchNormalization()(cnn)
cnn = keras.layers.MaxPooling2D(pool_size=(2, 2))(cnn)
cnn = keras.layers.Flatten()(cnn)
cnn = keras.layers.Dropout(dprob)(cnn)
cnn = keras.layers.Dense(10, activation='relu')(cnn)
# feature engineering part of model
engfeat = keras.layers.Lambda(
lambda x: engineered_features(x, height//2))(img)
# concatenate the two parts
both = keras.layers.concatenate([cnn, engfeat])
ltgprob = keras.layers.Dense(1, activation='sigmoid')(both)
# create a model
model = keras.Model(img, ltgprob)
def rmse(y_true, y_pred):
import tensorflow.keras.backend as K
return K.sqrt(K.mean(K.square(y_pred - y_true), axis=-1))
optimizer = tf.keras.optimizers.Adam(lr=params['learning_rate'],
clipnorm=1.)
model.compile(optimizer=optimizer,
loss='binary_crossentropy',
metrics=['accuracy', 'mse', rmse])
and the code for the preprocessing function:
def reshape_into_image(features, params):
# stack the inputs to form a 2-channel input
# features['ref'] is [-1, height*width]
# stacked image is [-1, height*width, n_channels]
n_channels = 2
stacked = tf.concat([features['ref'], features['ltg']], axis=1)
height = width = PATCH_SIZE(params)
return tf.reshape(stacked, [height, width, n_channels])
and the serving layer:
# 1. layer that extracts multiple inputs from JSON
height = width = PATCH_SIZE(hparams)
json_input = keras.layers.concatenate([
keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,)),
], axis=0)
# 2. convert json_input to image (what model wants)
to_img = keras.layers.Lambda(
lambda x: reshape_into_image(features=
'ref': tf.reshape(x[0], [height * width, 1]),
'ltg': tf.reshape(x[1], [height * width, 1])
, params=hparams),
name='serving_reshape')(json_input)
# 3. now, use trained model to predict
model_output = model(to_img)
# 4. create serving model
serving_model = keras.Model(json_input, model_output)
python tensorflow machine-learning keras keras-layer
add a comment |
I have a Keras model that I defined during training as:
img = keras.Input(shape=[65, 65, 2])
bnorm = keras.layers.BatchNormalization()(img)
...
model = keras.Model(img, outputprob)
During serving, though, my inputs come differently. Therefore, I defined an input layer (verifying that the to_img
shape comes out to be also (65, 65, 2)
) and tried to do model composition using:
to_img = keras.layers.Lambda(...)(json_input)
model_output = model(to_img)
serving_model = keras.Model(json_input, model_output)
However, I get this error:
tensorflow.python.framework.errors_impl.InvalidArgumentError:
Shape must be rank 4 but is rank 3 for
'model/batch_normalization/cond/FusedBatchNorm' (op:
'FusedBatchNorm') with input shapes: [65,65,2],
[2], [2], [0], [0].
This seems to indicate the batch-dimension didn't make it through. Why?
EDIT:
Things I have tried:
(1) Explicitly set trainable=False
in all the layers but that didn't seem to make any difference:
model_core = model
for layer in model_core.layers:
layer.trainable = False
model_output = model_core(to_img)
(2) Tried expanding the result of the preproc:
to_img = keras.layers.Lambda(
lambda x : preproc(x))(json_input)
to_img = keras.layers.Lambda(
lambda x : tf.expand_dims(x, axis=0) )(to_img)
This results in an error: AttributeError: 'Model' object has no attribute '_name'
on the line serving_model = keras.Model(json_input, model_output)
(3) Changed the lambda layer to do a map_fn to process the data individually:
to_img = keras.layers.Lambda(
lambda items: K.map_fn(lambda x: preproc, items))(json_input)
This caused a shape error that indicates that the preproc function is getting [65,2] items instead of [65,65,2]. This suggests that the Lambda layer applies the function to examples one at a time.
(4) Here's the full code for the model:
img = keras.Input(shape=[height, width, 2])
# convolutional part of model
cnn = keras.layers.BatchNormalization()(img)
for layer in range(nlayers):
nfilters = nfil * (layer + 1)
cnn = keras.layers.Conv2D(nfilters, (ksize, ksize), padding='same')(cnn)
cnn = keras.layers.Activation('elu')(cnn)
cnn = keras.layers.BatchNormalization()(cnn)
cnn = keras.layers.MaxPooling2D(pool_size=(2, 2))(cnn)
cnn = keras.layers.Flatten()(cnn)
cnn = keras.layers.Dropout(dprob)(cnn)
cnn = keras.layers.Dense(10, activation='relu')(cnn)
# feature engineering part of model
engfeat = keras.layers.Lambda(
lambda x: engineered_features(x, height//2))(img)
# concatenate the two parts
both = keras.layers.concatenate([cnn, engfeat])
ltgprob = keras.layers.Dense(1, activation='sigmoid')(both)
# create a model
model = keras.Model(img, ltgprob)
def rmse(y_true, y_pred):
import tensorflow.keras.backend as K
return K.sqrt(K.mean(K.square(y_pred - y_true), axis=-1))
optimizer = tf.keras.optimizers.Adam(lr=params['learning_rate'],
clipnorm=1.)
model.compile(optimizer=optimizer,
loss='binary_crossentropy',
metrics=['accuracy', 'mse', rmse])
and the code for the preprocessing function:
def reshape_into_image(features, params):
# stack the inputs to form a 2-channel input
# features['ref'] is [-1, height*width]
# stacked image is [-1, height*width, n_channels]
n_channels = 2
stacked = tf.concat([features['ref'], features['ltg']], axis=1)
height = width = PATCH_SIZE(params)
return tf.reshape(stacked, [height, width, n_channels])
and the serving layer:
# 1. layer that extracts multiple inputs from JSON
height = width = PATCH_SIZE(hparams)
json_input = keras.layers.concatenate([
keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,)),
], axis=0)
# 2. convert json_input to image (what model wants)
to_img = keras.layers.Lambda(
lambda x: reshape_into_image(features=
'ref': tf.reshape(x[0], [height * width, 1]),
'ltg': tf.reshape(x[1], [height * width, 1])
, params=hparams),
name='serving_reshape')(json_input)
# 3. now, use trained model to predict
model_output = model(to_img)
# 4. create serving model
serving_model = keras.Model(json_input, model_output)
python tensorflow machine-learning keras keras-layer
add a comment |
I have a Keras model that I defined during training as:
img = keras.Input(shape=[65, 65, 2])
bnorm = keras.layers.BatchNormalization()(img)
...
model = keras.Model(img, outputprob)
During serving, though, my inputs come differently. Therefore, I defined an input layer (verifying that the to_img
shape comes out to be also (65, 65, 2)
) and tried to do model composition using:
to_img = keras.layers.Lambda(...)(json_input)
model_output = model(to_img)
serving_model = keras.Model(json_input, model_output)
However, I get this error:
tensorflow.python.framework.errors_impl.InvalidArgumentError:
Shape must be rank 4 but is rank 3 for
'model/batch_normalization/cond/FusedBatchNorm' (op:
'FusedBatchNorm') with input shapes: [65,65,2],
[2], [2], [0], [0].
This seems to indicate the batch-dimension didn't make it through. Why?
EDIT:
Things I have tried:
(1) Explicitly set trainable=False
in all the layers but that didn't seem to make any difference:
model_core = model
for layer in model_core.layers:
layer.trainable = False
model_output = model_core(to_img)
(2) Tried expanding the result of the preproc:
to_img = keras.layers.Lambda(
lambda x : preproc(x))(json_input)
to_img = keras.layers.Lambda(
lambda x : tf.expand_dims(x, axis=0) )(to_img)
This results in an error: AttributeError: 'Model' object has no attribute '_name'
on the line serving_model = keras.Model(json_input, model_output)
(3) Changed the lambda layer to do a map_fn to process the data individually:
to_img = keras.layers.Lambda(
lambda items: K.map_fn(lambda x: preproc, items))(json_input)
This caused a shape error that indicates that the preproc function is getting [65,2] items instead of [65,65,2]. This suggests that the Lambda layer applies the function to examples one at a time.
(4) Here's the full code for the model:
img = keras.Input(shape=[height, width, 2])
# convolutional part of model
cnn = keras.layers.BatchNormalization()(img)
for layer in range(nlayers):
nfilters = nfil * (layer + 1)
cnn = keras.layers.Conv2D(nfilters, (ksize, ksize), padding='same')(cnn)
cnn = keras.layers.Activation('elu')(cnn)
cnn = keras.layers.BatchNormalization()(cnn)
cnn = keras.layers.MaxPooling2D(pool_size=(2, 2))(cnn)
cnn = keras.layers.Flatten()(cnn)
cnn = keras.layers.Dropout(dprob)(cnn)
cnn = keras.layers.Dense(10, activation='relu')(cnn)
# feature engineering part of model
engfeat = keras.layers.Lambda(
lambda x: engineered_features(x, height//2))(img)
# concatenate the two parts
both = keras.layers.concatenate([cnn, engfeat])
ltgprob = keras.layers.Dense(1, activation='sigmoid')(both)
# create a model
model = keras.Model(img, ltgprob)
def rmse(y_true, y_pred):
import tensorflow.keras.backend as K
return K.sqrt(K.mean(K.square(y_pred - y_true), axis=-1))
optimizer = tf.keras.optimizers.Adam(lr=params['learning_rate'],
clipnorm=1.)
model.compile(optimizer=optimizer,
loss='binary_crossentropy',
metrics=['accuracy', 'mse', rmse])
and the code for the preprocessing function:
def reshape_into_image(features, params):
# stack the inputs to form a 2-channel input
# features['ref'] is [-1, height*width]
# stacked image is [-1, height*width, n_channels]
n_channels = 2
stacked = tf.concat([features['ref'], features['ltg']], axis=1)
height = width = PATCH_SIZE(params)
return tf.reshape(stacked, [height, width, n_channels])
and the serving layer:
# 1. layer that extracts multiple inputs from JSON
height = width = PATCH_SIZE(hparams)
json_input = keras.layers.concatenate([
keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,)),
], axis=0)
# 2. convert json_input to image (what model wants)
to_img = keras.layers.Lambda(
lambda x: reshape_into_image(features=
'ref': tf.reshape(x[0], [height * width, 1]),
'ltg': tf.reshape(x[1], [height * width, 1])
, params=hparams),
name='serving_reshape')(json_input)
# 3. now, use trained model to predict
model_output = model(to_img)
# 4. create serving model
serving_model = keras.Model(json_input, model_output)
python tensorflow machine-learning keras keras-layer
I have a Keras model that I defined during training as:
img = keras.Input(shape=[65, 65, 2])
bnorm = keras.layers.BatchNormalization()(img)
...
model = keras.Model(img, outputprob)
During serving, though, my inputs come differently. Therefore, I defined an input layer (verifying that the to_img
shape comes out to be also (65, 65, 2)
) and tried to do model composition using:
to_img = keras.layers.Lambda(...)(json_input)
model_output = model(to_img)
serving_model = keras.Model(json_input, model_output)
However, I get this error:
tensorflow.python.framework.errors_impl.InvalidArgumentError:
Shape must be rank 4 but is rank 3 for
'model/batch_normalization/cond/FusedBatchNorm' (op:
'FusedBatchNorm') with input shapes: [65,65,2],
[2], [2], [0], [0].
This seems to indicate the batch-dimension didn't make it through. Why?
EDIT:
Things I have tried:
(1) Explicitly set trainable=False
in all the layers but that didn't seem to make any difference:
model_core = model
for layer in model_core.layers:
layer.trainable = False
model_output = model_core(to_img)
(2) Tried expanding the result of the preproc:
to_img = keras.layers.Lambda(
lambda x : preproc(x))(json_input)
to_img = keras.layers.Lambda(
lambda x : tf.expand_dims(x, axis=0) )(to_img)
This results in an error: AttributeError: 'Model' object has no attribute '_name'
on the line serving_model = keras.Model(json_input, model_output)
(3) Changed the lambda layer to do a map_fn to process the data individually:
to_img = keras.layers.Lambda(
lambda items: K.map_fn(lambda x: preproc, items))(json_input)
This caused a shape error that indicates that the preproc function is getting [65,2] items instead of [65,65,2]. This suggests that the Lambda layer applies the function to examples one at a time.
(4) Here's the full code for the model:
img = keras.Input(shape=[height, width, 2])
# convolutional part of model
cnn = keras.layers.BatchNormalization()(img)
for layer in range(nlayers):
nfilters = nfil * (layer + 1)
cnn = keras.layers.Conv2D(nfilters, (ksize, ksize), padding='same')(cnn)
cnn = keras.layers.Activation('elu')(cnn)
cnn = keras.layers.BatchNormalization()(cnn)
cnn = keras.layers.MaxPooling2D(pool_size=(2, 2))(cnn)
cnn = keras.layers.Flatten()(cnn)
cnn = keras.layers.Dropout(dprob)(cnn)
cnn = keras.layers.Dense(10, activation='relu')(cnn)
# feature engineering part of model
engfeat = keras.layers.Lambda(
lambda x: engineered_features(x, height//2))(img)
# concatenate the two parts
both = keras.layers.concatenate([cnn, engfeat])
ltgprob = keras.layers.Dense(1, activation='sigmoid')(both)
# create a model
model = keras.Model(img, ltgprob)
def rmse(y_true, y_pred):
import tensorflow.keras.backend as K
return K.sqrt(K.mean(K.square(y_pred - y_true), axis=-1))
optimizer = tf.keras.optimizers.Adam(lr=params['learning_rate'],
clipnorm=1.)
model.compile(optimizer=optimizer,
loss='binary_crossentropy',
metrics=['accuracy', 'mse', rmse])
and the code for the preprocessing function:
def reshape_into_image(features, params):
# stack the inputs to form a 2-channel input
# features['ref'] is [-1, height*width]
# stacked image is [-1, height*width, n_channels]
n_channels = 2
stacked = tf.concat([features['ref'], features['ltg']], axis=1)
height = width = PATCH_SIZE(params)
return tf.reshape(stacked, [height, width, n_channels])
and the serving layer:
# 1. layer that extracts multiple inputs from JSON
height = width = PATCH_SIZE(hparams)
json_input = keras.layers.concatenate([
keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,)),
], axis=0)
# 2. convert json_input to image (what model wants)
to_img = keras.layers.Lambda(
lambda x: reshape_into_image(features=
'ref': tf.reshape(x[0], [height * width, 1]),
'ltg': tf.reshape(x[1], [height * width, 1])
, params=hparams),
name='serving_reshape')(json_input)
# 3. now, use trained model to predict
model_output = model(to_img)
# 4. create serving model
serving_model = keras.Model(json_input, model_output)
python tensorflow machine-learning keras keras-layer
python tensorflow machine-learning keras keras-layer
edited Nov 15 '18 at 14:56
Lak
asked Nov 15 '18 at 10:19
LakLak
1,662714
1,662714
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
The input shape of your model, considering the samples axis, is (?, 65, 65, 2)
where ?
can be one or more than one. So you need to modify the Lambda layer (actually the function wrapped inside it) such that its output to be (?, 65, 65, 2)
as well. One way of doing it is to use K.expand_dims(out, axis=0)
in the wrapped function so that the output would have a shape of (1, 65, 65, 2)
.
By the way, K
refers to backend: from keras import backend as K
.
Further, note that you must define the function wrapped by the Lambda such that it preserves the batch axis; otherwise, it is very likely that you are doing something wrong in the definition of that function.
Update:
The error AttributeError: 'Model' object has no attribute '_name'
is raised because you are passing json_input
as the input of the model. However, it is not an input layer. Rather, it is the output of concatenation
layer. To resolve this, first define the input layers and then pass them to concatenation
layer and Model
class, like this:
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
json_input = keras.layers.concatenate(inputs, axis=0)
# ...
serving_model = keras.Model(inputs, model_output)
Update 2:
I think you can write this much more simpler and without going into so much unnecessary trouble. You want to go from two tensors of shape (?, h*w)
to a tensor of shape (?, h, w, 2)
. You can use Reshape
layer, so that would be:
from keras.layers import Reshape
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
reshape_layer = Reshape((height, width, 1))
r_in1 = reshape_layer(inputs[0])
r_in2 = reshape_layer(inputs[1])
img = concatenate([r_in1, r_in2])
output = model(img)
serving_model = keras.Model(inputs, output)
No need for any custom function or Lambda layer.
And by the way, if you are interested to know, the trouble with batch axis removal is caused by this line:
return tf.reshape(stacked, [height, width, n_channels])
You are not considering the batch axis when reshaping.
@Lak As I mentioned it must preserve the batch axis, otherwise that's a sign that you are doing something incorrectly. As for the name error, one possible cause of that is unspecified input shape. Could you please edit your question and add the whole new code with the error you get? Don't remove the previous information, just add your edit at the end.
– today
Nov 15 '18 at 10:52
Thanks for suggestion. I've edited the post with the things I've tried.
– Lak
Nov 15 '18 at 14:41
@Lak Thanks, but I said the whole code, at least the whole model definition; from input layers to constructing theModel
instance. That's because it seems the error is caused by the way you have defined your model and therefore we can't get give you a correct answer if we don't have the code of the whole model and inspect its structure.
– today
Nov 15 '18 at 14:45
added the model too now
– Lak
Nov 15 '18 at 14:56
@Lak Updated my answer. Please take a look.
– today
Nov 15 '18 at 15:24
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53317187%2fbatch-size-dimension-not-honored-when-composing-models%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The input shape of your model, considering the samples axis, is (?, 65, 65, 2)
where ?
can be one or more than one. So you need to modify the Lambda layer (actually the function wrapped inside it) such that its output to be (?, 65, 65, 2)
as well. One way of doing it is to use K.expand_dims(out, axis=0)
in the wrapped function so that the output would have a shape of (1, 65, 65, 2)
.
By the way, K
refers to backend: from keras import backend as K
.
Further, note that you must define the function wrapped by the Lambda such that it preserves the batch axis; otherwise, it is very likely that you are doing something wrong in the definition of that function.
Update:
The error AttributeError: 'Model' object has no attribute '_name'
is raised because you are passing json_input
as the input of the model. However, it is not an input layer. Rather, it is the output of concatenation
layer. To resolve this, first define the input layers and then pass them to concatenation
layer and Model
class, like this:
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
json_input = keras.layers.concatenate(inputs, axis=0)
# ...
serving_model = keras.Model(inputs, model_output)
Update 2:
I think you can write this much more simpler and without going into so much unnecessary trouble. You want to go from two tensors of shape (?, h*w)
to a tensor of shape (?, h, w, 2)
. You can use Reshape
layer, so that would be:
from keras.layers import Reshape
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
reshape_layer = Reshape((height, width, 1))
r_in1 = reshape_layer(inputs[0])
r_in2 = reshape_layer(inputs[1])
img = concatenate([r_in1, r_in2])
output = model(img)
serving_model = keras.Model(inputs, output)
No need for any custom function or Lambda layer.
And by the way, if you are interested to know, the trouble with batch axis removal is caused by this line:
return tf.reshape(stacked, [height, width, n_channels])
You are not considering the batch axis when reshaping.
@Lak As I mentioned it must preserve the batch axis, otherwise that's a sign that you are doing something incorrectly. As for the name error, one possible cause of that is unspecified input shape. Could you please edit your question and add the whole new code with the error you get? Don't remove the previous information, just add your edit at the end.
– today
Nov 15 '18 at 10:52
Thanks for suggestion. I've edited the post with the things I've tried.
– Lak
Nov 15 '18 at 14:41
@Lak Thanks, but I said the whole code, at least the whole model definition; from input layers to constructing theModel
instance. That's because it seems the error is caused by the way you have defined your model and therefore we can't get give you a correct answer if we don't have the code of the whole model and inspect its structure.
– today
Nov 15 '18 at 14:45
added the model too now
– Lak
Nov 15 '18 at 14:56
@Lak Updated my answer. Please take a look.
– today
Nov 15 '18 at 15:24
|
show 1 more comment
The input shape of your model, considering the samples axis, is (?, 65, 65, 2)
where ?
can be one or more than one. So you need to modify the Lambda layer (actually the function wrapped inside it) such that its output to be (?, 65, 65, 2)
as well. One way of doing it is to use K.expand_dims(out, axis=0)
in the wrapped function so that the output would have a shape of (1, 65, 65, 2)
.
By the way, K
refers to backend: from keras import backend as K
.
Further, note that you must define the function wrapped by the Lambda such that it preserves the batch axis; otherwise, it is very likely that you are doing something wrong in the definition of that function.
Update:
The error AttributeError: 'Model' object has no attribute '_name'
is raised because you are passing json_input
as the input of the model. However, it is not an input layer. Rather, it is the output of concatenation
layer. To resolve this, first define the input layers and then pass them to concatenation
layer and Model
class, like this:
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
json_input = keras.layers.concatenate(inputs, axis=0)
# ...
serving_model = keras.Model(inputs, model_output)
Update 2:
I think you can write this much more simpler and without going into so much unnecessary trouble. You want to go from two tensors of shape (?, h*w)
to a tensor of shape (?, h, w, 2)
. You can use Reshape
layer, so that would be:
from keras.layers import Reshape
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
reshape_layer = Reshape((height, width, 1))
r_in1 = reshape_layer(inputs[0])
r_in2 = reshape_layer(inputs[1])
img = concatenate([r_in1, r_in2])
output = model(img)
serving_model = keras.Model(inputs, output)
No need for any custom function or Lambda layer.
And by the way, if you are interested to know, the trouble with batch axis removal is caused by this line:
return tf.reshape(stacked, [height, width, n_channels])
You are not considering the batch axis when reshaping.
@Lak As I mentioned it must preserve the batch axis, otherwise that's a sign that you are doing something incorrectly. As for the name error, one possible cause of that is unspecified input shape. Could you please edit your question and add the whole new code with the error you get? Don't remove the previous information, just add your edit at the end.
– today
Nov 15 '18 at 10:52
Thanks for suggestion. I've edited the post with the things I've tried.
– Lak
Nov 15 '18 at 14:41
@Lak Thanks, but I said the whole code, at least the whole model definition; from input layers to constructing theModel
instance. That's because it seems the error is caused by the way you have defined your model and therefore we can't get give you a correct answer if we don't have the code of the whole model and inspect its structure.
– today
Nov 15 '18 at 14:45
added the model too now
– Lak
Nov 15 '18 at 14:56
@Lak Updated my answer. Please take a look.
– today
Nov 15 '18 at 15:24
|
show 1 more comment
The input shape of your model, considering the samples axis, is (?, 65, 65, 2)
where ?
can be one or more than one. So you need to modify the Lambda layer (actually the function wrapped inside it) such that its output to be (?, 65, 65, 2)
as well. One way of doing it is to use K.expand_dims(out, axis=0)
in the wrapped function so that the output would have a shape of (1, 65, 65, 2)
.
By the way, K
refers to backend: from keras import backend as K
.
Further, note that you must define the function wrapped by the Lambda such that it preserves the batch axis; otherwise, it is very likely that you are doing something wrong in the definition of that function.
Update:
The error AttributeError: 'Model' object has no attribute '_name'
is raised because you are passing json_input
as the input of the model. However, it is not an input layer. Rather, it is the output of concatenation
layer. To resolve this, first define the input layers and then pass them to concatenation
layer and Model
class, like this:
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
json_input = keras.layers.concatenate(inputs, axis=0)
# ...
serving_model = keras.Model(inputs, model_output)
Update 2:
I think you can write this much more simpler and without going into so much unnecessary trouble. You want to go from two tensors of shape (?, h*w)
to a tensor of shape (?, h, w, 2)
. You can use Reshape
layer, so that would be:
from keras.layers import Reshape
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
reshape_layer = Reshape((height, width, 1))
r_in1 = reshape_layer(inputs[0])
r_in2 = reshape_layer(inputs[1])
img = concatenate([r_in1, r_in2])
output = model(img)
serving_model = keras.Model(inputs, output)
No need for any custom function or Lambda layer.
And by the way, if you are interested to know, the trouble with batch axis removal is caused by this line:
return tf.reshape(stacked, [height, width, n_channels])
You are not considering the batch axis when reshaping.
The input shape of your model, considering the samples axis, is (?, 65, 65, 2)
where ?
can be one or more than one. So you need to modify the Lambda layer (actually the function wrapped inside it) such that its output to be (?, 65, 65, 2)
as well. One way of doing it is to use K.expand_dims(out, axis=0)
in the wrapped function so that the output would have a shape of (1, 65, 65, 2)
.
By the way, K
refers to backend: from keras import backend as K
.
Further, note that you must define the function wrapped by the Lambda such that it preserves the batch axis; otherwise, it is very likely that you are doing something wrong in the definition of that function.
Update:
The error AttributeError: 'Model' object has no attribute '_name'
is raised because you are passing json_input
as the input of the model. However, it is not an input layer. Rather, it is the output of concatenation
layer. To resolve this, first define the input layers and then pass them to concatenation
layer and Model
class, like this:
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
json_input = keras.layers.concatenate(inputs, axis=0)
# ...
serving_model = keras.Model(inputs, model_output)
Update 2:
I think you can write this much more simpler and without going into so much unnecessary trouble. You want to go from two tensors of shape (?, h*w)
to a tensor of shape (?, h, w, 2)
. You can use Reshape
layer, so that would be:
from keras.layers import Reshape
inputs = [keras.layers.Input(name='ref', dtype=tf.float32, shape=(height * width,)),
keras.layers.Input(name='ltg', dtype=tf.float32, shape=(height * width,))]
reshape_layer = Reshape((height, width, 1))
r_in1 = reshape_layer(inputs[0])
r_in2 = reshape_layer(inputs[1])
img = concatenate([r_in1, r_in2])
output = model(img)
serving_model = keras.Model(inputs, output)
No need for any custom function or Lambda layer.
And by the way, if you are interested to know, the trouble with batch axis removal is caused by this line:
return tf.reshape(stacked, [height, width, n_channels])
You are not considering the batch axis when reshaping.
edited Nov 15 '18 at 15:50
answered Nov 15 '18 at 10:25
todaytoday
11.2k22139
11.2k22139
@Lak As I mentioned it must preserve the batch axis, otherwise that's a sign that you are doing something incorrectly. As for the name error, one possible cause of that is unspecified input shape. Could you please edit your question and add the whole new code with the error you get? Don't remove the previous information, just add your edit at the end.
– today
Nov 15 '18 at 10:52
Thanks for suggestion. I've edited the post with the things I've tried.
– Lak
Nov 15 '18 at 14:41
@Lak Thanks, but I said the whole code, at least the whole model definition; from input layers to constructing theModel
instance. That's because it seems the error is caused by the way you have defined your model and therefore we can't get give you a correct answer if we don't have the code of the whole model and inspect its structure.
– today
Nov 15 '18 at 14:45
added the model too now
– Lak
Nov 15 '18 at 14:56
@Lak Updated my answer. Please take a look.
– today
Nov 15 '18 at 15:24
|
show 1 more comment
@Lak As I mentioned it must preserve the batch axis, otherwise that's a sign that you are doing something incorrectly. As for the name error, one possible cause of that is unspecified input shape. Could you please edit your question and add the whole new code with the error you get? Don't remove the previous information, just add your edit at the end.
– today
Nov 15 '18 at 10:52
Thanks for suggestion. I've edited the post with the things I've tried.
– Lak
Nov 15 '18 at 14:41
@Lak Thanks, but I said the whole code, at least the whole model definition; from input layers to constructing theModel
instance. That's because it seems the error is caused by the way you have defined your model and therefore we can't get give you a correct answer if we don't have the code of the whole model and inspect its structure.
– today
Nov 15 '18 at 14:45
added the model too now
– Lak
Nov 15 '18 at 14:56
@Lak Updated my answer. Please take a look.
– today
Nov 15 '18 at 15:24
@Lak As I mentioned it must preserve the batch axis, otherwise that's a sign that you are doing something incorrectly. As for the name error, one possible cause of that is unspecified input shape. Could you please edit your question and add the whole new code with the error you get? Don't remove the previous information, just add your edit at the end.
– today
Nov 15 '18 at 10:52
@Lak As I mentioned it must preserve the batch axis, otherwise that's a sign that you are doing something incorrectly. As for the name error, one possible cause of that is unspecified input shape. Could you please edit your question and add the whole new code with the error you get? Don't remove the previous information, just add your edit at the end.
– today
Nov 15 '18 at 10:52
Thanks for suggestion. I've edited the post with the things I've tried.
– Lak
Nov 15 '18 at 14:41
Thanks for suggestion. I've edited the post with the things I've tried.
– Lak
Nov 15 '18 at 14:41
@Lak Thanks, but I said the whole code, at least the whole model definition; from input layers to constructing the
Model
instance. That's because it seems the error is caused by the way you have defined your model and therefore we can't get give you a correct answer if we don't have the code of the whole model and inspect its structure.– today
Nov 15 '18 at 14:45
@Lak Thanks, but I said the whole code, at least the whole model definition; from input layers to constructing the
Model
instance. That's because it seems the error is caused by the way you have defined your model and therefore we can't get give you a correct answer if we don't have the code of the whole model and inspect its structure.– today
Nov 15 '18 at 14:45
added the model too now
– Lak
Nov 15 '18 at 14:56
added the model too now
– Lak
Nov 15 '18 at 14:56
@Lak Updated my answer. Please take a look.
– today
Nov 15 '18 at 15:24
@Lak Updated my answer. Please take a look.
– today
Nov 15 '18 at 15:24
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53317187%2fbatch-size-dimension-not-honored-when-composing-models%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown