Merge Keras中两个张量的卷积合并
我试图在Keras中卷积两个一维张量。 我从其他模型获得两个输入:Merge Keras中两个张量的卷积合并,merge,keras,Merge,Keras,我试图在Keras中卷积两个一维张量。 我从其他模型获得两个输入: x-长度为100 ker-长度为5 我想使用内核ker得到x的1D卷积。 我写了一个Lambda层来实现它: import tensorflow as tf def convolve1d(x): y = tf.nn.conv1d(value=x[0], filters=x[1], padding='VALID', stride=1) return y x = Input(shape=(100,)) ker =
x
-长度为100ker
-长度为5ker
得到x
的1D卷积。
我写了一个Lambda层来实现它:
import tensorflow as tf
def convolve1d(x):
y = tf.nn.conv1d(value=x[0], filters=x[1], padding='VALID', stride=1)
return y
x = Input(shape=(100,))
ker = Input(shape=(5,))
y = Lambda(convolve1d)([x,ker])
model = Model([x,ker], [y])
我得到以下错误:
ValueError: Shape must be rank 4 but is rank 3 for 'lambda_67/conv1d/Conv2D' (op: 'Conv2D') with input shapes: [?,1,100], [1,?,5].
有人能帮我理解如何修复它吗?根据给定的代码,很难指出您所说的是什么意思 可能吗 但若你们的意思是合并两个层并将合并的层馈送给convulation,那个么这是可能的
x = Input(shape=(100,))
ker = Input(shape=(5,))
merged = keras.layers.concatenate([x,ker], axis=-1)
y = K.conv1d(merged, 'same')
model = Model([x,ker], y)
编辑:
@user2179331感谢您澄清您的意图。现在您错误地使用了Lambda类,这就是显示错误消息的原因。
但是,可以使用keras.backend层来实现您正在尝试的操作。
但是要注意的是,当使用较低级别的层时,您将丢失一些较高级别的抽象。例如,当使用keras.backend.conv1d时,您需要输入形状为(批量大小、宽度、通道),内核形状为(内核大小、输入通道、输出通道)。因此,在您的例子中,假设x
有1个通道(输入通道==1),y也有相同数量的通道(输出通道==1)
因此,您的代码现在可以重构如下
from keras import backend as K
def convolve1d(x,kernel):
y = K.conv1d(x,kernel, padding='valid', strides=1,data_format="channels_last")
return y
input_channels = 1
output_channels = 1
kernel_width = 5
input_width = 100
ker = K.variable(K.random_uniform([kernel_width,input_channels,output_channels]),K.floatx())
x = Input(shape=(input_width,input_channels)
y = convolve1d(x,ker)
这比我预期的要困难得多,因为Keras和Tensorflow不希望卷积内核中有任何批处理维度,所以我必须自己在批处理维度上编写循环,这需要指定
batch_shape
,而不仅仅是Input
层中的shape
。这是:
import numpy as np
import tensorflow as tf
import keras
from keras import backend as K
from keras import Input, Model
from keras.layers import Lambda
def convolve1d(x):
input, kernel = x
output_list = []
if K.image_data_format() == 'channels_last':
kernel = K.expand_dims(kernel, axis=-2)
else:
kernel = K.expand_dims(kernel, axis=0)
for i in range(batch_size): # Loop over batch dimension
output_temp = tf.nn.conv1d(value=input[i:i+1, :, :],
filters=kernel[i, :, :],
padding='VALID',
stride=1)
output_list.append(output_temp)
print(K.int_shape(output_temp))
return K.concatenate(output_list, axis=0)
batch_input_shape = (1, 100, 1)
batch_kernel_shape = (1, 5, 1)
x = Input(batch_shape=batch_input_shape)
ker = Input(batch_shape=batch_kernel_shape)
y = Lambda(convolve1d)([x,ker])
model = Model([x, ker], [y])
a = np.ones(batch_input_shape)
b = np.ones(batch_kernel_shape)
c = model.predict([a, b])
在当前状态下:
- 它不适用于具有多个通道的输入(
)x
- 如果您提供了几个过滤器,那么您将获得尽可能多的输出,每个输出都是输入与相应内核的卷积
- 我想我已经明白你的意思了。下面给出了错误的示例代码:
input_signal = Input(shape=(L), name='input_signal')
input_h = Input(shape=(N), name='input_h')
faded= Lambda(lambda x: tf.nn.conv1d(input, x))(input_h)
您需要将每个信号向量与不同的衰落系数向量进行卷积。
TensorFlow等tf.nn.conv1d中的“conv”操作仅支持固定值内核。因此,上面的代码无法按您的要求运行
我也不知道。您给出的代码可以正常运行,但是,它太复杂,效率不高。在我的想法中,另一种可行但低效的方法是与Toeplitz矩阵相乘,该矩阵的行向量是移位衰落系数向量。当信号向量太长时,矩阵将非常大 是否要提供卷积内核作为模型的输入?如果这就是你的意思,我会为此写一个Lambda层。是的,没错。我有两个1D输入,一个长度为100,另一个长度为5。我想用第二个作为内核得到第一个输入的卷积。谢谢Mitiku,但这不是我想要做的。我编辑了我的问题,以便更好地解释我的意图。我认为OP希望同时输入
x
和ker
。在您的示例中,ker
需要每次重新分配,并且不能直接反馈到网络。如果只需要1的批大小,则可以创建回调来修改批结束时的ker
值。但如果批量更大,每个样本都有不同的ker
,这将无法满足OP的要求。你明白我的意思吗?