目录结构
主要记录其中的 conv_utils.py。
conv_utils.py
def normalize_tuple(value, n, name):
"""Transforms a single int or iterable of ints into an int tuple.
# Arguments
value: The value to validate and convert. Could be an int, or any iterable
of ints.
n: The size of the tuple to be returned.
name: The name of the argument being validated, e.g. `strides` or
`kernel_size`. This is only used to format error messages.
# Returns
A tuple of n integers.
# Raises
ValueError: If something else than an int/long or iterable thereof was
passed.
"""
if isinstance(value, int):
return (value,) * n
else:
try:
value_tuple = tuple(value)
except TypeError:
raise ValueError('The `' + name + '` argument must be a tuple of ' +
str(n) + ' integers. Received: ' + str(value))
if len(value_tuple) != n:
raise ValueError('The `' + name + '` argument must be a tuple of ' +
str(n) + ' integers. Received: ' + str(value))
for single_value in value_tuple:
try:
int(single_value)
except ValueError:
raise ValueError('The `' + name + '` argument must be a tuple of ' +
str(n) + ' integers. Received: ' + str(value) + ' '
'including element ' + str(single_value) + ' of '
'type ' + str(type(single_value)))
return value_tuple
该函数接收整型数字或者整型元组,用在`strides` 或`kernel_size`中,如果出问题就格式化错误信息。错误信息包括以下两种:
类型错误:输入的不是整型或者整型元组
长度错误:输入元组的长度和可接受元组的长度不一致
def normalize_padding(value):
padding = value.lower()
allowed = {'valid', 'same', 'causal'}
if K.backend() == 'theano':
allowed.add('full')
if padding not in allowed:
raise ValueError('The `padding` argument must be one of "valid", "same" '
'(or "causal" for Conv1D). Received: ' + str(padding))
return padding
对网络层中padding值判断的函数,只接收三种'valid', 'same', 'causal'。
def convert_kernel(kernel)
转换卷积核,有Theano转换个TensorFlow。
def conv_output_length(input_length, filter_size,
padding, stride, dilation=1):
"""Determines output length of a convolution given input length.
# Arguments
input_length: integer.
filter_size: integer.
padding: one of `"same"`, `"valid"`, `"full"`.
stride: integer.
dilation: dilation rate, integer.
# Returns
The output length (integer).
"""
if input_length is None:
return None
assert padding in {'same', 'valid', 'full', 'causal'}
dilated_filter_size = filter_size + (filter_size - 1) * (dilation - 1)
if padding == 'same':
output_length = input_length
elif padding == 'valid':
output_length = input_length - dilated_filter_size + 1
elif padding == 'causal':
output_length = input_length
elif padding == 'full':
output_length = input_length + dilated_filter_size - 1
return (output_length + stride - 1) // stride
计算输出map的边长。共有以下几个公式(原来这几个公式在这里):
空洞卷积的卷积核尺寸计算:dilated_filter_size = filter_size + (filter_size - 1) * (dilation - 1),dilation为膨胀率。
如果padding=‘same’:output_length = input_length
如果padding=‘valid’:output_length = input_length - dilated_filter_size + 1
如果padding=‘causal’:output_length = input_length
如果padding=“full”:output_length = input_length + dilated_filter_size - 1
如果设置了步长(stride),那么以上结果为(output_length + stride - 1) // stride。
def conv_input_length(output_length, filter_size, padding, stride):
"""Determines input length of a convolution given output length.
# Arguments
output_length: integer.
filter_size: integer.
padding: one of `"same"`, `"valid"`, `"full"`.
stride: integer.
# Returns
The input length (integer).
"""
if output_length is None:
return None
assert padding in {'same', 'valid', 'full'}
if padding == 'same':
pad = filter_size // 2
elif padding == 'valid':
pad = 0
elif padding == 'full':
pad = filter_size - 1
return (output_length - 1) * stride - 2 * pad + filter_size
这个函数计算的是卷积核的加边宽度。在网上找了三张图,依次分别是padding=‘full’,padding=‘valid’,padding=‘same’:
def deconv_length(dim_size, stride_size, kernel_size, padding,
output_padding, dilation=1):
"""Determines output length of a transposed convolution given input length.
# Arguments
dim_size: Integer, the input length.
stride_size: Integer, the stride along the dimension of `dim_size`.
kernel_size: Integer, the kernel size along the dimension of
`dim_size`.
padding: One of `"same"`, `"valid"`, `"full"`.
output_padding: Integer, amount of padding along the output dimension,
Can be set to `None` in which case the output length is inferred.
dilation: dilation rate, integer.
# Returns
The output length (integer).
"""
assert padding in {'same', 'valid', 'full'}
if dim_size is None:
return None
# Get the dilated kernel size
kernel_size = kernel_size + (kernel_size - 1) * (dilation - 1)
# Infer length if output padding is None, else compute the exact length
if output_padding is None:
if padding == 'valid':
dim_size = dim_size * stride_size + max(kernel_size - stride_size, 0)
elif padding == 'full':
dim_size = dim_size * stride_size - (stride_size + kernel_size - 2)
elif padding == 'same':
dim_size = dim_size * stride_size
else:
if padding == 'same':
pad = kernel_size // 2
elif padding == 'valid':
pad = 0
elif padding == 'full':
pad = kernel_size - 1
dim_size = ((dim_size - 1) * stride_size + kernel_size - 2 * pad +
output_padding)
return dim_size
该函数计算转置卷积层的输出长度。第一步计算卷积核的尺寸kernel_size = kernel_size + (kernel_size - 1) * (dilation - 1)。