卷积系列——形变卷积(Deformableconvolution)代码理解和使用

更新时间:2023-07-30 14:54:48 阅读: 评论:0

卷积系列——形变卷积(Deformableconvolution)代码理解和
使⽤
可以直接看⽬录scripts下的scaled_mnist.py,⽹络模型由函数get_deform_cnn()加载:
# ---
# Deformable CNN
inputs, outputs = get_deform_cnn(trainable=Fal)
写秋天的四字词语model = Model(inputs=inputs, outputs=outputs)
get_deform_cnn()定义在⽬录deform_conv下的cnn.py中,整体就是⼀个普通的cnn⽹络,只不过卷积前加了ConvOffft2D:
def get_deform_cnn(trainable):
inputs = l = Input((28, 28, 1), name='input')
# conv11
母亲节手抄报内容
l = Conv2D(32, (3, 3), padding='same', name='conv11', trainable=trainable)(l)
l = Activation('relu', name='conv11_relu')(l)
l = BatchNormalization(name='conv11_bn')(l)
# conv12
l_offt = ConvOfft2D(32, name='conv12_offt')(l)
l = Conv2D(64, (3, 3), padding='same', strides=(2, 2), name='conv12', trainable=trainable)(l_offt)
l = Activation('relu', name='conv12_relu')(l)
l = BatchNormalization(name='conv12_bn')(l)
...
return inputs, outputs燃气热水器什么牌子好
上⾯代码中由ConvOfft2D得到的l_offt应该是偏移/形变后的feature maps,因为紧接着Conv2D的
输⼊就是l_offt,接下来看⼀下ConvOfft2D类的定义(ConvOfft2D类在deform_conv⽬录下的layers.py中):
class ConvOfft2D(Conv2D):
"""ConvOfft2D"""
def __init__(lf, filters, init_normal_stddev=0.01, **kwargs):
"""Init"""
lf.filters = filters
super(ConvOfft2D, lf).__init__(
lf.filters * 2, (3, 3), padding='same', u_bias=Fal,
# TODO gradients are near zero if init is zeros
kernel_initializer='zeros',
# kernel_initializer=RandomNormal(0, init_normal_stddev),
**kwargs
)
def call(lf, x):
# TODO offts probably have no nonlinearity?
x_shape = x.get_shape()
offts = super(ConvOfft2D, lf).call(x)
offts = lf._to_bc_h_w_2(offts, x_shape)
x = lf._to_bc_h_w(x, x_shape)
x_offt = tf_batch_map_offts(x, offts)
x_offt = lf._to_b_h_w_c(x_offt, x_shape)
return x_offt
⾸先该类是Conv2D的⼦类,然后调⽤了⽗类的构造函数:参数filters改为2*lf.filters,卷积核⼤⼩为(3, 3),padding=‘same'。构造器所作的是利⽤keras.layers⾃带的Conv2D卷积得到每⼀个feature map的每⼀个pixel的横纵偏移量,因此改卷积的filters的数量变成了2倍,因为每⼀个输⼊的feature map会产⽣两个feature maps输出,分别表⽰输⼊的feature map中每⼀个pixel在横,纵坐标上的偏移量。并且,该卷积输出的feature maps必须和输⼊同尺⼨,因为对应每⼀个pixel,所以卷积核固定为(3,3),同时padding=’same‘。
然后把该ConvOfft2D类的对象直接像函数⼀样调⽤时,就相当于执⾏了call()⽅法,在call()⽅法中,调⽤⽗类的call()⽅法输⼊feature maps得到偏移量,通过lf._to_bc_h_w_2()改变offts维度到(b*c, h, w, 2),然后改变feature maps维度到(b*c, h, w),然后利⽤
tf_batch_map_offts()得到偏移后的feature maps,最后再通过lf._to_b_h_w_c()恢复⽤于卷积的维度(b, h, w, c)。
tf_batch_map_offts()的代码如下(定义于⽬录deform_conv下的deform_conv.py⽂件中):
def tf_batch_map_offts(input, offts, order=1):
长城的画法"""Batch map offts into input
Parameters
---------
普法宣传活动方案input : tf.Tensor. shape = (b, s, s)
offts: tf.Tensor. shape = (b, s, s, 2)
"""
input_shape = tf.shape(input)
batch_size = input_shape[0]
input_size = input_shape[1]
最新流行语
offts = tf.reshape(offts, (batch_size, -1, 2))
grid = tf.meshgrid(
tf.range(input_size), tf.range(input_size), indexing='ij'
)
grid = tf.stack(grid, axis=-1)
grid = tf.cast(grid, 'float32')
grid = tf.reshape(grid, (-1, 2))
grid = tf_repeat_2d(grid, batch_size)
coords = offts + grid
mapped_vals = tf_batch_map_coordinates(input, coords)
return mapped_vals
通过meshgrid得到⽹格坐标,加上偏移坐标就是偏移后的feature maps坐标对应值,只要把原feature maps的值映射过来就好(就是最后⼀步的tf_batch_map_coordinates)。
最后使⽤形变卷积的时候,ConvOfft2D的参数filter要注意,应该是上⼀个卷积的filters的数量,如下所⽰:
inputs = Input((48,48,1))
x = ConvOfft2D(1)(inputs)
x = Conv2D(16, (5,5), activation='relu')(x)
x = BatchNormalization()(x)
x = ConvOfft2D(16)(x)
x = Conv2D(16, (5,5), activation='relu')(x)滇式月饼
x = BatchNormalization()(x)
x = MaxPooling2D((2,2))(x)
x = ConvOfft2D(16)(x)
x = Conv2D(32, (5,5), activation='relu')(x)
宋美龄x = BatchNormalization()(x)
x = ConvOfft2D(32)(x)
x = Conv2D(32, (5,5), activation='relu')(x)

本文发布于:2023-07-30 14:54:48,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1102080.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:卷积   偏移   函数   坐标   形变   代码   偏移量   得到
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图