我试图在我的Keras模型中实现一个使用特定高斯滤波器的conv2D层。虽然现有的Keras Conv2D没有过滤器本身的参数,但我有使用过滤器的代码。相反,有一个filters
参数,它是一个指定输出空间维度的整数,以及kernel_size
,它是一个指定内核维度的元组。
我尝试使用Keras后端来解决这个问题,因为conv2D函数here允许您按照我的意愿输入特定的过滤器。问题是我不知道如何将它重新放回我的模型中,所以再一次,我被卡住了。我也发现了类似于我的问题,如this,其中建议编写我自己的图层,但我不确定如何做到这一点,如果有更简单的方法,我希望避免它。
与往常一样,非常感谢任何帮助。
答案 0 :(得分:1)
长答案简短:您根本不需要卷积层。卷积层的目的是为您找到合适的过滤器。由于您已经知道要使用哪个过滤器,因此您可以愉快地跳过整个卷积内容并直接跳到完全连接的层。 将高斯滤镜应用于图像。然后使用 Flatten()图层将图像直接提供给MLP。
请勿尝试将第五个轮子添加到购物车中。
希望得到这个帮助。
答案 1 :(得分:0)
我刚刚发布了linked问题的答案,但在此处作为如何在Keras中应用自定义过滤器的示例可能很有用。对于高斯示例,请使用适用于2D的this来获取滤镜,
import numpy as np
import scipy.stats as st
def gkern(kernlen=[21,21], nsig=[3, 3]):
"""Returns a 2D Gaussian kernel array."""
assert len(nsig) == 2
assert len(kernlen) == 2
kern1d = []
for i in range(2):
interval = (2*nsig[i]+1.)/(kernlen[i])
x = np.linspace(-nsig[i]-interval/2., nsig[i]+interval/2., kernlen[i]+1)
kern1d.append(np.diff(st.norm.cdf(x)))
kernel_raw = np.sqrt(np.outer(kern1d[0], kern1d[1]))
kernel = kernel_raw/kernel_raw.sum()
return kernel
import matplotlib.pyplot as plt
plt.imshow(gkern([7,7]), interpolation='none')
plt.show()
然后您可以将其设置为初始过滤器并冻结该层,使其不再训练,看起来像这样,
from keras.models import Sequential
from keras.layers import Conv2D
#Set Some Image
image = [[4,3,1,0],[2,1,0,1],[1,2,4,1],[3,1,0,2]]
# Pad to "channels_last" format
# which is [batch, width, height, channels]=[1,4,4,1]
image = np.expand_dims(np.expand_dims(np.array(image),2),0)
#Initialise to set kernel to required value
def kernel_init(shape):
kernel = np.zeros(shape)
kernel[:,:,0,0] = gkern([shape[0], shape[1]])
return kernel
#Build Keras model
model = Sequential()
#We would freeze training of the layers if we
# wanted to keep a Gaussian filter
Gausslayer = Conv2D(1, [3,3], kernel_initializer=kernel_init,
input_shape=(4,4,1), padding="valid")
Gausslayer.trainable = False
model.add(Gausslayer)
#Add some more layers here
#model.add(Conv2D(...)
model.build()
# To apply existing filter, we use predict with no training
out = model.predict(image)
print(out[0,:,:,0])
,并且可以添加更多可训练的层。