Keras and tensorflow conflict when transfer learning on MobileNetV3 - tensorflow

I'm trying to do transfer learning with MobileNetV3 in Keras but I'm having some issues.
from keras.models import Model
from keras.layers import GlobalMaxPooling2D, Dense, Dropout
from keras.optimizers import Adam
from keras.callbacks import ModelCheckpoint
from tensorflow.keras.applications import MobileNetV3Small
import numpy as np
from tqdm import tqdm
from PIL import Image, ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
pretrained_model = MobileNetV3Small(input_shape=(224,224,3),
weights="imagenet",
include_top=False)
# freeze all layers except the last one
for layer in pretrained_model.layers:
layer.trainable = False
pretrained_model.layers[-1].trainable = True
# combine the model with some extra layers for classification
last_output = pretrained_model.layers[-1].output
x = GlobalMaxPooling2D()(last_output)
x = Dense(128, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(1, activation='sigmoid')(x)
model = Model(pretrained_model.input, x)
I get this error when I try to make the Dense layer:
TypeError: Cannot convert a symbolic Keras input/output to a numpy array. This error may indicate that you're trying to pass a symbolic value to a NumPy call, which is not supported. Or, you may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model.
but it's fixed by adding the following code snippet:
from tensorflow.python.framework.ops import disable_eager_execution
disable_eager_execution()
When I include the code fix above, I get this error when I call model.fit():
FailedPreconditionError: 2 root error(s) found.
(0) Failed precondition: Could not find variable Conv_1_2/kernel. This could mean that the variable has been deleted. In TF1, it can also mean the variable is uninitialized. Debug info: container=localhost, status=Not found: Resource localhost/Conv_1_2/kernel/N10tensorflow3VarE does not exist.
[[{{node Conv_1_2/Conv2D/ReadVariableOp}}]]
[[_arg_dense_12_target_0_1/_100]]
(1) Failed precondition: Could not find variable Conv_1_2/kernel. This could mean that the variable has been deleted. In TF1, it can also mean the variable is uninitialized. Debug info: container=localhost, status=Not found: Resource localhost/Conv_1_2/kernel/N10tensorflow3VarE does not exist.
[[{{node Conv_1_2/Conv2D/ReadVariableOp}}]]
0 successful operations.
0 derived errors ignored.
How can I fix these issues and train the model?

From comments
Don't mix tf.keras and standalone keras. They are not compatible. Only use one of them (paraphrased from Frightera)
Working code as shown below
from tensorflow.keras.models import Model
from tensorflow.keras.layers import GlobalMaxPooling2D, Dense, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.applications import MobileNetV3Small
import numpy as np
from tqdm import tqdm
from PIL import Image, ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
pretrained_model = MobileNetV3Small(input_shape=(224,224,3),
weights="imagenet",
include_top=False)
# freeze all layers except the last one
for layer in pretrained_model.layers:
layer.trainable = False
pretrained_model.layers[-1].trainable = True
# combine the model with some extra layers for classification
last_output = pretrained_model.layers[-1].output
x = GlobalMaxPooling2D()(last_output)
x = Dense(128, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(1, activation='sigmoid')(x)
model = Model(pretrained_model.input, x)

Related

Issue retrieving error when adding a classifier to a MobileNet model

I have the following code, I am retrieving error when I try to add my own classifier.
import keras
from keras import layers,Model
from keras.layers import Input,GlobalAveragePooling2D,Flatten,Dense
MobileNetV2_model= tf.keras.applications.MobileNetV2(input_shape=None, alpha=1.0, include_top=False,
weights='imagenet')
#MobileNetV2_model.summary()
x= MobileNetV2_model.output
x = layers.GlobalAveragePooling2D()(x)
final_output=layers.Dense(2, activation='sigmoid')(x)
model = keras.Model(inputs=MobileNetV2.input, outputs = final_output)
model.compile(optimizer="adam", loss='BinaryCrossentropy', metrics=['accuracy'],loss_weights=0.1)
Error
TypeError: Cannot convert a symbolic Keras input/output to a numpy array. This error may indicate that
you're trying to pass a symbolic value to a NumPy call, which is not supported. Or, you may be trying
to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model.
You should never mix keras and tf.keras. You can refer working code as shown below
import tensorflow as tf
from tensorflow.keras import layers, Model
MobileNetV2_model= tf.keras.applications.MobileNetV2(input_shape=(224,224,3), alpha=1.0, include_top=False, weights='imagenet')
#MobileNetV2_model.summary()
x= MobileNetV2_model.output
x = layers.GlobalAveragePooling2D()(x)
final_output=layers.Dense(2, activation='sigmoid')(x)
model = Model(inputs=MobileNetV2_model.input, outputs = final_output)
model.compile(optimizer="adam", loss='BinaryCrossentropy', metrics=['accuracy'],loss_weights=0.1)

Input 0 of layer fc1 is incompatible with the layer: expected axis -1 of input shape to have value 25088 but received input with shape (None, 32768)

I'm implementing SRGAN (and am not very experienced in this field), which uses a pre-trained VGG19 model to extract features. The following code was working fine on Keras 2.1.2 and tf 1.15.0 till yesterday. then it started throwing an "AttributeError: module 'keras.utils.generic_utils' has no attribute 'populate_dict_with_module_objects'" So i updated the keras version to 2.4.3 and tf to 2.5.0. but then its showing a "Input 0 of layer fc1 is incompatible with the layer: expected axis -1 of input shape to have value 25088 but received input with shape (None, 32768)" on the following line
features = vgg(input_layer)
But here the input has to be (256,256,3).
I had downgraded the keras and tf versions to the one I mentioned before to get rid of this error in the first place and it was working well till yesterday.
changing the input shape to (224,224,3) does not work. Any help in solving this error will be very appreciated.
import glob
import time
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import keras
from keras.layers import Input
from keras.applications.vgg19 import VGG19
from keras.callbacks import TensorBoard
from keras.layers import BatchNormalization, Activation, LeakyReLU, Add, Dense,Flatten
from keras.layers.convolutional import Conv2D, UpSampling2D
from keras.models import Model
from keras.optimizers import Adam
from scipy.misc import imread, imresize
from PIL import Image
def build_vgg():
input_shape = (256, 256, 3)
vgg = VGG19(weights="imagenet")
vgg.outputs = [vgg.layers[9].output]
input_layer = Input(shape=input_shape)
features = vgg(input_layer)
model = Model(inputs=[input_layer], outputs=[features])
return model
vgg = build_vgg()
vgg.trainable = False
vgg.compile(loss='mse', optimizer=common_optimizer, metrics=['accuracy'])
# Build and compile the discriminator
discriminator = build_discriminator()
discriminator.compile(loss='mse', optimizer=common_optimizer, metrics=['accuracy'])
# Build the generator network
generator = build_generator()
The Error message
Im using google colab
Importing keras from tensorflow and setting include_top=False in
vgg = VGG19(weights="imagenet",include_top=False)
seems to work.

Tensorflow 2 /Google Colab / EfficientNet Training - AttributeError: 'Node' object has no attribute 'output_masks'

I am trying to train EfficientNetB1 on Google Colab and constantly running into different issues with correct import statements from Keras or Tensorflow.Keras, currently this is how my imports look like
import tensorflow as tf
from tensorflow.keras import backend as K
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.python.keras.layers.pooling import AveragePooling2D
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import SGD
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import pickle
import cv2
import os
from sklearn.metrics import confusion_matrix
from sklearn.utils.multiclass import unique_labels
import efficientnet.keras as enet
from tensorflow.keras.layers import Dense, Dropout, Activation, BatchNormalization, Flatten, Input
and this is how my model looks like
load the ResNet-50 network, ensuring the head FC layer sets are left
# off
baseModel = enet.EfficientNetB1(weights="imagenet", include_top=False, input_tensor=Input(shape=(224, 224, 3)), pooling='avg')
# Adding 2 fully-connected layers to B0.
x = baseModel.output
x = BatchNormalization()(x)
x = Dropout(0.7)(x)
x = Dense(512)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Dropout(0.5)(x)
x = Dense(512)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# Output layer
predictions = Dense(len(lb.classes_), activation="softmax")(x)
model = Model(inputs = baseModel.input, outputs = predictions)
# loop over all layers in the base model and freeze them so they will
# *not* be updated during the training process
for layer in baseModel.layers:
layer.trainable = False
But for the life of me I can't figure out why I am getting the below error
AttributeError Traceback (most recent call last)
<ipython-input-19-269fe6fc6f99> in <module>()
----> 1 baseModel = enet.EfficientNetB1(weights="imagenet", include_top=False, input_tensor=Input(shape=(224, 224, 3)), pooling='avg')
2
3 # Adding 2 fully-connected layers to B0.
4 x = baseModel.output
5 x = BatchNormalization()(x)
5 frames
/usr/local/lib/python3.6/dist-packages/keras/engine/base_layer.py in _collect_previous_mask(input_tensors)
1439 inbound_layer, node_index, tensor_index = x._keras_history
1440 node = inbound_layer._inbound_nodes[node_index]
-> 1441 mask = node.output_masks[tensor_index]
1442 masks.append(mask)
1443 else:
AttributeError: 'Node' object has no attribute 'output_masks'
The problem is the way you import the efficientnet.
You import it from the Keras package and not from the TensorFlow.Keras package.
Change your efficientnet import to
import efficientnet.tfkeras as enet
Not sure, but this error maybe caused by wrong TF version. Google Colab for now comes with TF 1.x by default. Try this to change the TF version and see if this resolves the issue.
try:
%tensorflow_version 2.x
except:
print("Failed to load")

load_model error: ValueError: Improperly formatted model config when tensorflow.keras

I can load the model with load_model("model.h5") in colab and do a model.predict which works. But when I download the h5 file and run load_model locally, the load_model call gets an error "ValueError: Improperly formatted model config."
This is the model:
base_model=MobileNet(weights='imagenet',include_top=False) #imports the mobilenet model and discards the last 1000 neuron layer.
x=base_model.output
x=GlobalAveragePooling2D()(x)
x=Dense(1024,activation='relu')(x) #we add dense layers so that the model can learn more complex functions and classify for better results.
x=Dense(1024,activation='relu')(x) #dense layer 2
x=Dense(512,activation='relu')(x) #dense layer 3
preds=Dense(2,activation='softmax')(x) #final layer with softmax activation
using transfer learning
model=Model(inputs=base_model.input,outputs=preds)
for layer in model.layers[:20]:
layer.trainable=False
for layer in model.layers[20:]:
layer.trainable=True
then trained
train_generator=train_datagen.flow_from_directory('/content/chest_xray/train/',
target_size=(224,224),
color_mode='rgb',
batch_size=32,
class_mode='categorical', shuffle=True)
model.compile(optimizer='Adam',loss='categorical_crossentropy',metrics=['accuracy'])
# Adam optimizer
# loss function will be categorical cross entropy
# evaluation metric will be accuracy
step_size_train=train_generator.n//train_generator.batch_size
model.fit_generator(generator=train_generator,
steps_per_epoch=step_size_train,
epochs=5)
model saved
model.save('chest-xray-pneumonia.h5')
prediction works
ill_path = "/content/chest_xray/train/PNEUMONIA/"
good_path = "/content/chest_xray/train/NORMAL/"
ill_pic = ill_path + os.listdir(ill_path)[1]
good_pic = good_path + os.listdir(good_path)[1]
print(get_rez(ill_pic))
print(get_rez(good_pic))
But locally running in a Flask app python script main.py, it doesn't
from flask import render_template, jsonify, Flask, redirect, url_for, request
from app import app
import random
import os
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.mobilenet import preprocess_input, decode_predictions
import numpy as np
import ipdb
weightsPath = app.config['UPLOAD_FOLDER']
get error on the next line: ValueError: Improperly formatted model config.
new_model = load_model(os.path.join(app.config['UPLOAD_FOLDER'],"chest-xray-pneumonia.h5"))
def upload_file():
if request.method == 'POST':
f = request.files['file']
path = os.path.join(app.config['UPLOAD_FOLDER'], f.filename)
#f.save(os.path.join(app.config['UPLOAD_FOLDER'], f.filename))
ill_pic = os.path.join(app.config['UPLOAD_FOLDER'],
f.filename)
print(get_rez(ill_pic))

Possible compatibility issue with Keras, TensorFlow and scikit (tf.global_variables())

I'm trying to do a small test with my dataset on Keras Regressor (using TensorFlow), but I'm having a small issue. The error seems to be on the function cross_val_score from scikit. It starts on it and the last error message is:
File "/usr/local/lib/python2.7/dist-packages/Keras-2.0.2-py2.7.egg/keras/backend/tensorflow_backend.py", line 298, in _initialize_variables
variables = tf.global_variables()
AttributeError: 'module' object has no attribute 'global_variables'
My full code is basically the example found in http://machinelearningmastery.com/regression-tutorial-keras-deep-learning-library-python/ with small changes.
I've looked upon the " 'module' object has no attribute 'global_variables' " error and it seems to be about the Tensorflow version, but I'm using the most recent one (1.0) and there is no function in the code that works directly with tf that I can change. Below is my full code, is there anyway i can change it so it works? Thanks for the help
import numpy
import pandas
import sys
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.datasets import load_svmlight_file
# define base mode
def baseline_model():
# create model
model = Sequential()
model.add(Dense(68, activation="relu", kernel_initializer="normal", input_dim=68))
model.add(Dense(1, kernel_initializer="normal"))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam')
return model
X, y, query_id = load_svmlight_file(str(sys.argv[1]), query_id=True)
scaler = StandardScaler()
X = scaler.fit_transform(X.toarray())
# fix random seed for reproducibility
seed = 1
numpy.random.seed(seed)
# evaluate model with standardized dataset
estimator = KerasRegressor(build_fn=baseline_model, nb_epoch=100, batch_size=5, verbose=0)
kfold = KFold(n_splits=5, random_state=seed)
results = cross_val_score(estimator, X, y, cv=kfold)
print("Results: %.2f (%.2f) MSE" % (results.mean(), results.std()))
You are probably using an older Tensorflow version install tensorflow 1.2.0rc2 and you should be fine.