I am trying to implement a Fully Convolutional Neural Network from scratch after studying the Research paper. Since FCN works on input of any size I am having a hard time implementing the DataLoader for it.I am trying to batch the inputs using batch() function but it gives an error because of variable length tensors. Is there any feasible way to batch the tensors of arbitrary shape ?
My Code :
import tensorflow as tf
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
import os
from albumentations import ElasticTransform,VerticalFlip,RandomSizedCrop,Compose,RandomRotate90
# Train and Val contains the respective paths for [TrainImage,Labels] and [ValImage,Labels] respectively.
num_classes = 21
Train = tf.data.Dataset.from_tensor_slices(Train)
Val = tf.data.Dataset.from_tensor_slices(Val)
def Create_Mask(Img):
Seg_Labels = np.zeros((Img.shape[0],Img.shape[1],num_classes),dtype=np.float32)
for class_ in range(num_classes):
Seg_Labels[:,:,class_] = (Img == class_)
return tf.cast(Seg_Labels,dtype=tf.float32)
def Create_PreProcess_Mask_Img(Instance):
Img = np.asarray(Image.open(Instance[0].numpy()))
Mask = np.asarray(Image.open(Instance[1].numpy()))
# Since Mask is in 'P' mode it will automatically convert to labels using Color Palette
Normalization = tf.keras.layers.experimental.preprocessing.Rescaling(1./255)
if tf.random.uniform(()) > 0.5: # Applying data Augmentation
Num = tf.random.uniform((),minval=0,maxval=3,dtype=tf.int32)
if Num == 0:
aug = ElasticTransform(p=1)
Augmented = aug(image = Img,mask = Mask)
elif Num == 1:
Height,Width = Img.shape[0],Img.shape[1]
aug = RandomSizedCrop(min_max_height=(50,101),height=Height,width=Width,p = 1)
Augmented = aug(image = Img,mask = Mask)
elif Num == 2:
aug = Compose([VerticalFlip(p=0.5),RandomRotate90(p=0.5)])
Augmented = aug(image = Img,mask = Mask)
Img = Augmented["image"]
Mask = Augmented["mask"]
return Normalization(Img),Create_Mask(Mask)
def Preprocess(Instance):
Img,Mask = tf.py_function(Create_PreProcess_Mask_Img,[Instance],[tf.float32,tf.float32])
return tf.ensure_shape(Img,[None,None,3]),tf.ensure_shape(Mask,[None,None,num_classes])
#tf.ensure_shape returns the matrix if shape matches else error
def DataLoader(dataset,BATCH_SIZE = 32,BUFFER_SIZE = 256):
data = dataset.map(Preprocess,num_parallel_calls = tf.data.AUTOTUNE)
data = data.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat(1)
data = data.prefetch(buffer_size = tf.data.AUTOTUNE)
return data
Train = DataLoader(Train)
Val = DataLoader(Val)
for X,Y in Train.take(1):
print(X.shape)
print(Y.shape)
Stack Trace:
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/eager/context.py in execution_mode(mode)
2112 ctx.executor = executor_new
-> 2113 yield
2114 finally:
9 frames
InvalidArgumentError: Cannot batch tensors with different shapes in component 0. First element had shape [500,375,3] and element 1 had shape [500,383,3]. [Op:IteratorGetNext]
During handling of the above exception, another exception occurred:
InvalidArgumentError Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/eager/executor.py in wait(self)
67 def wait(self):
68 """Waits for ops dispatched in this executor to finish."""
---> 69 pywrap_tfe.TFE_ExecutorWaitForAllPendingNodes(self._handle)
70
71 def clear_error(self):
InvalidArgumentError: Cannot batch tensors with different shapes in component 0. First element had shape [500,375,3] and element 1 had shape [500,383,3].