diff --git a/include/k2c_conv_transpose_layers.c b/include/k2c_conv_transpose_layers.c new file mode 100644 index 0000000..39e9c4e --- /dev/null +++ b/include/k2c_conv_transpose_layers.c @@ -0,0 +1,81 @@ +/** + k2c_conv_transpose_layers.c + This file is part of keras2c + This addition (this file) to the keras2c project was originated by Anchal Gupta + See LICENSE file + */ +#include +#include "k2c_include.h" + +/** + * 1D (temporal) Convolution Transpose + * Assumes a "channels last" structure. + * + * :param output: output tensor. + * :param input: input tensor. + * :param kernel: kernel tensor. + * :param bias: bias tensor. + * :param stride: stride length of the convolution. + * :param start_crop: number of elements to crop from the start of the output. + If padding is 'valid', this should be zero, for 'same' it + should be (kernel_size - stride) // 2. + * :param activation: activation function to apply to output. + */ +void k2c_conv1d_transpose(k2c_tensor *output, const k2c_tensor *input, + const k2c_tensor *kernel, const k2c_tensor *bias, + const size_t stride, const size_t start_crop, + k2c_activationType *activation) +{ + memset(output->array, 0, output->numel * sizeof(output->array[0])); + + const size_t n_height = input->shape[0]; + const size_t n_channels = input->shape[1]; + const size_t k_size = kernel->shape[0]; + const size_t n_filters = kernel->shape[1]; + const size_t out_height = output->shape[0]; + + const size_t ker_dim12 = n_channels * n_filters; + + size_t cs = 0; + size_t ce = 0; + size_t ts = 0; + size_t ks = 0; + + for (size_t f = 0; f < n_filters; ++f) + { + for (size_t ch = 0; ch < n_channels; ++ch) + { + for (size_t t = 0; t < n_height; ++t) + { + ts = t * stride; + if (ts > start_crop) + { + cs = ts - start_crop; + } + else + { + cs = 0; + } + if (ts + k_size - start_crop > out_height) + { + ce = out_height; + } + else + { + ce = ts + k_size - start_crop; + } + ks = cs - (ts - start_crop); + for (size_t i = 0; i < ce - cs; ++i) + { + output->array[(i + cs) * n_filters + f] += + kernel->array[(i + ks) * ker_dim12 + f * n_channels + ch] * + input->array[t * n_channels + ch]; + } + } + } + } + // } + + k2c_bias_add(output, bias); + activation(output->array, output->numel); +} diff --git a/include/k2c_include.h b/include/k2c_include.h index df1f784..423f5ca 100644 --- a/include/k2c_include.h +++ b/include/k2c_include.h @@ -145,3 +145,11 @@ void k2c_gru(k2c_tensor* output, const k2c_tensor* input, float * state, k2c_activationType *recurrent_activation, k2c_activationType *output_activation); +// Convolution Transpose layers +void k2c_conv1d_transpose(k2c_tensor *output, const k2c_tensor *input, + const k2c_tensor *kernel, const k2c_tensor *bias, + const size_t stride, const size_t start_crop, + k2c_activationType *activation); + +// Split layers +void k2c_split(k2c_tensor *output, k2c_tensor *input, size_t offset); diff --git a/include/k2c_split_layers.c b/include/k2c_split_layers.c new file mode 100644 index 0000000..5c1f95b --- /dev/null +++ b/include/k2c_split_layers.c @@ -0,0 +1,21 @@ +/** + k2c_split_layers.c + This file is part of keras2c + This addition (this file) to the keras2c project was originated by Anchal Gupta + See LICENSE file + */ + +#include +#include "k2c_include.h" + +/* +Split input tensor into one output tensor + * :param output: output tensor. + * :param input: input tensor. + * :param offset: The offset index at input to start copying from. +*/ + +void k2c_split(k2c_tensor *output, k2c_tensor *input, size_t offset) +{ + memcpy(&output->array[0], &input->array[offset], output->numel * sizeof(output->array[0])); +} \ No newline at end of file diff --git a/include/makefile b/include/makefile index 600e899..2c59cd3 100644 --- a/include/makefile +++ b/include/makefile @@ -25,7 +25,9 @@ OBJ = \ k2c_merge_layers.o \ k2c_normalization_layers.o \ k2c_pooling_layers.o \ - k2c_recurrent_layers.o + k2c_recurrent_layers.o \ + k2c_conv_transpose_layers.o \ + k2c_conv_split_layers.o DEPS = \ k2c_include.h \