Keras ValueError : the Dens' input dimension should be defined - python

I'm trying to use VGG16 with some modification on it. I followed this blog post from keras.io
Here the code I'm using to create the model:
def create_model():
vgg16_model = vgg16.VGG16(weights='imagenet', include_top=False)
print('[INFO] Model loaded.')
x = vgg16_model.output
x = Flatten()(x)
x = Dense(256, activation="relu")(x)
x = Dropout(0.5)(x)
x = Dense(1, activation='linear')(x)
model = Model(inputs=vgg16_model.inputs, outputs=x)
return model
Calling the model = create_model() gives an error:
ValueError: The last dimension of the inputs to Dense should be defined. Found None.
What could be the problem?

try to pass an input_shape when you use the vgg16.VGG16
def create_model():
vgg16_model = vgg16.VGG16(input_shape=(224,224,3), weights='imagenet', include_top=False)
print('[INFO] Model loaded.')
x = vgg16_model.output
x = Flatten()(x)
x = Dense(256, activation="relu")(x)
x = Dropout(0.5)(x)
x = Dense(1, activation='linear')(x)
model = Model(inputs=vgg16_model.inputs, outputs=x)
return model

Related

How To combine Resnet and LSTM model

I want to combine Resnet and LSTM model, but here I got some problem such Input 0 of layer "lstm_7" is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: (None, 64). How to solve the problem.
here the code for combining the model
def identity_block(input_tensor,units):
x = layers.Dense(units)(input_tensor)
x = layers.Activation('relu')(x)
x = layers.Dense(units)(x)
x = layers.Activation('relu')(x)
x = layers.Dense(units)(x)
x = layers.add([x, input_tensor])
x = layers.Activation('relu')(x)
return x
`def dens_block(input_tensor,units):
x = layers.Dense(units)(input_tensor)
x = layers.Activation('relu')(x)
x = layers.Dense(units)(x)
x = layers.Activation('relu')(x)
x = layers.Dense(units)(x)
shortcut = layers.Dense(units)(input_tensor)
x = layers.add([x, shortcut])
x = layers.Activation('relu')(x)
return x`
def ResNet50Regression():
"""Instantiates the ResNet50 architecture.
# Arguments
input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
to use as input for the model.
# Returns
A Keras model instance.
"""
Res_input = layers.Input(shape=(89,))
width = 64
x = dens_block(Res_input,width)
x = identity_block(x,width)
x = identity_block(x,width)
x = dens_block(x,width)
x = identity_block(x,width)
x = identity_block(x,width)
x = dens_block(x,width)
x = identity_block(x,width)
x = identity_block(x,width)
# x = layers.BatchNormalization()(x)
# x = layers.Dense(3)(x)
model = models.Model(inputs=Res_input, outputs=x)
return model
model1 = ResNet50Regression()
model = Sequential()
model.add(model1)
model.add(LSTM(64,activation='relu', return_sequences= False))
model.add(Dense(512,activation='relu'))
model.add(Dense(128,activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss = 'mse', optimizer=Adam(learning_rate=0.002), metrics=['mse'])
model.summary()

Keras model convert into pytorch

def network():
inputs = Input(name='inputs', shape=[51, ])
layer1 = Dense(2048)(inputs)
layer1 = BatchNormalization(name='BC11')(layer1)
layer1 = Activation('relu', name='Act11')(layer1)
layer2 = Dense(1024, name='FC1')(layer1)
layer2 = BatchNormalization(name='BC1')(layer2)
layer2 = Activation('relu', name='Act1')(layer2)
layer_shortcut1 = Dense(1024, activation='relu')(inputs)
layer_shortcut1 = BatchNormalization(name='BCshortcut1')(layer_shortcut1)
layer2 = Add()([layer2, layer_shortcut1])
merge1 = concatenate([layer1, layer2])
layer3 = Dense(512, name='FC3')(merge1)
layer3 = BatchNormalization(name='BC3')(layer3)
layer3 = Activation('relu', name='Act3')(layer3)
layer4 = Dense(256, name='FC5')(layer3)
layer4 = BatchNormalization(name='BC5')(layer4)
layer4= Activation('relu', name='Act5')(layer4)
layer_shortcut2 = Dense(256, activation='relu')(layer2)
layer_shortcut2 = BatchNormalization(name='BCshortcut2')(layer_shortcut2)
layer4 = Add()([layer4, layer_shortcut2])
merge2 = concatenate([layer3, layer4])
layer5 = Dense(128, name='FC7')(merge2)
layer5 = BatchNormalization(name='BC7')(layer5)
layer5 = Activation('relu', name='Act7')(layer5)
layer6 = Dense(64, name='FC8')(layer5)
layer6 = BatchNormalization(name='BC8')(layer6)
layer6 = Activation('relu', name='Act8')(layer6)
layer_shortcut3 = Dense(64, activation='relu')(layer4)
layer_shortcut3 = BatchNormalization(name='BCshortcut')(layer_shortcut3)
layer6 = Add()([layer6, layer_shortcut3])
merge3 = concatenate([layer5, layer6])
layer7 = Dense(32, name='FC9')(merge3)
layer7 = BatchNormalization(name='BC9')(layer7)
layer7 = Activation('relu', name='Act9')(layer7)
layer8 = Dense(16, name='FC0')(layer7)
layer8 = BatchNormalization(name='BC0')(layer8)
layer8 = Activation('relu', name='Act0')(layer8)
out0 = Dense(12, activation='sigmoid', name='Out0')(merge2)
out1 = Dense(12, activation='sigmoid', name='Out1')(merge3)
out2 = Dense(12, activation='sigmoid', name='Out2')(layer8)
model = Model(inputs=inputs, outputs=[out0,out1,out2])
return model
I am new in pytorch. Could someone help me to convert this into pytorch? I have seen How can I convert this keras cnn model to pytorch version but meet the dimension issues. Many thanks!
From this stack overflow answer. Forward your upvotes to the OG.
You can save keras weight and reload them in pytorch. the steps are
Step 0: Train a Model in Keras. ...
Step 1: Recreate & Initialize Your Model Architecture in PyTorch. ...
Step 2: Import Your Keras Model and Copy the Weights. ...
Step 3: Load Those Weights onto Your PyTorch Model. ...
Step 4: Test and Save Your Pytorch Model.
You Can follow example here https://gereshes.com/2019/06/24/how-to-transfer-a-simple-keras-model-to-pytorch-the-hard-way/

Tensorflow 2.0 Model subclassing

I made this function that incorporates a resnet into a model. It works well, and I can save it.
My problem is that I can't load it because it needs a call function. I am not exactly sure of how to turn this into a class. The attempt is at the bottom. some pointers would be helpful.
def build_network():
inp = Input(shape=(256,256,3))
resnet = tf.keras.applications.ResNet152V2(
include_top=False, weights='imagenet', input_tensor=None,
input_shape=(256,256,3), pooling=None, classes=1000
)
# classifier_activation='softmax'
x = resnet(inp)
x = GlobalAveragePooling2D()(x)
x = Dropout(0.3)(x)
x = Dense(9, activation='softmax')(x)
model = tf.keras.Model(inputs=inp,outputs = x)
opt = tf.keras.optimizers.SGD(momentum=0.9)
# optimizer = 'adam',
model.compile(loss='categorical_crossentropy',
optimizer = opt,
metrics=['accuracy'])
model.summary()
return model
class Resnet(tf.keras.Model):
def __init__(self, num_classes=9):
super(Resnet, self).__init__()
self.block_1 = tf.keras.applications.ResNet152V2(
include_top=False, weights='imagenet', input_tensor=None,
input_shape=(256,256,3), pooling=None, classes=1000)
self.global_pool = layers.GlobalAveragePooling2D()
self.dropout = Dropout(0.3)
self.classifier = Dense(num_classes, activation = 'softmax')
def call(self, inputs):
x = self.block_1(inputs)
x = self.global_pool(x)
x = self.dropout(x)
x = self.classifier(x)
return tf.keras.Model(inputs = inputs, outputs = x)
Using the subclassing API will actually make your model unserializable (see the "Limitations section in the "What are Symbolic and Imperative APIs in TensorFlow 2.0? " blogpost):
Imperative models are also more difficult to inspect, copy, or clone.
For example, model.save(), model.get_config(), and clone_model do not work for subclassed models. Likewise, model.summary() only gives you a list of layers (and doesn’t provide information on how they’re connected, since that’s not accessible).
Edit: From Tensorflow 2.4, it is possible to pass a save_traces argument to model.save to serialize models built using the subclassing API. See https://www.tensorflow.org/guide/keras/save_and_serialize#how_savedmodel_handles_custom_objects.
Here's a simple example of how you can do this:
import tensorflow as tf
from tensorflow.keras.layers import (Dense, Dropout, GlobalAveragePooling2D,
Input)
def build_network():
inp = Input(shape=(256, 256, 3))
resnet = tf.keras.applications.ResNet152V2(include_top=False,
weights="imagenet",
input_tensor=None,
input_shape=(256, 256, 3),
pooling=None,
classes=1000)
# classifier_activation="softmax"
x = resnet(inp)
x = GlobalAveragePooling2D()(x)
x = Dropout(0.3)(x)
x = Dense(9, activation="softmax")(x)
model = tf.keras.Model(inputs=inp, outputs=x)
# optimizer = "adam",
opt = tf.keras.optimizers.SGD(momentum=0.9)
model.compile(loss="categorical_crossentropy",
optimizer=opt,
metrics=["accuracy"])
model.summary()
return model
if __name__ == "__main__":
model = build_network()
model.summary()
# Save
model.save("my_model.h5")
# Load
loaded_model = tf.keras.models.load_model("my_model.h5")
loaded_model.summary()
To load your saved model from your build_network function use tf.keras.models.load_model.

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

I keep getting the error TypeError: 'Tensor' object is not callable

global_average_layer = keras.layers.GlobalAveragePooling2D()
feature_batch_average = global_average_layer(feature_batch)
print(feature_batch_average.shape)
flatten = keras.layers.Flatten()(base_model.layers[-1].output)
dense1 = keras.layers.Dense(256, activation = "relu")(flatten)
prediction_layer = keras.layers.Dense(3, activation = "softmax")(dense1)
x = base_model(inputs, training=False)
x = global_average_layer(x)
x = keras.layers.Dropout(0.5)(x)
outputs = prediction_layer(x)
model = keras.Model(inputs, outputs)
model.summary()
I keep getting TypeError: 'Tensor' object is not callable at the line outputs = prediction_layer(x). Any clue what I may be doing wrong?
Edit:
Added a few more lines to make it clear what I am doing
base_model = keras.applications.DenseNet121(input_shape=IMG_SHAPE,
include_top=False,
weights='imagenet')
image_batch, label_batch = next(iter(train_dataset))
feature_batch = base_model(image_batch)
global_average_layer = keras.layers.GlobalAveragePooling2D()
feature_batch_average = global_average_layer(feature_batch)
print(feature_batch_average.shape)
flatten = keras.layers.Flatten()(base_model.layers[-1].output)
dense1 = keras.layers.Dense(256, activation = "relu")(flatten)
prediction_layer = keras.layers.Dense(3, activation = "softmax")(dense1)
x = base_model(inputs, training=False)
x = global_average_layer(x)
x = keras.layers.Dropout(0.5)(x)
outputs = prediction_layer(x)
model = keras.Model(inputs, outputs)
model.summary()
prediction_layer, as mentioned on line 5, would be the output of the Dense layer, and hence be just a Tensor and not a layer.
You do not require the flatten layer on base_model.layers[-1].output, and can just do it on x.

Categories

Resources