serizba / cppflow

Run TensorFlow models in C++ without installation and without Bazel
https://serizba.github.io/cppflow/
MIT License
779 stars 177 forks source link

how to create custom tensor value with shape (b,n,m) ? #187

Closed alfanrizaldy closed 2 years ago

alfanrizaldy commented 2 years ago

How to create custom tensor value with shape (b,n,m) I see the cppflow::fill method but it allows inserting 1 value which fill the whole same value in the shape i see https://github.com/serizba/cppflow/issues/114 but not found how to fill the value from custom value or vector for example

serizba commented 2 years ago

Hi @alfanrizaldy

I don't understand your problem. You want to create a tensor from data that you already have in other structure?

If it's just a small tensor with few data points you can use:

/**
* Creates a flat tensor with the given values
* @tparam T A type that can be convertible into a tensor
* @param values The values to be converted
*/
template<typename T>
tensor(const std::initializer_list<T>& values);

For example:

auto a = cppflow::tensor({1, 2, 3, 4});
std::cout << a << std::endl;
// (tensor: shape=[4], dtype=TF_INT32, data=
// [1 2 3 4])

If you have the data in an std::vector you can use:

/**
* Creates a tensor with the given values and specified shape
* @tparam T A type that can be convertible into a tensor
* @param values The values to be converted (in a flattened version)
* @param shape The shape of the converted tensor
*/
template<typename T>
tensor(const std::vector<T>& values, const std::vector<int64_t>& shape);

For example:

std::vector<int> v = {1, 2, 3, 4};
auto a = cppflow::tensor(v, {2, 2});
std::cout << a << std::endl;
// (tensor: shape=[2 2], dtype=TF_INT32, data=
// [[1 2]
//  [3 4]])
alfanrizaldy commented 2 years ago

Thank you for quick response @serizba. Here i want to create a tensor with size (1,400,3) For example, here i have a vector 2D containing data in size (400,3), and i want to pass them into tensor

    vector<vector<float>> tensordata;
    for(int i=0; i<cloud->points.size(); i++)
    {
        vector<float> temp;
        for(int j=0; j<3; j++)
        {
            if(j==0)
            {
                temp.push_back(cloud->points[i].x);
            }
            if(j==1)
            {
                temp.push_back(cloud->points[i].y);
            }
            if(j==2)
            {
                temp.push_back(cloud->points[i].z);
            }            
        }
        tensordata.push_back(temp);
    }

How it could be able converted into tensor?

or i must convert my 2D vector into 1D vector like this

std::vector<int> v = {1, 2, 3, 4};
auto a = cppflow::tensor(v, {2, 2});
std::cout << a << std::endl;
// (tensor: shape=[2 2], dtype=TF_INT32, data=
// [[1 2]
//  [3 4]])
serizba commented 2 years ago

I see. You cannot create a tensor directly from a multidimensional std::vector. You must create a flat std:vector<float> tensordata, and then convert it to tensor specifying the shape.

In your case, it wouold be something like:

 vector<float> tensordata;
 for(int i=0; i<cloud->points.size(); i++)
 {
     for(int j=0; j<3; j++)
     {
         if(j==0)
             tensordata.push_back(cloud->points[i].x);
         if(j==1)
             tensordata.push_back(cloud->points[i].y);
         if(j==2)
             tensordata.push_back(cloud->points[i].z);     
     }
 }
auto mytensor = cppflow::tensor(tensordata, {1, cloud->points.size(), 3});
alfanrizaldy commented 2 years ago

Thank you. I will give it a try and update here for the result

alfanrizaldy commented 2 years ago

Great, it works and can do prediction in my loaded model. Thanks !