Python 如何在keras中添加自定义图像锐化层?
我正在keras中建立一个模型,从图像中检测建筑物屋顶。我想在模型中添加一个自定义锐化层。我知道我们可以在预处理中锐化图像,但如果我添加一个图层就好了。我用自定义锐化功能尝试了Lambda层,但它不起作用,然后我尝试了自定义层,得到了相同的错误:Python 如何在keras中添加自定义图像锐化层?,python,tensorflow,neural-network,keras,deep-learning,Python,Tensorflow,Neural Network,Keras,Deep Learning,我正在keras中建立一个模型,从图像中检测建筑物屋顶。我想在模型中添加一个自定义锐化层。我知道我们可以在预处理中锐化图像,但如果我添加一个图层就好了。我用自定义锐化功能尝试了Lambda层,但它不起作用,然后我尝试了自定义层,得到了相同的错误: TypeError Traceback (most recent call last) <ipython-input-5-3062d6b8160d> in <module
TypeError Traceback (most recent call last)
<ipython-input-5-3062d6b8160d> in <module>()
1 # MY MODEL
2 from u_net import mymodel300
----> 3 model = mymodel300((300, 300, 3))
~\Desktop\SAVERA\MYCODE\u_net.py in mymodel300(input_shape)
186 # LAYERS
187 inputs = Input(shape=input_shape)
--> 188 sharp = Sharpen(num_outputs=(300,300,3))(inputs)
189 # 300x300
190
~\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in __call__(self, inputs, *args, **kwargs)
701
702 if not in_deferred_mode:
--> 703 outputs = self.call(inputs, *args, **kwargs)
704 if outputs is None:
705 raise ValueError('A layer\'s `call` method should return a Tensor '
~\Desktop\SAVERA\MYCODE\u_net.py in call(self, input_)
179 kernel_sharp = np.array(([-2, -2, -2], [-2, 17, -2], [-2, -2, -2]), dtype='int')
180 #denoised = cv2.fastNlMeansDenoisingColored(img,None,5,5,2,10)
--> 181 self.sharp = cv2.filter2D(input_, -1, kernel_sharp)
182 return self.sharp
183
TypeError: src is not a numpy array, neither a scalar
下面是我要放置此层的模型:
def mymodel300(input_shape=(300, 300, 3)):
inputs = Input(shape=input_shape)
# MY CUSTOM LAYER
sharp = Sharpen(num_outputs=(300,300,3))(inputs)
# 300x300
down0 = Conv2D(32, (3, 3), padding='same')(sharp)
down0 = BatchNormalization()(down0)
down0 = Activation('relu')(down0)
down0 = Conv2D(32, (3, 3), padding='same')(down0)
down0 = BatchNormalization()(down0)
down0 = Activation('relu')(down0)
down0_pool = MaxPooling2D((2, 2), strides=(2, 2))(down0)
我认为这应该作为预处理步骤的一部分来完成,因为在锐化层中没有您想要训练的参数来帮助特征生成或分类,所以它不需要是网络模型的一部分
Keras图像预处理文档在这里:我发现了如何使用自定义内核创建自定义层。感谢apple提示您使用conv2d 我使用Tensorflow的tf.nn.conv2d,而不是cv2.filter2D,以及我的自定义锐化过滤器。这是自定义图层:
from tensorflow.keras.layers import Layer
from tensorflow.keras import backend as K
# CUSTOM SHARPEN LAYER
class Sharpen(Layer):
def __init__(self, num_outputs):
super(Sharpen, self).__init__()
self.num_outputs = num_outputs
def call(self, input_):
import numpy as np
import cv2
# SHARPEN
kernel_sharp = np.array(([-2, -2, -2], [-2, 17, -2], [-2, -2, -2]), dtype='int')
#denoised = cv2.fastNlMeansDenoisingColored(img,None,5,5,2,10)
self.sharp = cv2.filter2D(input_, -1, kernel_sharp)
return self.sharp
# CUSTOM SHARPEN LAYER
class Sharpen(tf.keras.layers.Layer):
def __init__(self, num_outputs):
super(Sharpen, self).__init__()
self.num_outputs = num_outputs
def build(self, input_shape):
self.kernel = np.array([[-2, -2, -2],
[-2, 17, -2],
[-2, -2, -2]])
self.kernel = tf.expand_dims(self.kernel, 0)
self.kernel = tf.expand_dims(self.kernel, 0)
self.kernel = tf.cast(self.kernel, tf.float32)
def call(self, input_):
return tf.nn.conv2d(input_, self.kernel, strides=[1, 1, 1, 1], padding='SAME')
“我知道我们可以在预处理中锐化图像,但如果我添加一个层就好了”OP说。就像我们可以向Lambda层输入函数以获得自定义层,那么为什么我们不能添加直接自定义层。@appleapple说OP应该做什么,而不是他/她想做什么,是正确的答案——至少是个好答案。@P-Gn如果OP不知道这个方法,我会同意的。您需要在网络中设置一个固定的处理层(例如maxpool)是有原因的。您不应该使用
cv2
进行处理。它显然不会给你张量。也许您可以使用trainable=false
尝试类似于Conv2D
的方法。我们可以为Conv2D添加自定义内核吗?否则Conv2D会有什么帮助呢?我们也可以通过tf将cv2的结果转换成tensor来从cv2返回tensor。convert_to_tensor但是你不能通过keras(tensorflow)
将cv2
函数放在GPU上,对吗?或者可能有帮助。