def compute_convolution_nd(data, kernel, dimension: int, mode=ConvolutionMode.valid, element_wise: bool=False): mode_string = __get_convolution_mode_string(mode) result = [] data_prefix_shape = data.shape[:-2] kernel_prefix_shape = kernel.shape[:-2] if element_wise: final_shape = element_wise_shape(data_prefix_shape, kernel_prefix_shape)[0] data = numpy.broadcast_to(data, final_shape + data.shape[-2:]) kernel = numpy.broadcast_to(kernel, final_shape + kernel.shape[-2:]) if final_shape: for index in array_index_traversal(final_shape): result.append(__compute_convolution_nd(data[index], kernel[index], dimension, mode_string)) return numpy.array(result).reshape(final_shape + result[0].shape) else: return __compute_convolution_nd(data, kernel, dimension, mode_string) else: if data_prefix_shape: for data_index in array_index_traversal(data_prefix_shape): if kernel_prefix_shape: for kernel_index in array_index_traversal(kernel_prefix_shape): result.append(__compute_convolution_nd(data[data_index], kernel[kernel_index], dimension, mode_string)) else: result.append(__compute_convolution_nd(data[data_index], kernel, dimension, mode_string)) final_shape = data_prefix_shape + kernel_prefix_shape + basic_convolution_shape(data.shape[-2:], kernel.shape[-2:], 2, mode_string) return numpy.array(result).reshape(final_shape) else: if kernel_prefix_shape: for kernel_index in array_index_traversal(kernel_prefix_shape): result.append(__compute_convolution_nd(data, kernel[kernel_index], dimension, mode_string)) final_shape = data_prefix_shape + kernel_prefix_shape + basic_convolution_shape(data.shape[-2:], kernel.shape[-2:], 2, mode_string) return numpy.array(result).reshape(final_shape) else: return __compute_convolution_nd(data, kernel, dimension, mode_string)
def max_unpooling_shape(shape_data, shape_pooling, dimension): prefix_shape, prefix_broadcast_data, prefix_broadcast_kernel = element_wise_shape( shape_data[:-dimension], shape_pooling[:-dimension]) new_shape = prefix_shape + tuple(shape_data[i] for i in range(-dimension, 0)) return new_shape, prefix_broadcast_data + ( 0, ) * dimension, prefix_broadcast_kernel + (0, ) * dimension
def element_wise_convolution_nd_shape(shape_data, shape_kernel, dimension, mode): prefix_shape, prefix_broadcast_data, prefix_broadcast_kernel = element_wise_shape(shape_data[:-dimension], shape_kernel[:-dimension]) if mode == 'valid' or mode == ConvolutionMode.valid: new_shape = prefix_shape + tuple(shape_data[i] - shape_kernel[i] + 1 for i in range(-dimension, 0)) elif mode == 'full' or mode == ConvolutionMode.full: new_shape = prefix_shape + tuple(shape_data[i] + shape_kernel[i] - 1 for i in range(-dimension, 0)) else: raise ValueError('Invalid convolution mode: {}'.format(mode)) return new_shape, prefix_broadcast_data + (0,) * dimension, prefix_broadcast_kernel + (0,) * dimension
def unpooling_shape(shape_pooling, size, step, unpooling_size, dimension): prefix_shape, prefix_broadcast_data, prefix_broadcast_kernel = element_wise_shape( shape_pooling[:-dimension], shape_pooling[:-dimension]) new_shape = prefix_shape + tuple( (size[i] + (shape_pooling[i] - 1) * step[i]) if unpooling_size is None else unpooling_size[i] for i in range(-dimension, 0)) return new_shape, prefix_broadcast_data + ( 0, ) * dimension, prefix_broadcast_kernel + (0, ) * dimension
def compute_max_unpooling_nd(data, pooling, size, step, dimension: int): result = [] data_prefix_shape = data.shape[:-dimension] kernel_prefix_shape = pooling.shape[:-dimension] final_shape = element_wise_shape(data_prefix_shape, kernel_prefix_shape)[0] data = numpy.broadcast_to(data, final_shape + data.shape[-dimension:]) pooling = numpy.broadcast_to(pooling, final_shape + pooling.shape[-dimension:]) if final_shape: for key in array_index_traversal(final_shape): result.append(__compute_max_unpooling_nd(data[key], pooling[key], size, step, dimension)) return numpy.array(result).reshape(final_shape + result[0].shape) else: return __compute_max_unpooling_nd(data, pooling, size, step, dimension)
def compute_convolution_nd(data, kernel, dimension: int, mode=ConvolutionMode.valid, element_wise: bool = False): mode_string = __get_recurrent_mode_string(mode) result = [] data_prefix_shape = data.shape[:-dimension] kernel_prefix_shape = kernel.shape[:-dimension] if element_wise: final_shape = element_wise_shape(data_prefix_shape, kernel_prefix_shape)[0] data = numpy.broadcast_to(data, final_shape + data.shape[-2:]) kernel = numpy.broadcast_to(kernel, final_shape + kernel.shape[-2:]) if final_shape: for index in array_index_traversal(final_shape): result.append( __compute_convolution_nd(data[index], kernel[index], dimension, mode_string)) return numpy.array(result).reshape(final_shape + result[0].shape) else: return __compute_convolution_nd(data, kernel, dimension, mode_string) else: if kernel_prefix_shape: final_shape = data_prefix_shape + kernel_prefix_shape + basic_convolution_shape( data.shape[-dimension:], kernel.shape[-dimension:], dimension, mode_string) result = numpy.zeros(final_shape) for kernel_index in array_index_traversal(kernel_prefix_shape): sub_result_index = tuple( slice(None) for _ in data_prefix_shape) + kernel_index + tuple( slice(None) for _ in range(dimension)) result[sub_result_index] = __compute_convolution_nd( data, kernel[kernel_index], dimension, mode_string) return result else: return __compute_convolution_nd(data, kernel, dimension, mode_string)