I am trying to use a function that uses some OpenCV function on the image. But the data I am getting is a tensor and I am not able to convert it into an image.
def image_func(img):
img=cv2.cvtColor(img,cv2.COLOR_BGR2YUV)
img=cv2.resize(img,(200,66))
return img
model=Sequential()
model.add(Lambda(get_ideal_img,input_shape=(r,c,ch),output_shape=(r,c,ch)))
When I run this snippet it throws an error in the cvtColor
function saying that img
is not a numpy array. I printed out img
and it seemed to be a tensor.
I do not know how to change the tensor to an image and then return the tensor as well. I want the model to have this layer.
If I cannot achieve this with a lambda layer what else can I do?
tf.keras.layers.Lambda(function, output_shape=None, mask=None, arguments=None, **kwargs) Wraps arbitrary expressions as a Layer object. The Lambda layer exists so that arbitrary expressions can be used as a Layer when constructing Sequential and Functional API models. Lambda layers are best suited for simple operations or quick experimentation.
There are two ways to write custom layers, Lambda Layers and Custom Class Layers. We use Lambda Layers for simple customization and we use Custom Class Layers when we want to apply trainable weights on the input. Keep checking our further articles to get exciting Keras projects.
AWS Lambda is a Function-as-a-Service (FaaS) offering from Amazon that lets you run code without the complexity of building and maintaining the underlying infrastructure. OpenCV is one of the larger python libraries.
Let say you want to add your own activation function (which is not built-in Keras) to a layer. Then you first need to define a function that will take the output from the previous layer as input and apply a custom activation function to it. We then pass this function to the lambda layer.
You confused with the symbolic operation in the Lambda
layer with the numerical operation in a python function.
Basically, your custom operation accepts numerical inputs but not symbolic ones. To fix this, what you need is something like py_func
in tensorflow
In addition, you have not considered the backpropagation. In short, although this layer is non-parametric and non-learnable, you need to take care of its gradient as well.
import tensorflow as tf
from keras.layers import Input, Conv2D, Lambda
from keras.models import Model
from keras import backend as K
import cv2
def image_func(img):
img=cv2.cvtColor(img,cv2.COLOR_BGR2YUV)
img=cv2.resize(img,(200,66))
return img.astype('float32')
def image_tensor_func(img4d) :
results = []
for img3d in img4d :
rimg3d = image_func(img3d )
results.append( np.expand_dims( rimg3d, axis=0 ) )
return np.concatenate( results, axis = 0 )
class CustomLayer( Layer ) :
def call( self, xin ) :
xout = tf.py_func( image_tensor_func,
[xin],
'float32',
stateful=False,
name='cvOpt')
xout = K.stop_gradient( xout ) # explicitly set no grad
xout.set_shape( [xin.shape[0], 66, 200, xin.shape[-1]] ) # explicitly set output shape
return xout
def compute_output_shape( self, sin ) :
return ( sin[0], 66, 200, sin[-1] )
x = Input(shape=(None,None,3))
f = CustomLayer(name='custom')(x)
y = Conv2D(1,(1,1), padding='same')(x)
model = Model( inputs=x, outputs=y )
print model.summary()
Now you can test this layer with some dummy data.
a = np.random.randn(2,100,200,3)
b = model.predict(a)
print b.shape
model.compile('sgd',loss='mse')
model.fit(a,b)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With