CNN prediction using tensorflow - python

I'm quite new to python and tensorflow, but already managed to build, train and validate a CNN with my own database of images saved as tf.records.
Now I want the model to read in a single picture and predict in real-time. Therefore, I wanted to modify my validation script by getting rid of the parser (which decoded my images saved as tf.records) and didn't batch the input images, since I only want to predict one. Somehow I always get the following Error:
TypeError: Value passed to parameter 'input' has DataType uint8 not in list of allowed values: float16, bfloat16, float32, float64
I took a closer look at the script I used to create the tf.records and compared them to the parser I used in the scripts for training and validation, but wasn't able to find the mistake.
I would be thankful, if you could help me to find the mistake or show me an easier way to predict the classes with an already trained CNN.
import tensorflow as tf
import cv2
num_classes = 2
crop_top = 5
crop_bottom = 10
crop_sides = 5
img_size_height = 80
img_size_width = 100
model_dir = "./2cv_128fc"
def load_image():
img = cv2.imread('./dir_pred_img/img_2.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.resize(img, (img_size_width + (2 * crop_sides), img_size_height + crop_top + crop_bottom),
interpolation=cv2.INTER_CUBIC)
img = img[crop_top:(img_size_height + crop_top), crop_sides:(img_size_width + crop_sides)]
features = {'image': img}
return features
def conv_nn(input_layer):
conv_1 = tf.layers.conv2d(inputs=input_layer, name='conv_layer_1', filters=32, kernel_size=3, padding='same',
activation=tf.nn.relu)
pool_1 = tf.layers.max_pooling2d(inputs=conv_1, pool_size=2, strides=2)
conv_2 = tf.layers.conv2d(inputs=pool_1, name='conv_layer_2', filters=32, kernel_size=3, padding='same',
activation=tf.nn.relu)
pool_2 = tf.layers.max_pooling2d(inputs=conv_2, pool_size=2, strides=2)
flatten = tf.contrib.layers.flatten(pool_2)
fc_layer = tf.layers.dense(inputs=flatten, name='fully_connected_layer', units=128, activation=tf.nn.relu)
fc_layer = tf.layers.dropout(fc_layer, rate=0.5, noise_shape=None, seed=None)
output_layer = tf.layers.dense(inputs=fc_layer, name='output_layer', units=num_classes)
return output_layer
def model_fn(features):
input_layer = features["image"]
input_layer = tf.identity(input_layer, name="input_tensor")
input_layer = tf.reshape(input_layer, [-1, img_size_height, img_size_width, 1]) # 1.tensor 2.shape
input_layer = tf.identity(input_layer, name="input_tensor_reshaped")
logits = conv_nn(input_layer)
pred = tf.nn.softmax(logits=logits)
return pred
model = tf.estimator.Estimator(model_fn=model_fn, model_dir=model_dir)
prediction = list(model.predict(input_fn=load_image))
print(prediction[0])
full error message:
WARNING:tensorflow:Input graph does not use tf.data.Dataset or contain a QueueRunner. That means predict yields forever. This is probably a mistake.
Traceback (most recent call last):
File "C:/Users/Dell/PycharmProjects/create_data/pred_img.py", line 54, in <module>
prediction = list(model.predict(input_fn=load_image))
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\estimator\estimator.py", line 577, in predict
features, None, model_fn_lib.ModeKeys.PREDICT, self.config)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\estimator\estimator.py", line 1195, in _call_model_fn
model_fn_results = self._model_fn(features=features, **kwargs)
File "C:/Users/Dell/PycharmProjects/create_data/pred_img.py", line 47, in model_fn
logits = conv_nn(input_layer)
File "C:/Users/Dell/PycharmProjects/create_data/pred_img.py", line 27, in conv_nn
activation=tf.nn.relu)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\layers\convolutional.py", line 417, in conv2d
return layer.apply(inputs)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 817, in apply
return self.__call__(inputs, *args, **kwargs)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\layers\base.py", line 374, in __call__
outputs = super(Layer, self).__call__(inputs, *args, **kwargs)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 757, in __call__
outputs = self.call(inputs, *args, **kwargs)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\keras\layers\convolutional.py", line 194, in call
outputs = self._convolution_op(inputs, self.kernel)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 868, in __call__
return self.conv_op(inp, filter)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 520, in __call__
return self.call(inp, filter)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 204, in __call__
name=self.name)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\ops\gen_nn_ops.py", line 1043, in conv2d
data_format=data_format, dilations=dilations, name=name)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 609, in _apply_op_helper
param_name=input_name)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 60, in _SatisfiesTypeConstraint
", ".join(dtypes.as_dtype(x).name for x in allowed_list)))
TypeError: Value passed to parameter 'input' has DataType uint8 not in list of allowed values: float16, bfloat16, float32, float64

The following code descirbes how you can implement this with keras.
import keras
from keras.layers import Input, Convolution2D, MaxPooling2D, Cropping2D, Dense, Flatten, Dropout
from keras.preprocessing import image
from keras.models import Model
from keras.optimizers import Adam
import cv2
import numpy as np
# parameters
num_classes = 2
crop_top = 5
crop_bottom = 10
crop_sides = 5
img_size_height = 80
img_size_width = 100
channels = 3
input_shape = (img_size_height, img_size_width, channels)
activation = 'relu'
learning_rate = 0.0001
if num_classes == 2:
loss = 'binary_crossentropy'
else:
loss = 'categorical_crossentropy'
test_image = image.load_img('./data/img.png')
test_image = image.img_to_array(test_image)
input_shape = test_image.shape
def model(input_shape=input_shape):
inputs = Input(shape=input_shape)
# cropping=((pixels_from_top, pixels_from_bottom), (pixels_from_left, pixels_from_right))
cropping = Cropping2D(cropping=((crop_top, crop_bottom), (crop_sides, crop_sides)))(inputs)
conv_1 = Convolution2D(32, kernel_size=(3, 3), padding='same', activation=activation)(cropping)
pool_1 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(conv_1)
conv_2 = Convolution2D(32, kernel_size=(3, 3), padding='same', activation=activation)(pool_1)
pool_2 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(conv_2)
flatten = Flatten()(pool_2)
dense_1 = Dense(128, activation=activation, name='fully_connected_layer')(flatten)
dropout = Dropout(0.5)(dense_1)
outputs = Dense(num_classes, activation='softmax')(dropout)
model = Model(inputs=inputs, outputs=outputs)
adam = Adam(lr=learning_rate)
model.compile(optimizer=adam, loss=loss, metrics=['acc', 'mse', 'mae'])
model.summary()
return model
test_image = np.expand_dims(test_image, axis=0)
model = model(input_shape)
# note that without training we will only get random results
prediction = model.predict_on_batch(test_image)
print(prediction)

I found a solution.
I added following line to the end of def load_image() and returned dataset instead of feautures.
dataset = tf.data.Dataset.from_tensors(features)
return dataset

Related

Training Deep Neural Network Using Tensorflow

I am trying to immplement the VGG16 network using Tensorflow.
to test the model, i want to classify a dataset of images.
i sarted by creating a train_data with tensorflow.data.Dataset:
<TensorSliceDataset element_spec=(TensorSpec(shape=(215, 160, 3), dtype=tf.float64, name=None), TensorSpec(shape=(20,), dtype=tf.float64, name=None))>
(their is 20 ouput classes)
created a custom 2d Conv Layer:
`class CustomConv2d(Layer):
def __init__(self,filters,kernel_size,padding,name):
super(CustomConv2d,self).__init__()
self.conv = Conv2D(filters=filters,
kernel_size=kernel_size,
activation='relu',
padding =padding,
name=name,
)
self.batchN = BatchNormalization()
def call(self,x,training=True):
output = self.conv(x)
output = self.batchN(output)
return output`
Created a Sub Model Class
`class VGG16(Model):
def __init__(self,input_shape,NUM_OF_CLASSES=20,dropout_parameters=0.5):
super(VGG16,self).__init__()
self.dropout = Dropout(dropout_parameters)
### First Conv Block
self.conv_11 = Conv2D(filters=53,
kernel_size=(3,3),
activation='relu',
padding ='same',
name='conv11',
input_shape=input_shape
)
self.conv_12 = CustomConv2d(64,(3,3),padding='same',name='conv_12')
self.maxpool = MaxPool2D(pool_size=(2,2),padding='same')`
## Second Conv Block
self.conv21 = CustomConv2d(64,(3,3),padding='same',name='conv_21')
self.conv22 = CustomConv2d(64,(3,3),padding='same',name='conv_22')
## Third Conv Block
self.conv31 = CustomConv2d(256,(3,3),padding='same',name='conv_31')
self.conv32 = CustomConv2d(256,(3,3),padding='same',name='conv_32')
self.conv33 = CustomConv2d(256,(3,3),padding='same',name='conv_33')
## Fourth Conv Block
self.conv41 = CustomConv2d(512,(3,3),padding='same',name='conv_41')
self.conv42 = CustomConv2d(512,(3,3),padding='same',name='conv_42')
self.conv43 = CustomConv2d(512,(3,3),padding='same',name='conv_43')
## Fifth CConv Block
self.conv51 = CustomConv2d(512,(3,3),padding='same',name='conv_51')
self.conv52 = CustomConv2d(512,(3,3),padding='same',name='conv_52')
self.conv53 = CustomConv2d(512,(3,3),padding='same',name='conv_53')
#####
self.flatten = Flatten()
self.dense1 = Dense(1024,activation='relu',name='Dense_1')
self.dense2 = Dense(512,activation='relu',name='Dense_2')
self.dense3 = Dense(NUM_OF_CLASSES,activation='softmax',name='Dense_3')
def call(self,x,training=True):
x = self.maxpool(self.conv_12(self.conv_11(x)))
x = self.maxpool(self.conv22(self.conv21(x)))
x = self.maxpool(self.conv33(self.conv32(self.conv31(x))))
x = self.maxpool(self.conv43(self.conv42(self.conv41(x))))
x = self.maxpool(self.conv53(self.conv52(self.conv51(x))))
x = self.flatten(x)
x = self.dense3(self.dense2(self.dense1(x)))
return x
model = VGG16((215,160,3,1))
`
by the way i dont know why i have to put 1 at the end of shape
After Compiling the model
when i try to fit the data to the model i have this error:
`ValueError: in user code:
` File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1021, in train_function *
return step_function(self, iterator)
File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1010, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1000, in run_step **
outputs = model.train_step(data)
File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 859, in train_step
y_pred = self(x, training=True)
File "/usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
ValueError: Exception encountered when calling layer "vgg16_2" (type VGG16).
in user code:
File "/tmp/ipykernel_49926/980605695.py", line 38, in call *
x = self.maxpool(self.conv_12(self.conv_11(x)))
File "/usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler **
raise e.with_traceback(filtered_tb) from None
File "/usr/local/lib/python3.8/dist-packages/keras/engine/input_spec.py", line 228, in assert_input_compatibility
raise ValueError(f'Input {input_index} of layer "{layer_name}" '
ValueError: Input 0 of layer "conv11" is incompatible with the layer: expected min_ndim=4, found ndim=3. Full shape received: (215, 160, 3)
Call arguments received:
• x=tf.Tensor(shape=(215, 160, 3), dtype=float32)
• training=True``
Tought maybe their is problem in the shape of the Dataset
Edit:
the problem was solved after spliting the data into batches with:
trainDataset = trainDataset.shuffle(buffer_size=20).prefetch(buffer_size=15).batch(32)
but now the training is very slow. is it normal to take about 5 sec on each image of the batch?
It should be
model = VGG16((215,160,3))
Because conv2d input shape parameter take 3 values. (Height,width,channel)
you can input model like model(np.ones((1,215,160,3))) where 1 is the batch size

Deep Learning Tensorflow reshape is not working?

I try to get a prediction out of a trained model but i need to reshape it for tensorflow but it gives me this error all the time:
ValueError: in user code:
WARNING:tensorflow:Model was constructed with shape (None, 100, 100, 3) for input KerasTensor(type_spec=TensorSpec(shape=(None, 100, 100, 3), dtype=tf.float32, name='conv2d_input'), name='conv2d_input', description="created by layer 'conv2d_input'"), but it was called on an input with incompatible shape (None, 100, 100, 1).
Traceback (most recent call last):
File "c:\Dev\PM_AI\partthree.py", line 16, in <module>
prediction = model.predict([prepare("wurmbefall.jpg")])
File "C:\Users\danie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\utils\traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "C:\Users\danie\AppData\Local\Temp\__autograph_generated_filenl1hl3g5.py", line 15, in tf__predict_function
retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
ValueError: in user code:
File "C:\Users\danie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\training.py", line 1845, in predict_function *
return step_function(self, iterator)
File "C:\Users\danie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\training.py", line 1834, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "C:\Users\danie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\training.py", line 1823, in run_step **
outputs = model.predict_step(data)
File "C:\Users\danie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\training.py", line 1791, in predict_step
return self(x, training=False)
File "C:\Users\danie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\utils\traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "C:\Users\danie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\input_spec.py", line 248, in assert_input_compatibility
raise ValueError(
ValueError: Exception encountered when calling layer "sequential" (type Sequential).
Input 0 of layer "conv2d" is incompatible with the layer: expected axis -1 of input shape to have value 3, but received input with shape (None, 100, 100, 1)
Call arguments received by layer "sequential" (type Sequential):
• inputs=('tf.Tensor(shape=(None, 100, 100, 1), dtype=uint8)',)
• training=False
• mask=None
MY Code: Part One
import numpy as np
import matplotlib.pyplot as plt
import os
import random
import pickle
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D
from tqdm import tqdm
DATADIR = 'C:\Dev\PM_AI\FlowerImages'
CATEGORIES = ['Apfelschorf', 'Blattlaeuse', 'echterMehltau', 'falscherMehltau', 'Grauschimmel', 'KrautBraunFaeule', 'Raupen', 'Rostpilze']
training_data = []
def create_training_data():
for category in CATEGORIES:
path = os.path.join(DATADIR, category) #Path to images
class_num = CATEGORIES.index(category)
for img in tqdm(os.listdir(path)):
try:
img_array = cv2.imread(os.path.join(path,img))
new_array = cv2.resize(img_array, (IMG_Size, IMG_Size))
training_data.append([new_array, class_num])
except Exception as e:
pass
IMG_Size = 100
create_training_data()
print(len(training_data))
random.shuffle(training_data)
for sample in training_data[:10]:
print(sample[1])
X = []
y = []
for features, label in training_data:
X.append(features)
y.append(label)
X = np.array(X).reshape(-1, IMG_Size, IMG_Size, 3)
pickle_out = open("X.pickle", "wb")
pickle.dump(X, pickle_out)
pickle_out.close()
pickle_out = open("y.pickle", "wb")
pickle.dump(y, pickle_out)
pickle_out.close()
Part Two:
import tensorflow as tf
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D
from tensorflow.keras.callbacks import TensorBoard
NAME = "PflanzenApp"
X = pickle.load(open("X.pickle", "rb"))
y = pickle.load(open("Y.pickle", "rb"))
y = np.array(y)
X = np.array(X)
X = X/255.0
model = Sequential()
model.add(Conv2D(64, (3,3), input_shape = X.shape[1:]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, (3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Dense(1))
model.add(Activation('sigmoid'))
tensorboard = TensorBoard(log_dir="logs/{}".format(NAME))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(tf.expand_dims(X, axis=-1), y, batch_size=10, epochs=5, validation_split=0.1, callbacks=[tensorboard])
model.save('PflanzenApp.model')
Part Three:
import tensorflow as tf
import numpy as np
CATEGORIES = ['Apfelschorf', 'Blattlaeuse', 'echterMehltau', 'falscherMehltau', 'Grauschimmel', 'KrautBraunFaeule', 'Raupen', 'Rostpilze']
def prepare(filepath):
IMG_Size = 100
img_array = cv2.imread(filepath)
new_array = cv2.resize(img_array, (IMG_Size, IMG_Size))
reshaped_array = np.array(new_array).reshape(-1, IMG_Size, IMG_Size, 1)
return reshaped_array
model = tf.keras.models.load_model("PflanzenApp.model")
prediction = model.predict([prepare("wurmbefall.jpg")])
print(prediction)
The Error is in Part Three. I already tried to find the error why it says shape (None, 100, 100,1) if the none is the error but i couldnt find anything. Has somebody an Idea?
As lejlot explains in the comments above, the model expects colour pictures not greyscale and thus [100,100,3] not [100,100,1].

How to fit image data correctly to a model in python?

i am trying to trained a cnn model, but i really don't understand how to do it properly. i still learning about this kind of stuff so i'm really lost. I already tried doing stuff with it but still cannot get my head around it. can someone explain to me how to do it properly. when i try to fit the train data to the model this error pops up.
WARNING:tensorflow:Model was constructed with shape (None, 224, 224, 3) for input KerasTensor(type_spec=TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='input_1'), name='input_1', description="created by layer 'input_1'"), but it was called on an input with incompatible shape (None,).
Traceback (most recent call last):
File "G:/Skripsi/Program/training.py", line 80, in <module>
train.train()
File "G:/Skripsi/Program/training.py", line 70, in train
model.fit(self.x_train, self.y_train, epochs=2, verbose=1)
File "G:\Skripsi\Program\venv\lib\site-packages\keras\utils\traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "G:\Skripsi\Program\venv\lib\site-packages\tensorflow\python\framework\func_graph.py", line 1129, in autograph_handler
raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:
File "G:\Skripsi\Program\venv\lib\site-packages\keras\engine\training.py", line 878, in train_function *
return step_function(self, iterator)
File "G:\Skripsi\Program\venv\lib\site-packages\keras\engine\training.py", line 867, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "G:\Skripsi\Program\venv\lib\site-packages\keras\engine\training.py", line 860, in run_step **
outputs = model.train_step(data)
File "G:\Skripsi\Program\venv\lib\site-packages\keras\engine\training.py", line 808, in train_step
y_pred = self(x, training=True)
File "G:\Skripsi\Program\venv\lib\site-packages\keras\utils\traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "G:\Skripsi\Program\venv\lib\site-packages\keras\engine\input_spec.py", line 227, in assert_input_compatibility
raise ValueError(f'Input {input_index} of layer "{layer_name}" '
ValueError: Exception encountered when calling layer "model" (type Functional).
Input 0 of layer "conv2d" is incompatible with the layer: expected min_ndim=4, found ndim=1. Full shape received: (None,)
Call arguments received:
• inputs=tf.Tensor(shape=(None,), dtype=int32)
• training=True
• mask=None
this is my code for training the model.
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from densenet201 import DenseNet201
import tensorflow as tf
import pandas as pd
import numpy as np
import cv2
import os
dataset_folder = "./datasets/train_datasets"
class TrainingPreprocessing:
#staticmethod
def preprocessing_train(path):
images = cv2.imread(path, 3)
images_resize = cv2.resize(src=images, dsize=(224, 224), interpolation=cv2.INTER_LINEAR)
images_normalize = cv2.normalize(images_resize, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX,
dtype=cv2.CV_32F)
return images_normalize.reshape(224, 224, 3)
class Training:
#staticmethod
def load_data():
"""Loads and Preprocess dataset"""
train_labels_encode = []
train_labels = []
train_data = []
file_list = os.listdir(dataset_folder)
for folder in file_list:
file_list2 = os.listdir(str(dataset_folder) + '/' + str(folder))
for images in file_list2:
train_labels_encode.append(folder)
train_labels.append(folder)
train_data.append(np.array(TrainingPreprocessing.preprocessing_train(
str(dataset_folder) + '/' + str(folder) + '/' + str(images)
)))
labels = np.array(train_labels_decode)
data = np.array(train_data)
return labels, data
def split_data(self):
"""Split the preprocessed dataset to train and test data"""
x, y = self.load_data()
self.x_train, self.x_test, self.y_train, self.y_test = train_test_split(x, y, test_size=0.20, random_state=0)
print('Training data shape : ', self.x_train.shape, self.y_train.shape)
print('Testing data shape : ', self.x_test.shape, self.y_test.shape)
def train(self):
"""Compile dan fit DenseNet model"""
input_shape = 224, 224, 3
number_classes = 2
model = DenseNet201.densenet(input_shape, number_classes)
model.summary()
model.compile(loss='binary_crossentropy', optimizer='Adam', metrics=["accuracy"])
model.fit(self.x_train, self.y_train, epochs=2, verbose=1)
model.save_weights('densenet201_best_model.h5', overwrite=True)
loss, accuracy = model.evaluate(self.x_test, self.y_test)
print("[INFO] accuracy: {:.2f}%".format(accuracy * 100))
train = Training()
train.split_data()
train.train()
and this is the code for the cnn network
from tensorflow.keras.layers import AveragePooling2D, GlobalAveragePooling2D, MaxPool2D
from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Dense
from tensorflow.keras.layers import ReLU, concatenate, Dropout
from tensorflow.keras.models import Model
import tensorflow.keras.layers as layers
import tensorflow.keras.backend as K
import tensorflow as tf
class DenseNet201:
def densenet(image_shape, number_classes, growth_rate=32):
def batch_relu_conv(x, growth_rate, kernel=1, strides=1):
x = BatchNormalization()(x)
x = ReLU()(x)
x = Conv2D(growth_rate, kernel, strides=strides, padding='same', kernel_initializer="he_uniform")(x)
return x
def dense_block(x, repetition):
for _ in range(repetition):
y = batch_relu_conv(x, 4 * growth_rate)
y = batch_relu_conv(y, growth_rate, 3)
x = concatenate([y, x])
return x
def transition_layer(x):
x = batch_relu_conv(x, K.int_shape(x)[-1] // 2)
x = AveragePooling2D(2, strides=2, padding='same')(x)
return x
inputs = Input(image_shape)
x = Conv2D(64, 7, strides=2, padding='same', kernel_initializer="he_uniform")(inputs)
x = MaxPool2D(3, strides=2, padding='same')(x)
for repetition in [6, 12, 48, 32]:
d = dense_block(x, repetition)
x = transition_layer(d)
x = GlobalAveragePooling2D ()(d)
output = Dense(number_classes, activation='softmax')(x)
model = Model(inputs, output)
return model
It seems you inverted data and labels (x and y) in the function:
def load_data(): which returns: return labels, data
I think you are calling model.fit(self.x_train, self.y_train, epochs=2, verbose=1)
with label and then data. Hence the model complaining about not getting the expected data shape.

TFF RuntimeError: Attempting to capture an EagerTensor without building a function

I have a TFF model to run But I got an error.
I provided the x and y and moved forward to implement it like the tutorial.
TF version = 2.5.1
TFF version = 0.19.0
My snippet code is
split = len(usr_data_set)
client_train_dataset = collections.OrderedDict()
for i in range(0, split):
client_name = "client_" + str(i)
xx, y = usr_data_set[i] # shape for client one [2441, 13055], for client two
# [2420, 13055], for client three [2451, 13055]
data = collections.OrderedDict((('x', xx), ('y', y)))
client_train_dataset[client_name] = data
train_dataset = tff.simulation.datasets.TestClientData(client_train_dataset)
sample_dataset = train_dataset.create_tf_dataset_for_client(train_dataset.client_ids[0])
sample_element = next(iter(sample_dataset))
def preprocess(dataset):
NUM_EPOCHS = 5
BATCH_SIZE = 32
PREFETCH_BUFFER = 10
def batch_format_fn(element):
return collections.OrderedDict(
x=reshape(element['x'], [-1, 13055]),
y=reshape(element['y'], [-1, 2]))
return dataset.repeat(NUM_EPOCHS).batch(BATCH_SIZE).map(
batch_format_fn).prefetch(PREFETCH_BUFFER)
preprocessed_sample_dataset = preprocess(sample_dataset)
# sample_batch = nest.map_structure(lambda x: x.numpy(), next(iter(preprocessed_sample_dataset)))
def make_federated_data(client_data, client_ids):
return [preprocess(client_data.create_tf_dataset_for_client(x)) for x in client_ids]
# return make_federated_data(train_dataset, train_dataset.client_ids), preprocessed_sample_dataset
federated_train_data = make_federated_data(train_dataset, train_dataset.client_ids)
# federated_train_data, preprocessed_sample_dataset = tff_dataset(usr_data_set)
losses = tf.keras.losses.CategoricalCrossentropy()
metric = [tf.keras.metrics.CategoricalAccuracy()]
def CNN():
model = Sequential()
model.add(Reshape((13055, 1), input_shape=(13055,)))
model.add(Conv1D(8, kernel_size=7, padding='same', strides=3, activation='relu'))
model.add(MaxPooling1D(4, strides=2, padding='same'))
model.add(Conv1D(128, kernel_size=7, padding='same', strides=3, activation='relu'))
model.add(MaxPooling1D(4, strides=2, padding='same'))
model.add(Conv1D(64, kernel_size=3, padding='same', strides=1, activation='relu'))
model.add(MaxPooling1D(4, strides=2, padding='same'))
model.add(Conv1D(64, kernel_size=3, padding='same', strides=1, activation='relu'))
model.add(MaxPooling1D(4, strides=2, padding='same'))
model.add(Flatten())
model.add(Dense(units=64, activation='relu'))
model.add(Dense(units=64, activation='relu'))
model.add(Dense(units=2, activation='softmax'))
return model
def model_fn():
keras_model = CNN()
return tff.learning.from_keras_model(
keras_model,
input_spec=preprocessed_sample_dataset.element_spec,
loss=losses,
metrics=metric)
iterative_process = tff.learning.build_federated_averaging_process(
model_fn,
client_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=0.02),
server_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=1.0))
print(str(iterative_process.initialize.type_signature))
I read another post about this error but my all function are in the scope of model_fn and I could not see any other problems.
The full script error is like this,
File "/Users/amir/Documents/CODE/Python/FedGS/tff_dataset.py", line 175, in <module>
server_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=1.0))
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow_federated/python/learning/federated_averaging.py", line 270, in build_federated_averaging_process
model_update_aggregation_factory=model_update_aggregation_factory)
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow_federated/python/learning/framework/optimizer_utils.py", line 631, in build_model_delta_optimizer_process
model_weights_type = model_utils.weights_type_from_model(model_fn)
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow_federated/python/learning/model_utils.py", line 100, in weights_type_from_model
model = model()
File "/Users/amir/Documents/CODE/Python/FedGS/tff_dataset.py", line 170, in model_fn
metrics=metric)
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow_federated/python/learning/keras_utils.py", line 175, in from_keras_model
metrics=metrics))
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow_federated/python/learning/keras_utils.py", line 304, in __init__
tf.TensorSpec.from_tensor, self.report_local_outputs())
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 889, in __call__
result = self._call(*args, **kwds)
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 957, in _call
filtered_flat_args, self._concrete_stateful_fn.captured_inputs) # pylint: disable=protected-access
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 1974, in _call_flat
flat_outputs = forward_function.call(ctx, args_with_tangents)
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 625, in call
executor_type=executor_type)
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow/python/ops/functional_ops.py", line 1189, in partitioned_call
args = [ops.convert_to_tensor(x) for x in args]
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow/python/ops/functional_ops.py", line 1189, in <listcomp>
args = [ops.convert_to_tensor(x) for x in args]
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow/python/profiler/trace.py", line 163, in wrapped
return func(*args, **kwargs)
File "/Users/amir/tensorflow/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 1525, in convert_to_tensor
raise RuntimeError("Attempting to capture an EagerTensor without "
RuntimeError: Attempting to capture an EagerTensor without building a function.
Can anyone help me fix this? I did anything to solve it but have not succeeded.
I believe you will need to create the objects held by losses and metric variables inside the model_fn. Something like this:
def model_fn():
keras_model = CNN()
return tff.learning.from_keras_model(
keras_model,
input_spec=preprocessed_sample_dataset.element_spec,
loss=tf.keras.losses.CategoricalCrossentropy(),
metrics=[tf.keras.metrics.CategoricalAccuracy()])
The problem is Keras metrics usually create tf.Variables which need to be captured in serialization.

Not able to load weights for fine tuning in Keras with ResNet50

I first trained with ResNet-50 layers frozen on my dataset using the following :
model_r50 = ResNet50(weights='imagenet', include_top=False)
model_r50.summary()
input_layer = Input(shape=(img_width,img_height,3),name = 'image_input')
output_r50 = model_r50(input_layer)
fl = Flatten(name='flatten')(output_r50)
dense = Dense(1024, activation='relu', name='fc1')(fl)
drop = Dropout(0.5, name='drop')(dense)
pred = Dense(nb_classes, activation='softmax', name='predictions')(drop)
fine_model = Model(outputs=pred,inputs=input_layer)
for layer in model_r50.layers:
layer.trainable = False
print layer
fine_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
fine_model.summary()
I then try to fine tune it with layers unfrozen using the following:
model_r50 = ResNet50(weights='imagenet', include_top=False)
model_r50.summary()
input_layer = Input(shape=(img_width,img_height,3),name = 'image_input')
output_r50 = model_r50(input_layer)
fl = Flatten(name='flatten')(output_r50)
dense = Dense(1024, activation='relu', name='fc1')(fl)
drop = Dropout(0.5, name='drop')(dense)
pred = Dense(nb_classes, activation='softmax', name='predictions')(drop)
fine_model = Model(outputs=pred,inputs=input_layer)
weights = 'val54_r50.01-0.86.hdf5'
fine_model.load_weights('models/'+weights)
fine_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
fine_model.summary()
But I get this error out of nowhere. I just unfroze the network and didnt change anything!
load_weights_from_hdf5_group(f, self.layers)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/topology.py", line 3008, in load_weights_from_hdf5_group
K.batch_set_value(weight_value_tuples)
File "/usr/local/lib/python2.7/dist-packages/keras/backend/tensorflow_backend.py", line 2189, in batch_set_value
get_session().run(assign_ops, feed_dict=feed_dict)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/client/session.py", line 778, in run
run_metadata_ptr)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/client/session.py", line 961, in _run
% (np_val.shape, subfeed_t.name, str(subfeed_t.get_shape())))
ValueError: Cannot feed value of shape (128,) for Tensor u'Placeholder_140:0', which has shape '(512,)'
And it's not consistent. I get a different shape most of the time. Why is this happening? If I just change ResNet to VGG19 this won't happen. Is there a problem with ResNet in Keras?
Your fine_model is a Model with another Model (i.e. ResNet50) inside it. It seems that the problem is save_weight() and load_weight() cannot handle this type of nested Models correctly.
Maybe you can try to build model in a way that does not result in a "nested Model". For example,
input_layer = Input(shape=(img_width, img_height, 3), name='image_input')
model_r50 = ResNet50(weights='imagenet', include_top=False, input_tensor=input_layer)
output_r50 = model_r50.output
fl = Flatten(name='flatten')(output_r50)
...
The following procedure usually worked for me:
Load your weights into the frozen model.
Change the layers to be trainable.
Compile the model.
I.e. in this case:
model_r50 = ResNet50(weights='imagenet', include_top=False)
model_r50.summary()
input_layer = Input(shape=(img_width,img_height,3),name = 'image_input')
output_r50 = model_r50(input_layer)
fl = Flatten(name='flatten')(output_r50)
dense = Dense(1024, activation='relu', name='fc1')(fl)
drop = Dropout(0.5, name='drop')(dense)
pred = Dense(nb_classes, activation='softmax', name='predictions')(drop)
fine_model = Model(outputs=pred,inputs=input_layer)
for layer in model_r50.layers:
layer.trainable = False
print layer
weights = 'val54_r50.01-0.86.hdf5'
fine_model.load_weights('models/'+weights)
for layer in model_r50.layers:
layer.trainable = True
fine_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
fine_model.summary()

Categories