How add tf.keras.Input in a custom keras model? - python

I'm writting a custom keras model here is my code:
class Model(tf.keras.Model):
def __init__(self, first_layer, num_classes):
super(Model, self).__init__()
self.layer_1 = tf.keras.layers.Dense(first_layer, activation='relu')
self.layer_2 = tf.keras.layers.Dense(num_classes, activation='softmax')
def call(self,inp):
output = self.layer_1(inp)
output = self.layer_2(output)
return output
but I get this error:
ValueError: The last dimension of the inputs to `Dense` should be defined. Found `None`.
I found the tf.keras.input, but all the examples with that are with sequential models for example with a sequential model this is the solution with keras.input:
encoder_input = keras.Input(shape=(28, 28, 1), name="img")
x = layers.Conv2D(16, 3, activation="relu")(encoder_input)
x = layers.Conv2D(32, 3, activation="relu")(x)
but how I introduce this in a custom keras model?
please

version: TF 2.6
Edited code:
import tensorflow as tf
class Model(tf.keras.Model):
def __init__(self, first_layer, num_classes):
super(Model, self).__init__()
self.layer_1 = tf.keras.layers.Dense(first_layer, activation='relu')
self.layer_2 = tf.keras.layers.Dense(num_classes, activation='softmax')
def call(self,inp):
output = self.layer_1(inp)
output = self.layer_2(output)
return output
encoder_input = tf.keras.Input(shape=(28, 28, 1))
x = tf.keras.layers.Conv2D(16, 3, activation="relu")
#x = layers.Conv2D(32, 3, activation="relu")(x)
model = Model(5,3) #instantiated the model
y=model(encoder_input)#took input
print(y)
Output:
KerasTensor(type_spec=TensorSpec(shape=(None, 28, 28, 3),
dtype=tf.float32, name=None), name='model_4/dense_6/Softmax:0',
description="created by layer 'model_4'")
Reference:
https://www.tensorflow.org/guide/keras/custom_layers_and_models

Related

Keras plot_model: How do I write a new block and give it a name

Is there a possibility to create my own block using keras
Maybe something like this:
import tensorflow as tf
class NewLayer(tf.keras.layers.Layer):
def __init__(self):
super(NewLayer, self).__init__()
self.dense1 = tf.keras.layers.Dense(64, activation='relu')
self.dense2 = tf.keras.layers.Dense(16, activation='relu')
self.dense3 = tf.keras.layers.Dense(3)
self._name = 'My_model'
def call(self, inputs):
x = tf.keras.layers.Flatten()(inputs)
x = self.dense1(x)
x = self.dense2(x)
output = self.dense3(x)
return output
inputs = tf.keras.layers.Input((128, 128, 3))
x = tf.keras.layers.Conv2D(256, 67)(inputs)
new_layer = NewLayer()
outputs = new_layer(x)
model = tf.keras.Model(inputs, outputs)
dot_img_file = 'model.png'
tf.keras.utils.plot_model(model, to_file=dot_img_file, show_shapes=True)

how to add layers before transfer learning

I want to add attention layer before transfer learning, something like below, however, in the function create_model_tl I do not suppose to pass x yet, how to write a function to create a model so later on I can call the function to create model myModel = create_model_tl(input_shape, mdl_type, weights) and pass for compile and fit?
def attention(v, k, q, d_model, num_heads, mask):
......
return output
def create_model_tl(input_shape, mdl_type, weights):
print("start creating model - transfer learning ...")
conv_layer = Conv2D(16, kernel_size=(1, 1), activation='relu', input_shape=input_shape)
x = conv_layer(x)
x = attention(x, x, x, 16, 4, None) # k, q, v, d_model, num_heads, mask
base_model = vgg16.VGG16(include_top=False, input_shape=(x.shape[1], x.shape[2], x.shape[3], weights=weights)
flat1 = Flatten()(base_model.layers[-1].output)
class1 = Dense(1024, activation='relu')(flat1)
dropout1 = Dropout(0.2)(class1)
class2 = Dense(512, activation='relu')(dropout1)
dropout2 = Dropout(0.2)(class2)
output = Dense(2, activation='softmax')(dropout2)
#output = Dense(1, activation='sigmoid')(dropout2)
model = Model(inputs=base_model.inputs, outputs=output)
return model

unable to initialize Keras model through subclassing

im trying to create a keras model through subclassing using:
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
self.dense1 = Dense(64, activation='relu')
self.dense2 = Dense(10)
def call(self, inputs):
x = self.dense1(inputs)
return self.dense2(x)
model = MyModel(tf.random.uniform([1, 10]))
model.summary()
I want it to be equal to this squential api:
inputs = tf.keras.Input(shape=(3,))
x = tf.keras.layers.Dense(64, activation=tf.nn.relu)(inputs)
outputs = tf.keras.layers.Dense(10, activation=tf.nn.softmax)(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
but after running those lines i get:
TypeError: __init__() takes 1 positional argument but 2 were given
can u assist?
You passed the input data as arguments to the model constructor. You need to instantiate it
model = MyModel()
Then you can pass input tensors
model(tf.random.uniform([1, 10]))
And this will work
<tf.Tensor: shape=(1, 10), dtype=float32, numpy=
array([[-0.10745259, -0.21291552, -0.04618738, -0.0118152 , -0.1662825 ,
0.8145975 , 0.44216082, -0.07359659, 0.68233466, -0.15205911]],
dtype=float32)>

How can I create keras functional api of multiple inputs and outputs?

The network consist of encoder, lstm and decoder.
The encoder take an input image sequence (TimeDistribution) and extract 2 outputs with different shape.
one use for lstm and pass it to decoder and another one use directly for decoder.
The decoder takes two inputs and output one average image with the same shape with input sequence.
How can I write a keras functional api for this structure?
This is my sample code I have tried:
class CustomEncoder(Architecture):
def __init__(self, inputShape=(128, 128, 1), batchSize=None,
latentSize=1000, training=None):
self.training=training
super().__init__(inputShape, batchSize )
def Build(self):
inLayer = Input(self.inputShape, self.batchSize)
net = Conv2D(64, kernelSize=15, strides=4)(inLayer, training=self.training) #
net = Conv2D(64, kernelSize=11, strides=2)(net, training=self.training)
net = Conv2D(128, kernelSize=7, strides=2)(net, training=self.training)
...
sample = ...
return Model(inputs=inLayer, outputs=[sample, net])
class CustomDecoder(Architecture):
def __init__(self, inputShape=(128, 128, 1), batchSize=None, latentSize=1000, training=None):
self.training=training
super().__init__(inputShape, batchSize, latentSize)
def Build(self):
# input layer is from GlobalAveragePooling:
inLayerA = Input([self.latentSize], self.batchSize)
inLayerB = Input([8, 8, 64], self.batchSize)
neta = Reshape((1, 1, self.latentSize))(inLayerA)
neta = UpSampling2D((self.inputShape[0]//16, self.inputShape[1]//16))(neta)
neta = DeconvBeta(128, kernelSize=7)(neta, training=self.training)
neta = DeconvBeta(64, kernelSize=11)(neta, training=self.training)
neta = DeconvBeta(64, kernelSize=15, strides=4)(neta, training=self.training)
netb = DeconvBeta(128, kernelSize=7)(inLayerB, training=self.training)
netb = DeconvBeta(64, kernelSize=11)(netb, training=self.training)
netb = DeconvBeta(64, kernelSize=15, strides=4)(netb, training=self.training)
neta = Conv2DTranspose(filters=1, kernel_size=15,
padding='same', activation="tanh")(neta)
netb = Conv2DTranspose(filters=1, kernel_size=15,
padding='same', activation="tanh")(netb)
net = Average([neta, netb])
return Model([inLayerA, inLayerB], net)
class ConvLSTMBeta(Architecture):
def __init__(self, inputShape=(None, 8, 8, 64), batchSize=None, latentSize=1000, training=None):
self.training=training
super().__init__(inputShape, batchSize, latentSize)
def Build(self):
# create the input layer for feeding the netowrk
inLayer = Input(self.inputShape, self.batchSize)
net = (ConvLSTM2D(64, (3, 3), padding="same",dropout=0.2, recurrent_dropout=0.2, return_sequences=True))(inLayer) # 1
return Model(inputs=inLayer, outputs=net)

Keras Model from submodeling is not able to compile

I want to use Subclassing/inheritance of the keras Model class. When I want to compile my model it isn't.
I started with keras recently but used a lot of pytorch before.
I currently run tensorflow and keras on version 1.10 and 2.16 respectively and really dont know why I cant compile the model. I tried updating tf to version 1.13 but nothing changed.
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from keras.layers import Input,Conv2D,MaxPooling2D,UpSampling2D,BatchNormalization
from keras import Model, layers
print(tf.VERSION)
print(tf.keras.__version__)
batch_size = 128
epochs = 50
inChannel = 1
img_width, img_height = 64, 64
input_shape = (img_width, img_height, 1)
class AE_64x64(Model):
def __init__(self):
super(AE_64x64, self).__init__()
'''
data_format: channels last
'''
self.conv1 = Conv2D(filters=30, kernel_size=(7,7), activation='relu', padding='same', strides=2)(Input(shape=input_shape))
self.conv2 = Conv2D(filters=40, kernel_size=(5,5), activation='relu', padding='same', strides=2)
self.batchnorm = BatchNormalization(axis=2)
self.max_pool = MaxPooling2D((3,3),padding='same')
self.conv3 = Conv2D(filters=50, kernel_size=(3,3), activation='relu', padding='same', strides=2)
self.conv4 = Conv2D(filters=60, kernel_size=(3,3), activation='relu')
self.b1 = Conv2D(filters=80, kernel_size=(3,3), activation='relu')
self.b2 = Conv2D(filters=99, kernel_size=(3,3), activation='relu')
self.conv6 = Conv2D(filters=50, kernel_size=(3,3), activation='relu')
self.conv7 = Conv2D(filters=40, kernel_size=(3,3), activation='relu')
self.conv8 = Conv2D(filters=30, kernel_size=(3,3), activation='relu')
self.conv9 = Conv2D(filters=1, kernel_size=(3,3), activation='relu')
def call(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.batchnorm(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.max_pool(x)
x = self.batchnorm(x)
x = self.b1(x)
x = self.b2(x)
x = self.batchnorm(x)
x = self.conv5(x)
x = self.conv6(x)
x = self.batchnorm(x)
x = self.conv7(x)
x = self.conv8(x)
x = self.batchnorm(x)
x = self.conv9(x)
return x
AE_Model = AE_64x64()
AE_Model.compile(loss='mean_squared_error',optimizer=tf.train.AdamOptimizer(),metrics= ['mean_squared_error'])
AE_Model.summary()
I expected a summary output but instead I received this error message:
RuntimeError: You must compile your model before using it.
Is there a logical mistake in the code or a Hardware/Version problem?
you at least have to build your model. Or you fit your model with data.
anyway, when I run your code without data I get this result
AE_Model.compile(loss='mean_squared_error',optimizer=tf.train.AdamOptimizer(),metrics= ['mean_squared_error'])
AE_Model.build(input_shape)
AE_Model.summary()
1.13.1
2.2.4-tf
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================

Categories

Resources