Reputation: 31
Hi guys I need help with this. was trying to modify pix2pix with some costume fusion blocks got this error after training.
ValueError: Model <_main.Pix2pix object at 0x7f03ac4a0640> cannot be saved either because the input shape is not available or because the forward pass of the model is not defined.To define a forward pass, please override Model.call()
. To specify an input shape, either call build(input_shape)
directly, or call the model on actual data using Model()
, Model.fit()
, or Model.predict()
. If you have a custom training step, please make sure to invoke the forward pass in train step through Model.call_
, i.e. model(inputs)
, as opposed to model.call()
.
import tensorflow as tf
from tensorflow.keras.layers import Layer
from tensorflow.keras import Model
from ssim2dmodule import similarityattention2d
from attention_module import SSCblockaddall
#act_fn3 = tf.keras.activations.tanh() #tf.ReLU()
class encode_block(tf.keras.layers.Layer):
def __init__(self, filter_num, BatchNorm2d=True):
super(encode_block, self).__init__()
self.init = tf.keras.initializers.RandomNormal(stddev=0.02)
self.act_fn =tf.keras.layers.LeakyReLU(0.2)
self.conv = tf.keras.layers.Conv2D(filter_num, kernel_size=4,
strides=2, padding='same', kernel_initializer=self.init)
self.BatchNorm2d =None
if BatchNorm2d:
self.BatchNorm2d = tf.keras.layers.BatchNormalization()
def call(self,x):
x = self.conv(x)
if self.BatchNorm2d != None:
x = self.BatchNorm2d(x, training=True)
x = self.act_fn(x)
return x
class decode_block(tf.keras.layers.Layer):
def __init__(self, filter_num, dropout2d=True):
super(decode_block, self).__init__()
self.init = tf.keras.initializers.RandomNormal(stddev=0.02)
self.act_fn =tf.keras.layers.ReLU(0.2)
self.concat = tf.keras.layers.Concatenate()
self.BatchNorm2d = tf.keras.layers.BatchNormalization()
self.conv = tf.keras.layers.Conv2DTranspose(filter_num, kernel_size=4,
strides=2, padding='same', kernel_initializer=self.init)
self.dropout2d = None
if dropout2d:
self.dropout2d = tf.keras.layers.Dropout(0.5)
def call(self,x,concat_in):
x = self.concat([x, concat_in])
x = self.conv(x)
x = self.BatchNorm2d(x, training=True)
if self.dropout2d != None:
x = self.dropout2d(x, training=True)
x = self.act_fn(x)
return x
class bottleneck(tf.keras.layers.Layer):
def __init__(self, filter_num):
super(bottleneck, self).__init__()
self.init = tf.keras.initializers.RandomNormal(stddev=0.02)
self.act_fn =tf.keras.layers.ReLU(0.2)
self.conv = tf.keras.layers.Conv2D(filter_num, kernel_size=4,
strides=2, padding='same', kernel_initializer=self.init)
self.dconv = tf.keras.layers.Conv2DTranspose(filter_num, kernel_size=4,
strides=2, padding='same', kernel_initializer=self.init)
def call(self,x):
x = self.conv(x)
x = self.act_fn(x)
x = self.dconv(x)
x = self.act_fn(x)
return x
class final_layer(tf.keras.layers.Layer):
def __init__(self):
super(final_layer, self).__init__()
self.init = tf.keras.initializers.RandomNormal(stddev=0.02)
self.concat = tf.keras.layers.Concatenate()
self.conv = tf.keras.layers.Conv2DTranspose(3, kernel_size=4,
strides=2, padding='same', kernel_initializer=self.init)
def call(self,x, concat_in):
x = self.concat([x, concat_in])
x = self.conv(x)
x = tf.keras.activations.tanh(x)
return x
class MixedFusion_Block0(tf.keras.layers.Layer):
def __init__(self, inputs1, inputs2, filter_num):
super(MixedFusion_Block0, self).__init__()
self.input1 = inputs1
self.input2 = inputs2
self.filter_num = filter_num
self.ssim2d = similarityattention2d(inputs1, inputs2)
self.encode = encode_block(filter_num, BatchNorm2d=False)
def call(self, x1, x2):
# multi-style fusion
ssim2d_out = self.ssim2d(x1,x2)
encode_out = self.encode(ssim2d_out)
print(encode_out.shape)
if not encode_out.get_shape()[1:] == (self.filter_num*2, self.filter_num*2, self.filter_num):
encode_out = tf.keras.layers.Reshape((self.filter_num*2, self.filter_num*2, self.filter_num))(encode_out) #(tf.squeeze(encode_out, axis=[0]))
return encode_out
class MixedFusion_Block1(tf.keras.layers.Layer):
def __init__(self, x, filter_num): #SSCblockaddall, SSCblocksam1dlast, SSCblocksamlast, SSCblockcamlast, SSCblockparallel, SSCblockRandom
super(MixedFusion_Block1, self).__init__()
self.filter_num = filter_num
self.block_name = SSCblockaddall()
self.encode = encode_block(filter_num)
def call(self, x1, x2, x3):
y1 = self.block_name(x1)
y2 = self.block_name(x2)
y = tf.concat([y1, y2, x3], 3)
encode_out = self.encode(y)
print(encode_out.shape)
return encode_out
class generator(Model):
def __init__(self, input_nc, layer_out, filter_num):
super(generator,self).__init__()
self.filters = filter_num
self.in_dim = input_nc
self.layer_out = layer_out
# ~~~ Encoding Paths ~~~~~~ #
# Encoder (Modality 1)
#######################################################################
# Encoder **Modality 1
#######################################################################
self.encode_1_0 = encode_block(self.filters*1, BatchNorm2d=False)
self.encode_2_0 = encode_block(self.filters*2)
self.encode_3_0 = encode_block(self.filters*4)
self.encode_4_0 = encode_block(self.filters*8)
self.encode_5_0 = encode_block(self.filters*8)
self.encode_6_0 = encode_block(self.filters*8)
self.encode_7_0 = encode_block(self.filters*8)
#self.encode_8_0 = encode_block(self.filters*8)
#######################################################################
# Encoder **Modality 2
#######################################################################
self.encode_1_1 = encode_block(self.filters, BatchNorm2d=False)
self.encode_2_1 = encode_block(self.filters*2)
self.encode_3_1 = encode_block(self.filters*4)
self.encode_4_1 = encode_block(self.filters*8)
self.encode_5_1 = encode_block(self.filters*8)
self.encode_6_1 = encode_block(self.filters*8)
self.encode_7_1 = encode_block(self.filters*8)
#self.encode_8_1 = encode_block(self.filters*8)
#######################################################################
# fusion block
#######################################################################
# --- fusion encoder
self.fu_encoder_1 = MixedFusion_Block0(self.in_dim, self.in_dim, self.filters)
self.fu_encoder_2 = MixedFusion_Block1(self.layer_out, self.filters*2)
self.fu_encoder_3 = MixedFusion_Block1(self.layer_out*2, self.filters*4)
self.fu_encoder_4 = MixedFusion_Block1(self.layer_out*4, self.filters*8)
self.fu_encoder_5 = MixedFusion_Block1(self.layer_out*8, self.filters*8)
self.fu_encoder_6 = MixedFusion_Block1(self.layer_out*8, self.filters*8)
self.fu_encoder_7 = MixedFusion_Block1(self.layer_out*8, self.filters*8)
#self.fu_encoder_8 = MixedFusion_Block1(self.layer_out*8, self.filters*8)
# bottleneck layer
self.bottleneck = bottleneck(self.filters*8)
# ~~~ Decoding Path ~~~~~~ #
self.decod_1_0 = decode_block(self.filters*8)
self.decod_2_0 = decode_block(self.filters*8)
self.decod_3_0 = decode_block(self.filters*8)
self.decod_4_0 = decode_block(self.filters*4, dropout2d=False)
self.decod_5_0 = decode_block(self.filters*2, dropout2d=False)
self.decod_6_0 = decode_block(self.filters*1, dropout2d=False)
self.out = final_layer()
def call(self,x,y):
# ##############################
# ----- First Level --------
encoder_1_0 = self.encode_1_0(x) #(256, 256, input_size[-1])
encoder_1_1 = self.encode_1_1(y)
# ----- Second Level --------
encoder_2_0 = self.encode_2_0(encoder_1_0) # (128, 128, 64)
encoder_2_1 = self.encode_2_1(encoder_1_1)
# ----- Third Level --------
encoder_3_0 = self.encode_3_0(encoder_2_0) # (64, 64, 128)
encoder_3_1 = self.encode_3_1(encoder_2_1)
# ----- Fourth Level --------
encoder_4_0 = self.encode_4_0(encoder_3_0) # (32, 32, 256)
encoder_4_1 = self.encode_4_1(encoder_3_1)
# ----- Five Level --------
encoder_5_0 = self.encode_5_0(encoder_4_0) # (16, 16, 512)
encoder_5_1 = self.encode_5_1(encoder_4_1)
# ----- sixth Level --------
encoder_6_0 = self.encode_6_0(encoder_5_0) # (8, 8, 512)
encoder_6_1 = self.encode_6_1(encoder_5_1)
# ----- seventh Level --------
encoder_7_0 = self.encode_7_0(encoder_6_0) # (4, 4, 512)
encoder_7_1 = self.encode_7_1(encoder_6_1)
# ----------------------------------------
# fusion block -- f_block
f_block_1 = self.encode_1_0(z) #self.fu_encoder_1(x,y)
f_block_2 = self.fu_encoder_2(encoder_1_0, encoder_1_1, f_block_1)
f_block_3 = self.fu_encoder_3(encoder_2_0, encoder_2_1, f_block_2)
f_block_4 = self.fu_encoder_4(encoder_3_0, encoder_3_1, f_block_3)
f_block_5 = self.fu_encoder_5(encoder_4_0, encoder_4_1, f_block_4)
f_block_6 = self.fu_encoder_6(encoder_5_0, encoder_5_1, f_block_5)
f_block_7 = self.fu_encoder_7(encoder_6_0, encoder_6_1, f_block_6)
#f_block_8 = self.fu_encoder_8(encoder_7_0, encoder_7_1, f_block_7)
#f_block_9 = self.fu_encoder_9(encoder_8_0, encoder_8_1, f_block_8)
#######################################################################
# ~~~~~~ Bottleneck
btlnck = self.bottleneck(f_block_7) # (1 x 1 x 512) and # (2 x 2 x 512)
print(btlnck.shape)
#######################################################################
# ~~~~~~ Decoding
decoder_1_0 = self.decod_1_0 (btlnck,f_block_7) # (4, 4, 512)
decoder_2_0 = self.decod_2_0(decoder_1_0,f_block_6) # (8, 8, 512)
decoder_3_0 = self.decod_3_0(decoder_2_0,f_block_5) # (16, 16, 512)
decoder_4_0 = self.decod_4_0(decoder_3_0,f_block_4) # (32, 32, 256)
decoder_5_0 = self.decod_5_0(decoder_4_0,f_block_3) # (64, 64, 128)
decoder_6_0 = self.decod_6_0(decoder_5_0,f_block_2) # (128, 128, 64)
decod_out = self.out(decoder_6_0, f_block_1) # (256, 256, output_channels)
# get three channels
return decod_out
class adversary(Model):
def __init__(self,filter_num):
super(adversary,self).__init__()
self.filters = filter_num
self.init = tf.keras.initializers.RandomNormal(stddev=0.02)
self.last = tf.keras.layers.Conv2D(1, (4,4), padding='same', kernel_initializer = self.init,
activation=tf.keras.activations.sigmoid)
self.conv_1 = encode_block(self.filters*1)
self.conv_2 = encode_block(self.filters*2)
self.conv_3 = encode_block(self.filters*4)
self.conv_4 = encode_block(self.filters*8)
self.conv_5 = encode_block(self.filters*8)
self.conv_6 = encode_block(self.filters*8)
def call(self,x,y):
adv_1 = tf.keras.layers.concatenate([x, y]) # (256, 256, real_channels+fake_channels)
adv_2 = self.conv_1(adv_1) # (128, 128, 64)
adv_3 = self.conv_2(adv_2) # (64, 64, 128)
adv_4 = self.conv_3(adv_3) # (32, 32, 256)
adv_5 = self.conv_4(adv_4) # (16, 16, 512)
adv_6 = self.conv_5(adv_5) #(8, 8, 512)
adv_7 = self.conv_6(adv_6) #(4, 4, 512)
adv_8 = self.last(adv_7) #(4, 4, 1)
return adv_8
Upvotes: 3
Views: 4408
Reputation: 176
I encountered this error when I tried to save a custom model just after it had been created. The problem was not in the model itself, but with the use of it. The clue is presented in the message of the error. I needed to add a forward pass before saving, so that Tensorflow can deduce the shape. In my case it was fit
before saving.
model.compile(loss=tf.keras.losses.MeanSquaredError(),
metrics=[tf.keras.metrics.MeanAbsoluteError()])
model.fit(self.window.train, epochs=1,
validation_data=self.window.val)
model.save('custom_model')
Upvotes: 1