如何在Keras中实现不对输入通道维度求和的2D局部连接层
实现方案
完全可以实现,目前有两种成熟的落地方式,无需修改Keras源码:
方案1:通道拆分后拼接(兼容性最优)
实现逻辑非常简单:将输入按通道维度拆分为单个通道的张量,每个通道单独经过一个输出通道数为1的LocallyConnected2D层,最后将所有输出在通道维度拼接即可。由于每个通道的计算完全独立,自然不会出现跨通道求和的逻辑。
参考代码如下:
import tensorflow as tf from tensorflow.keras import layers def channel_wise_local_conv(inputs, kernel_size, padding="valid", strides=(1,1), activation=None): # 输入格式默认是 (batch_size, height, width, channels) in_channels = inputs.shape[-1] output_list = [] for idx in range(in_channels): # 提取单通道输入,保留维度不压缩 single_in = inputs[..., idx:idx+1] # 单通道局部连接计算,无跨通道交互 single_out = layers.LocallyConnected2D( filters=1, kernel_size=kernel_size, padding=padding, strides=strides, activation=activation )(single_in) output_list.append(single_out) # 通道维度拼接得到最终输出 return layers.Concatenate(axis=-1)(output_list)
调用时直接传入输入张量即可,如果你需要每个输入通道对应N个输出通道,只需修改filters参数为对应的N值即可。
方案2:自定义局部连接层(性能最优)
如果你的输入通道数较多,循环拆分的方式会产生额外性能开销,可以直接自定义局部连接层,修改核的运算逻辑,屏蔽跨通道求和操作:
- 核的形状定义为
(output_height, output_width, kernel_h, kernel_w, in_channels, out_channels),要求in_channels和out_channels相等 - 运算时只对同序号的输入通道和输出通道做局部卷积计算,禁用跨通道的广播求和
这种方案适合通道数大于10的场景,使用时注意自定义层需要做序列化注册才能正常保存加载模型。
内容的提问来源于stack exchange,提问作者hihi
相关产品推荐
相关产品推荐

