Итак, мне нужен сверточный слой 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, каналы). Например, двухмерный RGB-преобразователь будет (32, 32, 3), а inputs
будет иметь форму (None, 32, 32, 3).
Размер вывода рассчитывается из уравнения, которое я нашел в этом paper: Руководство по арифметике свертки c для глубокого обучения
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.
по тому же заданию. Не вижу простого решения, думаю, мне следует полностью изменить стратегию кода.