Reputation: 147
Is there a way to modify the input dimension of MobileNet. Whenever I change it to my desired input of (150,150,3) it throws an error.
import tensorflow_hub as hub
from tensorflow.keras import Sequential
# from tensorflow.keras import Activations
classifier_url
="https://hub.tensorflow.google.cn/google/tf2-
preview/mobilenet_v2/feature_vector/4"
baseModel = hub.KerasLayer(classifier_url,
input_shape=(150,150,3), output_shape=[1280],
name="Mobilenet")
baseModel.trainable = False # freeze mobilenet
weights
myModel =
Sequential(name="Mobilenet_tranferLearning")
myModel.add(baseModel)
myModel.add(Dropout(0.5))
myModel.add(tf.keras.layers.Activation("relu"))
myModel.add(Dense(102))
myModel.add(tf.keras.layers.Activation("softmax"))
myModel.summary()
ValueError: Exception encountered when calling layer "Mobilenet" (type KerasLayer).
in user code:
File "/usr/local/lib/python3.7/dist-packages/tensorflow_hub/keras_layer.py", line 237, in call *
result = smart_cond.smart_cond(training,
ValueError: Could not find matching concrete function to call loaded from the SavedModel. Got:
Positional arguments (4 total):
* Tensor("inputs:0", shape=(None, 150, 150, 3), dtype=float32)
* False
* False
* 0.99
Keyword arguments: {}
Expected these arguments to match one of the following 4 option(s):
Option 1:
Positional arguments (4 total):
* TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='inputs')
* True
* False
* TensorSpec(shape=(), dtype=tf.float32, name='batch_norm_momentum')
Keyword arguments: {}
Option 2:
Positional arguments (4 total):
* TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='inputs')
* True
* True
* TensorSpec(shape=(), dtype=tf.float32, name='batch_norm_momentum')
Keyword arguments: {}
Option 3:
Positional arguments (4 total):
* TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='inputs')
* False
* True
* TensorSpec(shape=(), dtype=tf.float32, name='batch_norm_momentum')
Keyword arguments: {}
Option 4:
Positional arguments (4 total):
* TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='inputs')
* False
* False
* TensorSpec(shape=(), dtype=tf.float32, name='batch_norm_momentum')
Keyword arguments: {}
Call arguments received: • inputs=tf.Tensor(shape=(None, 150, 150, 3), dtype=float32) • training=False
Upvotes: 0
Views: 1484
Reputation: 8102
Take a look here for info on using MobilenetV2. You are not restricted to 224 X 224 if you set include top=False. Also I advise you set the parameter pooling-'Max' That way MobileNet outputs a vector that you can directly feed into a dense layer. Below is the code I have used for 100's of classification tasks. Normally I use EfficientNetB3 but it works well for MobileNet as well.
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import Dense, Dropout, BatchNormalization
from tensorflow.keras.optimizers import Adam, Adamax
from tensorflow.keras.metrics import categorical_crossentropy
from tensorflow.keras import regularizers
from tensorflow.keras.models import Model, load_model
def make_model(img_img_size, class_count,lr=.001, trainable=True):
img_shape=(img_size[0], img_size[1], 3)
base_model=tf.keras.applications.MobileNet(include_top=False,
weights="imagenet",input_shape=img_shape, pooling='max')
base_model.trainable=trainable
x=base_model.output
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
x = Dense(256, kernel_regularizer = regularizers.l2(l = 0.016),
activity_regularizer = regularizers.l1(0.006),
bias_regularizer = regularizers.l1(0.006) ,activation='relu')(x)
x=Dropout(rate=.45, seed=123)(x)
output=Dense(class_count, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)
model.compile(Adamax(learning_rate=lr), loss='categorical_crossentropy', metrics=['accuracy'])
return model, base_model # return the base_model so you can control its training state
img_size=(150, 150, 3)
class_count= 102 # looks like you have 102 classes
lr = .001
trainable=True # They always tell you to make the base model not trainable.
# Train for a number of epochs than make the base model trainable.
# I find it is better to make the base model trainable from the outset
# It will converge faster and yield a lower validation loss
# for the same number of epochs
model, base_model= make_model(img_img_size, class_count,lr=lr, trainable=trainable)
Note MobileNet requires pixels be scaled within the range -1 to +1 so use the function below to scale your input images. Also I assume your labels are one hot encoded so I specified the loss as 'categorical_crossentropy'. If the are not one hot use sparse_categorical_crossentropy.
def scaler(img):
img=img/127.5-1
return img
Upvotes: 0