我正在尝试使用在图像上使用一些OpenCV函数的函数。但我得到的数据是张量,我无法将其转换为图像。
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)))
当我运行此代码段时,它会在cvtColor
函数中抛出一个错误,指出img
不是一个numpy数组。我打印出img
,似乎是张量。
我不知道如何将张量更改为图像然后返回张量。我希望模型有这个层。
如果我无法用lambda图层实现这一目标,我还能做些什么?
答案 0 :(得分:0)
我将假设image_func
函数执行您想要的(调整大小)和图像。请注意,图像由numpy数组表示。由于您使用的是tensorflow后端,因此您在Tensors上运行(这是您所知道的)。
现在的工作是将Tensor转换为numpy数组。要做到这一点,我们需要 使用其评估张量来评估Tensor。但为了做到这一点,我们需要一个抓住张量流会话。
使用keras后端模块的get_session()
方法获取当前的tensorflow会话。
以下是get_session()
def get_session():
"""Returns the TF session to be used by the backend.
If a default TensorFlow session is available, we will return it.
Else, we will return the global Keras session.
If no global Keras session exists at this point:
we will create a new global session.
Note that you can manually set the global session
via `K.set_session(sess)`.
# Returns
A TensorFlow session.
"""
所以试试:
def image_func(img)
from keras import backend as K
sess = K.get_session()
img = sess.run(img) # now img is a proper numpy array
img=cv2.cvtColor(img,cv2.COLOR_BGR2YUV)
img=cv2.resize(img,(200,66))
return img
注意,我无法测试
编辑:刚刚对此进行了测试,它将无效(正如您所注意到的)。 lambda函数需要返回 张量。计算流程会抛出一个Tensor,因此它也需要在差异化的意义上保持平滑。
我发现基本上lambda正在改变颜色并调整图像大小,为什么不在预处理步骤中执行此操作?
答案 1 :(得分:0)
您对Lambda
图层中的符号操作与python函数中的数值运算相混淆。
基本上,您的自定义操作接受数字输入但不接受符号输入。要解决此问题,您需要的是tensorflow
py_func
此外,您还没有考虑过反向传播。简而言之,虽然这个图层是非参数和不可学习的,但您也需要注意它的渐变。
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()
现在,您可以使用一些虚拟数据测试此图层。
a = np.random.randn(2,100,200,3)
b = model.predict(a)
print b.shape
model.compile('sgd',loss='mse')
model.fit(a,b)