Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convolution 1D CNTK C++ #3862

Open
Acrobyte opened this issue Dec 30, 2021 · 1 comment
Open

Convolution 1D CNTK C++ #3862

Acrobyte opened this issue Dec 30, 2021 · 1 comment

Comments

@Acrobyte
Copy link

Acrobyte commented Dec 30, 2021

Hello. Help me create a conv1D () function like Tensorflow.
I described the code, but I'm not sure if it works the way I need it. Because the result is different from a similar model written in python Tensorflow. I'm not sure what the problem is here.
Code c++:
inputl = InputVariable({ DataShape.TotalSize() }, false, DataType::Float, L"features");
auto input = Reshape(inputl, DataShape);
inputl->AsString() ------>>> Composite(Reshape): Input('features', [20000], [, #]) -> Output('Reshape1_Output_0', [500x 40], [, #])

auto convParam = Parameter({ 1, 40, 512}, AsDataType(), GlorotUniformInitializer());
auto layer = Convolution(convParam, input, { 1, 40}, { true }, { true }, { 1}, 1);
layer ->AsString() ------>>> "Composite(BatchNormalization): Input('features', [20000], [, #]) -> Output('BatchNormalization16_Output_0', [500x 512], [, #])"

I need something like:
Input data shape: 20000 = (40,40,40,......,40) = 500*40
After reshape input data, shape = (500, 40)
conv1D()
Output shape data = (400, 512)

@pat749
Copy link

pat749 commented Mar 26, 2023

Here is an example implementation of a conv1D() function in C++ that is similar to the one in TensorFlow:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

// Define a 1D convolution function
std::vector<float> conv1D(std::vector<float> input, std::vector<float> filter, int stride) {
    int input_size = input.size();
    int filter_size = filter.size();
    int output_size = (input_size - filter_size) / stride + 1;

    // Pad the input data with zeros
    int padding = filter_size / 2;
    std::vector<float> padded_input(input_size + 2 * padding, 0);
    std::copy(input.begin(), input.end(), padded_input.begin() + padding);

    // Perform convolution
    std::vector<float> output(output_size);
    for (int i = 0; i < output_size; i++) {
        int start = i * stride;
        int end = start + filter_size;
        std::vector<float> window(padded_input.begin() + start, padded_input.begin() + end);
        output[i] = std::inner_product(window.begin(), window.end(), filter.begin(), 0.0f);
    }

    return output;
}

int main() {
    // Define input data
    int input_size = 20000;
    std::vector<float> input_data(input_size, 1.0f);
    std::vector<int> input_shape = {500, 40};

    // Reshape input data
    int batch_size = input_shape[0];
    int input_dim = input_shape[1];
    std::vector<float> reshaped_input(batch_size * input_dim);
    for (int i = 0; i < batch_size; i++) {
        std::vector<float> input_row(input_data.begin() + i * input_dim, input_data.begin() + (i + 1) * input_dim);
        std::copy(input_row.begin(), input_row.end(), reshaped_input.begin() + i * input_dim);
    }

    // Define convolution filter
    int filter_size = 3;
    int num_filters = 512;
    std::vector<float> filter(filter_size * num_filters, 1.0f);

    // Perform convolution
    int stride = 1;
    std::vector<float> output = conv1D(reshaped_input, filter, stride);

    // Reshape output data
    int output_dim = num_filters;
    std::vector<int> output_shape = {batch_size, output_dim};
    std::vector<float> reshaped_output(batch_size * output_dim);
    for (int i = 0; i < batch_size; i++) {
        std::vector<float> output_row(output.begin() + i * output_dim, output.begin() + (i + 1) * output_dim);
        std::copy(output_row.begin(), output_row.end(), reshaped_output.begin() + i * output_dim);
    }

    std::cout << "Output shape: " << batch_size << "x" << output_dim << std::endl;
    return 0;
}

This implementation defines a conv1D() function that takes an input data vector, a filter vector, and a stride value as inputs, and returns the convolved output data as a vector. It also includes code to reshape the input and output data to match the shapes you provided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants