【问题标题】:Implement ConvND in Tensorflow在 TensorFlow 中实现 ConvND
【发布时间】:2020-06-19 10:01:14
【问题描述】:

所以我需要一个也支持复数的 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.

同样的任务。我没有看到一个简单的解决方案,我认为我应该完全改变代码的策略。

【问题讨论】:

  • 因为this,我什至不得不这样做丑陋的index = 0index += 1 而不是enumerate。有了 TF 2,他们至少走上了正确的轨道,但在他们做得更“pythonic”之前还有一些工作要做

标签: python tensorflow conv-neural-network convolution


【解决方案1】:

最后,我以这种comment的效率非常低的方式做到了,也评论了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

我说效率低下是因为我为每个作业创建了一个全新的数组。我的代码目前需要很长时间才能计算出来,所以我会继续寻找改进,如果我有更好的结果,我会在这里发布。

【讨论】:

    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 2017-02-24
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    相关资源
    最近更新 更多