我如何 运行 对张量的每个切片进行迭代二维卷积?
How do I run an iterative 2D convolution for each slice of a tensor?
我正在使用 Python 中的 TF/Keras 进行卷积神经网络的机器学习项目,我的目标是将图像分割成多个块,运行分别对每一个进行卷积,然后将其重新组合在一起。
我不知道该怎么做 运行 对 3D 数组的每个切片进行卷积。
例如,如果我有一个大小为 (500,100,100)
的张量,我想对所有 500 个大小为 (100 x 100)
的切片进行单独的卷积。我在自定义 Keras 层中实现它并希望这些是可训练的权重我尝试了一些不同的东西:
- 使用
map.fn()
到运行对数组的每个切片进行卷积
- 这似乎没有将权重分别附加到每一层。
- 使用
DepthwiseConv2D
层:
- 这对于层的第一次调用效果很好,但是当我第二次使用更多过滤器调用层时失败,因为它想在每个先前过滤的层上执行
depthwise
卷积
- 这当然不是我想要的,因为我想要对上一层的前一组过滤器进行一次卷积。
感谢任何想法,因为我真的被困在这里。谢谢!
如果你有一个形状为 (500,100,100)
的张量,并且想要提供这个张量的一些子集,同时分离 conv2d
层,你可以通过定义 conv2d
层在同一层。您应该首先定义 Lambda
层来拆分输入,然后将它们的输出馈送到 Conv2D
层,然后是 concatenate
它们。
我们以一个形状为 (100,28,28,1)
的张量为例,我们想将其拆分为 2 个子集张量并分别在每个子集上应用 conv2d
层:
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Conv2D, Input, concatenate, Lambda
from tensorflow.keras.models import Model
# define a sample dataset
x = tf.random.uniform((100, 28, 28, 1))
y = tf.random.uniform((100, 1), dtype=tf.int32, minval=0, maxval=9)
ds = tf.data.Dataset.from_tensor_slices((x, y))
ds = ds.batch(16)
def create_nn_model():
input = Input(shape=(28,28,1))
b1 = Lambda(lambda a: a[:,:14,:,:], name="first_slice")(input)
b2 = Lambda(lambda a: a[:,14:,:,:], name="second_slice")(input)
d1 = Conv2D(64, 2, padding='same', activation='relu', name="conv1_first_slice")(b1)
d2 = Conv2D(64, 2, padding='same', activation='relu', name="conv2_second_slice")(b2)
x = concatenate([d1,d2], axis=1)
x = Flatten()(x)
x = Dense(64, activation='relu')(x)
out = Dense(10, activation='softmax')(x)
model = Model(input, out)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
model = create_nn_model()
tf.keras.utils.plot_model(model, show_shapes=True)
这是绘制的模型架构:
我正在使用 Python 中的 TF/Keras 进行卷积神经网络的机器学习项目,我的目标是将图像分割成多个块,运行分别对每一个进行卷积,然后将其重新组合在一起。
我不知道该怎么做 运行 对 3D 数组的每个切片进行卷积。
例如,如果我有一个大小为 (500,100,100)
的张量,我想对所有 500 个大小为 (100 x 100)
的切片进行单独的卷积。我在自定义 Keras 层中实现它并希望这些是可训练的权重我尝试了一些不同的东西:
- 使用
map.fn()
到运行对数组的每个切片进行卷积- 这似乎没有将权重分别附加到每一层。
- 使用
DepthwiseConv2D
层:- 这对于层的第一次调用效果很好,但是当我第二次使用更多过滤器调用层时失败,因为它想在每个先前过滤的层上执行
depthwise
卷积 - 这当然不是我想要的,因为我想要对上一层的前一组过滤器进行一次卷积。
- 这对于层的第一次调用效果很好,但是当我第二次使用更多过滤器调用层时失败,因为它想在每个先前过滤的层上执行
感谢任何想法,因为我真的被困在这里。谢谢!
如果你有一个形状为 (500,100,100)
的张量,并且想要提供这个张量的一些子集,同时分离 conv2d
层,你可以通过定义 conv2d
层在同一层。您应该首先定义 Lambda
层来拆分输入,然后将它们的输出馈送到 Conv2D
层,然后是 concatenate
它们。
我们以一个形状为 (100,28,28,1)
的张量为例,我们想将其拆分为 2 个子集张量并分别在每个子集上应用 conv2d
层:
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Conv2D, Input, concatenate, Lambda
from tensorflow.keras.models import Model
# define a sample dataset
x = tf.random.uniform((100, 28, 28, 1))
y = tf.random.uniform((100, 1), dtype=tf.int32, minval=0, maxval=9)
ds = tf.data.Dataset.from_tensor_slices((x, y))
ds = ds.batch(16)
def create_nn_model():
input = Input(shape=(28,28,1))
b1 = Lambda(lambda a: a[:,:14,:,:], name="first_slice")(input)
b2 = Lambda(lambda a: a[:,14:,:,:], name="second_slice")(input)
d1 = Conv2D(64, 2, padding='same', activation='relu', name="conv1_first_slice")(b1)
d2 = Conv2D(64, 2, padding='same', activation='relu', name="conv2_second_slice")(b2)
x = concatenate([d1,d2], axis=1)
x = Flatten()(x)
x = Dense(64, activation='relu')(x)
out = Dense(10, activation='softmax')(x)
model = Model(input, out)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
model = create_nn_model()
tf.keras.utils.plot_model(model, show_shapes=True)
这是绘制的模型架构: