在 Tensorflow 中实现 ConvND
Implement ConvND in Tensorflow
所以我需要一个同样支持复数的ND卷积层。所以我决定自己编码。
我单独在 numpy 上测试了这段代码并且它有效。测试了多个通道,2D 和 1D 以及复杂的。但是,我在TF上做的时候遇到了问题。
到目前为止,这是我的代码:
def call(self, inputs):
with tf.name_scope("ComplexConvolution_" + str(self.layer_number)) as scope:
inputs = self._verify_inputs(inputs) # Check inputs are of expected shape and format
inputs = self.apply_padding(inputs) # Add zeros if needed
output_np = np.zeros( # I use np because tf does not support the assigment
(inputs.shape[0],) + # Per each image
self.output_size, # Image out size
dtype=self.input_dtype # To support complex numbers
)
img_index = 0
for image in inputs:
for filter_index in range(self.filters):
for i in range(int(np.prod(self.output_size[:-1]))): # for each element in the output
index = np.unravel_index(i, self.output_size[:-1])
start_index = tuple([a * b for a, b in zip(index, self.stride_shape)])
end_index = tuple([a+b for a, b in zip(start_index, self.kernel_shape)])
# set_trace()
sector_slice = tuple(
[slice(start_index[ind], end_index[ind]) for ind in range(len(start_index))]
)
sector = image[sector_slice]
new_value = tf.reduce_sum(sector * self.kernels[filter_index]) + self.bias[filter_index]
# I use Tied Bias https://datascience.stackexchange.com/a/37748/75968
output_np[img_index][index][filter_index] = new_value # The complicated line
img_index += 1
output = apply_activation(self.activation, output_np)
return output
input_size
是一个形状元组 (dim1, dim2, ..., dim3, channels)。例如,2D rgb conv 将是 (32, 32, 3) 并且 inputs
将具有形状 (None, 32, 32, 3).
输出大小是根据我在本文中找到的公式计算得出的:A guide to convolution arithmetic for deep learning
out_list = []
for i in range(len(self.input_size) - 1): # -1 because the number of input channels is irrelevant
out_list.append(int(np.floor((self.input_size[i] + 2 * self.padding_shape[i] - self.kernel_shape[i]) / self.stride_shape[i]) + 1))
out_list.append(self.filters)
基本上,我使用 np.zeros
因为如果我使用 tf.zeros
我无法分配 new_value
我得到:
TypeError: 'Tensor' object does not support item assignment
但是,在当前状态下,我得到:
NotImplementedError: Cannot convert a symbolic Tensor (placeholder_1:0) to a numpy array.
在同一个任务上。我没有看到一个简单的修复方法,我想我应该完全改变代码的策略。
最后,我基于这个 comment, also commented here 以一种非常低效的方式完成了它,但至少它有效:
new_value = tf.reduce_sum(sector * self.kernels[filter_index]) + self.bias[filter_index]
indices = (img_index,) + index + (filter_index,)
mask = tf.Variable(tf.fill(output_np.shape, 1))
mask = mask[indices].assign(0)
mask = tf.cast(mask, dtype=self.input_dtype)
output_np = array * mask + (1 - mask) * new_value
我说效率低下是因为我为每个作业创建了一个全新的数组。我的代码目前需要很长时间才能计算,所以我会继续寻求改进,如果我得到更好的东西,post 会在这里。
所以我需要一个同样支持复数的ND卷积层。所以我决定自己编码。
我单独在 numpy 上测试了这段代码并且它有效。测试了多个通道,2D 和 1D 以及复杂的。但是,我在TF上做的时候遇到了问题。
到目前为止,这是我的代码:
def call(self, inputs):
with tf.name_scope("ComplexConvolution_" + str(self.layer_number)) as scope:
inputs = self._verify_inputs(inputs) # Check inputs are of expected shape and format
inputs = self.apply_padding(inputs) # Add zeros if needed
output_np = np.zeros( # I use np because tf does not support the assigment
(inputs.shape[0],) + # Per each image
self.output_size, # Image out size
dtype=self.input_dtype # To support complex numbers
)
img_index = 0
for image in inputs:
for filter_index in range(self.filters):
for i in range(int(np.prod(self.output_size[:-1]))): # for each element in the output
index = np.unravel_index(i, self.output_size[:-1])
start_index = tuple([a * b for a, b in zip(index, self.stride_shape)])
end_index = tuple([a+b for a, b in zip(start_index, self.kernel_shape)])
# set_trace()
sector_slice = tuple(
[slice(start_index[ind], end_index[ind]) for ind in range(len(start_index))]
)
sector = image[sector_slice]
new_value = tf.reduce_sum(sector * self.kernels[filter_index]) + self.bias[filter_index]
# I use Tied Bias https://datascience.stackexchange.com/a/37748/75968
output_np[img_index][index][filter_index] = new_value # The complicated line
img_index += 1
output = apply_activation(self.activation, output_np)
return output
input_size
是一个形状元组 (dim1, dim2, ..., dim3, channels)。例如,2D rgb conv 将是 (32, 32, 3) 并且 inputs
将具有形状 (None, 32, 32, 3).
输出大小是根据我在本文中找到的公式计算得出的:A guide to convolution arithmetic for deep learning
out_list = []
for i in range(len(self.input_size) - 1): # -1 because the number of input channels is irrelevant
out_list.append(int(np.floor((self.input_size[i] + 2 * self.padding_shape[i] - self.kernel_shape[i]) / self.stride_shape[i]) + 1))
out_list.append(self.filters)
基本上,我使用 np.zeros
因为如果我使用 tf.zeros
我无法分配 new_value
我得到:
TypeError: 'Tensor' object does not support item assignment
但是,在当前状态下,我得到:
NotImplementedError: Cannot convert a symbolic Tensor (placeholder_1:0) to a numpy array.
在同一个任务上。我没有看到一个简单的修复方法,我想我应该完全改变代码的策略。
最后,我基于这个 comment, also commented here 以一种非常低效的方式完成了它,但至少它有效:
new_value = tf.reduce_sum(sector * self.kernels[filter_index]) + self.bias[filter_index]
indices = (img_index,) + index + (filter_index,)
mask = tf.Variable(tf.fill(output_np.shape, 1))
mask = mask[indices].assign(0)
mask = tf.cast(mask, dtype=self.input_dtype)
output_np = array * mask + (1 - mask) * new_value
我说效率低下是因为我为每个作业创建了一个全新的数组。我的代码目前需要很长时间才能计算,所以我会继续寻求改进,如果我得到更好的东西,post 会在这里。