Migrate Convolutional2D dim_ordering parameter to Conv2D in tf.keras - tensorflow

I'm newbie with Tensorflow and Keras, and I'm migrating the following code:
Convolution2D(64, 5, 5, activation='relu', border_mode='same', dim_ordering='tf', name='conv1_1')(inputs)
The interpreter suggest me this code:
Conv2D(64, (5, 5), activation="relu", name="conv1_1", padding="same", data_format="channels_last")
My question is:
Is dim_ordering='tf' the same as data_format="channels_last"?

Yes, dim_ordering='tf' is equal to data_format="channels_last", which is also the default, so most of the times you might simply ignore this parameter.
This site seems to store old Keras documentation pages where you can confirm this: http://faroit.com/keras-docs/1.0.8/layers/convolutional/#convolution2d

For the new api, you'll have to convert dim_ordering to data_format and the corresponding values are tf -> channels_last or th -> channels_first. So
# for dim_ordering = 'tf'
data_format = 'channels_last'
# for dim_ordering = 'th'
data_format = 'channels_first'

Related

Create timeseries dataset for TensorFlow v2

I'm trying to feed a model CNN+LSTM with data from a csv. What I'm missing is setting a correct dataset to start training my model.
This is my test model:
def test_model():
model = models.Sequential()
model.add(TimeDistributed(Conv1D(32, 4, strides=1, activation='relu', padding="valid"), input_shape=[None, 6, 20]))
model.add(TimeDistributed(MaxPooling1D(pool_size=2), input_shape=[None, 6, 20]))
model.add(TimeDistributed(Conv1D(64, 4, strides=1, activation='relu', padding="valid"), input_shape=[None, 6, 20]))
model.add(TimeDistributed(MaxPooling1D(pool_size=2), input_shape=[None, 6, 20]))
model.add(TimeDistributed(Flatten(), input_shape=[None, 6, 20]))
model.add(LSTM(100, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(100, activation="relu"))
model.add(Dropout(0.4))
model.add(Dense(5, activation="softmax"))
model.compile(optimizer=keras.optimizers.Adam(1e-3), loss="binary_crossentropy", metrics=["accuracy"])
return model
Here you can download test.csv
CSV dataset is made of 6 features + 1 multilabel. I need to create a time series each 20 row, so I think my shape should be [None, 6, 20] ordered by ascending timestamp value.
I'm new in TensorFlow and I don't know how to create an appropriate dataset from scratch, I was able to load a dataset from directory with images (for CNN) but in this scenario I really don't know how to do it.
This is what I tried to generate my dataset:
with open('test.csv') as csvfile:
dataset = list()
reader = csv.reader(csvfile, delimiter=',')
next(reader)
count = 0
timeseries = list()
labels = list()
for row in reader:
count = count + 1
if count <= 20:
timeseries.append(
[float(row[0]), float(row[1]), float(row[2]), float(row[3]), float(row[4]), float(row[5])])
else:
dataset.append(timeseries)
labels.append(int(row[6].split("L")[-1]))
timeseries = list()
count = 0
After that I transformed it in a tf.DataSet like this:
dataset = tf.data.Dataset.from_tensor_slices(dataset)
labels = tf.data.Dataset.from_tensor_slices(labels)
Here I got a <TensorSliceDataset shapes: (20, 6), types: tf.float32> like I want. Then I fed a K-Fold with it:
estimator = KerasClassifier(build_fn=test_model, epochs=60, batch_size=5, verbose=0)
kfold = KFold(n_splits=10, shuffle=True)
results = cross_val_score(estimator, dataset, labels, cv=kfold)
When running cross_val_score I got this error:
TypeError: Singleton array array(<TensorSliceDataset shapes: (20, 6), types: tf.float32>, dtype=object) cannot be considered a valid collection.
What I'm missing?

UnimplementedError: Fused conv implementation does not support grouped convolutions for now

I am trying to build a CNN model to recognise human sketch using the TU-Berlin dataset. I downloaded the png zip file, imported the data to Google Colab and then split the data into train-test folders. Here is the model:
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(filters = 64, kernel_size = (5,5),padding = 'Same',
activation ='relu', input_shape = target_dims),
tf.keras.layers.Conv2D(filters = 64, kernel_size = (5,5),padding = 'Same',
activation ='relu'),
tf.keras.layers.MaxPool2D(pool_size=(2,2)),
tf.keras.layers.Dropout(0.25),
tf.keras.layers.Conv2D(filters = 128, kernel_size = (3,3),padding = 'Same',
activation ='relu'),
tf.keras.layers.Conv2D(filters = 128, kernel_size = (3,3),padding = 'Same',
activation ='relu'),
tf.keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2)),
tf.keras.layers.Dropout(0.25),
tf.keras.layers.Conv2D(256, kernel_size=4, strides=1, activation='relu', padding='same'),
tf.keras.layers.Conv2D(256, kernel_size=4, strides=2, activation='relu', padding='same'),
tf.keras.layers.Dropout(0.25),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation = "relu"),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(n_classes, activation= "softmax")
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=["accuracy"])
model.fit_generator(train_generator, epochs=10, validation_data=val_generator)
And I am getting the following error:
UnimplementedError: Fused conv implementation does not support grouped convolutions for now.
[[node sequential/conv2d/Relu (defined at <ipython-input-9-36d4624b896d>:1) ]] [Op:__inference_train_function_1358]
Function call stack:
train_function
I would be grateful to any kind of help that will solve this issue. Thank you.
(PS - I am running Tensorflow 2.2.0 and no GPU)
I had a similar error, the problem was with the number of channels for my image and the number of channels I specified in the model. So check the number of dimension of your image and check the value specified in the input shape ensure they are the same
I had this same error using the facial expression recognition dataset, here's how i solved this same error.
From what i understand the dataset is gray color,
when you use ImageDataGenerator of tensorflow and flow_from_directory to generate the train and validation set,
you need to specify the color_mode as grayscale or rgb based on the dataset/images, here it will be 'grayscale',
in the model the first layer Conv2D the input_shape should be
input_shape = (height, width, 1), 1 because its grayscale.
Just mention the color_mode="grayscale" in flow from directory and check your model input (height,width,1).
Just as #grande_cifer said, the issue pops up from an incompatibility of number of image channel specified and correct number of channels of real images.
If you are not sure of the exact number of channel, I advice you specify 1 in your parameter target_dims, and forcefully convert all images when loading them to your net as grayscale, using the parameter color_mode = "grayscale" when loading the images to your net.
For more info, check keras online doc.
You will find this error in 2 cases:
when the number of channels for your image and the number of channels you specified in the model are not same . Here the solution is to make them equal.
When you use group param of Conv2D from tensorflow.keras . Here they have not implemented it with the use of group param , which is Depthwise Convolution in real (use tf.keras.layers.DepthwiseConv2D). For me the work around was pip install tf-nightly==2.10.0.dev20220406 as this package also have some unimplemented keras APIs...as this was not mentioned anywhere when I encountered this error
I hope this is useful

Cannot convert tf.keras.layers.ConvLSTM2D layer to open vino intermediate representation

I am trying to convert a trained model in tensorflow to Open VINO Intermediate Representation.
I have a model of the form given below
class Conv3DModel(tf.keras.Model):
def __init__(self):
super(Conv3DModel, self).__init__()
# Convolutions
self.conv1 = tf.compat.v2.keras.layers.Conv3D(32, (3, 3, 3), activation='relu', name="conv1", data_format='channels_last')
self.pool1 = tf.keras.layers.MaxPool3D(pool_size=(2, 2, 2), data_format='channels_last')
self.conv2 = tf.compat.v2.keras.layers.Conv3D(64, (3, 3, 3), activation='relu', name="conv1", data_format='channels_last')
self.pool2 = tf.keras.layers.MaxPool3D(pool_size=(2, 2,2), data_format='channels_last')
# LSTM & Flatten
self.convLSTM =tf.keras.layers.ConvLSTM2D(40, (3, 3))
self.flatten = tf.keras.layers.Flatten(name="flatten")
# Dense layers
self.d1 = tf.keras.layers.Dense(128, activation='relu', name="d1")
self.out = tf.keras.layers.Dense(6, activation='softmax', name="output")
def call(self, x):
x = self.conv1(x)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = self.convLSTM(x)
x = self.flatten(x)
x = self.d1(x)
return self.out(x)
I tried to convert the model into IR. The model is here .
I have trained this model in tensorflow 1.15. Tensorflow 2.0 is currently not supported.
Now I tried to run the command
python3 /opt/intel/openvino/deployment_tools/model_optimizer/mo_tf.py --saved_model_dir jester_trained_models/3dcnn-basic/ --output_dir /home/deepanshu/open_vino/udacity_project_custom_model/
Now i got the following error
Model Optimizer arguments:
Common parameters:
Path to the Input Model: None
Path for generated IR: /home/deepanshu/open_vino/udacity_project_custom_model/
IR output name: saved_model
Log level: ERROR
Batch: Not specified, inherited from the model
Input layers: Not specified, inherited from the model
Output layers: Not specified, inherited from the model
Input shapes: Not specified, inherited from the model
Mean values: Not specified
Scale values: Not specified
Scale factor: Not specified
Precision of IR: FP32
Enable fusing: True
Enable grouped convolutions fusing: True
Move mean values to preprocess section: False
Reverse input channels: False
TensorFlow specific parameters:
Input model in text protobuf format: False
Path to model dump for TensorBoard: None
List of shared libraries with TensorFlow custom layers implementation: None
Update the configuration file with input/output node names: None
Use configuration file used to generate the model with Object Detection API: None
Operations to offload: None
Patterns to offload: None
Use the config file: None
Model Optimizer version: 2020.1.0-61-gd349c3ba4a
[ ERROR ] Unexpected exception happened during extracting attributes for node conv3d_model/conv_lst_m2d/bias/Read/ReadVariableOp. Original exception message: 'ascii' codec can't decode byte 0xc9 in position 1: ordinal not in range(128)
As far as I can see it is the tf.keras.layers.ConvLSTM2D(40, (3, 3)) causing problems . I am kind of stuck here . Can anyone tell me where can I proceed further ?
Thanks
Edit to the question
Now I rejected the above tensorflow implementation and used keras . My h5 model developed was converted into .pb format using this post.
Now I ran the model optimizer on this .pb file. Using the command
python3 /opt/intel/openvino/deployment_tools/model_optimizer/mo_tf.py --input_model /home/deepanshu/ml_playground/jester_freezed/tf_model.pb --output_dir /home/deepanshu/open_vino/udacity_project_custom_model/ --input_shape=[1,30,64,64,1] --data_type FP32
Now i am facing another issue . The issue here is point no. 97 on this post.
So my model contains a cycle and model optimizer does not know a way to convert it. Has anybody faced this issue before ?
Please help.
Here is the model .
Here is the defination of the model in keras
from keras.models import Sequential
from keras.layers import Conv3D , MaxPool3D,Flatten ,Dense
from keras.layers.convolutional_recurrent import ConvLSTM2D
import keras
model = Sequential()
model.add(Conv3D(32, (3, 3, 3),
name="conv1" , input_shape=(30, 64, 64,1) , data_format='channels_last',
activation='relu') )
model.add(MaxPool3D(pool_size=(2, 2, 2), data_format='channels_last'))
model.add(Conv3D(64, (3, 3, 3), activation='relu', name="conv2", data_format='channels_last'))
model.add(MaxPool3D(pool_size=(2, 2,2), data_format='channels_last'))
model.add(ConvLSTM2D(40, (3, 3)))
model.add(Flatten(name="flatten"))
model.add(Dense(128, activation='relu', name="d1"))
model.add(Dense(6, activation='softmax', name="output"))
Actually the script to convert from h5 to .pb suggested by intel was not good enough. Always use the code from here to convert your keras model to .pb.
Once you obtain your .pb file now convert your model to IR using
python3 /opt/intel/openvino/deployment_tools/model_optimizer/mo_tf.py --input_model ml_playground/try_directory/tf_model.pb --output_dir /home/deepanshu/open_vino/udacity_project_custom_model/ --input_shape=[1,30,64,64,1] --data_type FP32
After the execution of this script we can obtain the intermediate representation of the keras model.

Tensorflow: Get the same tensor after a series of convolution and deconvolution

I am wondering whether it is possible to end up with the same tensor after propagating it through a convolutional and then deconvolutional filter. For example:
random_image = np.random.rand(1, 6, 6, 3)
input_image = tf.placeholder(shape=[1, 6, 6, 3], dtype=tf.float32)
conv = tf.layers.conv2d(input_image, filters=6, kernel_size=[3, 3], strides=(1, 1), data_format="channels_last")
deconv = tf.layers.conv2d_transpose(conv, filters=3, kernel_size=[3, 3], strides=(1, 1), data_format="channels_last")
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(random_image)
# Get an output which will be same as:
print(sess.run(deconv, feed_dict={input_image: random_image}))
In other words, if the generated random_image vector is for example: [1,2,3,4,5], after convolution and deconvolution the deconv vector to be [1,2,3,4,5].
However, I am not able to get it to work.
Looking forward to you answers!
It's possible to get some degree of visual similarity, by using VarianceScaling initialization for example. Or even with completely custom initializer. But transposed convolution isn't mathematically deconvolution. So you can't get math equality with conv2d_transpose.
Take a look Why isn't this Conv2d_Transpose / deconv2d returning the original input in tensorflow?

Loading weights in TH format when keras is set to TF format

I have Keras' image_dim_ordering property set to 'tf', so I define my models as this:
model = Sequential()
model.add(ZeroPadding2D((1, 1), input_shape=(224, 224, 3)))
model.add(Convolution2D(64, 3, 3, activation='relu'))
But when I call load_weights method, it crashes because my model was saved using "th" format:
Exception: Layer weight shape (3, 3, 3, 64) not compatible with provided weight shape (64, 3, 3, 3)
How can I load these weights and automatically transpose them to fix Tensorflow's format?
I asked Francois Chollet about this (he doesn't have an SO account) and he kindly passed along this reply:
"th" format means that the convolutional kernels will have the shape (depth, input_depth, rows, cols)
"tf" format means that the convolutional kernels will have the shape (rows, cols, input_depth, depth)
Therefore you can convert from the former to the later via np.transpose(x, (2, 3, 1, 0)) where x is the value of the convolution kernel.
Here's some code to do the conversion:
from keras import backend as K
K.set_image_dim_ordering('th')
# build model in TH mode, as th_model
th_model = ...
# load weights that were saved in TH mode into th_model
th_model.load_weights(...)
K.set_image_dim_ordering('tf')
# build model in TF mode, as tf_model
tf_model = ...
# transfer weights from th_model to tf_model
for th_layer, tf_layer in zip(th_model.layers, tf_model.layers):
if th_layer.__class__.__name__ == 'Convolution2D':
kernel, bias = layer.get_weights()
kernel = np.transpose(kernel, (2, 3, 1, 0))
tf_layer.set_weights([kernel, bias])
else:
tf_layer.set_weights(tf_layer.get_weights())
In case the model contains Dense layers downstream of the Convolution2D layers, then the weight matrix of the first Dense layer would need to be shuffled as well.
You can Use This Script which auto translates theano/tensorflow backend trained model weights directly into the other 3 possible combinations of backend / dim ordering.