Tensorflow tfcompile: fetching gradients - tensorflow

I created a very simple tensorflow model where I fetch gradients:
# tf Graph Input
X = tf.placeholder(tf.float32, [1, 2], name="X")
Y = tf.placeholder(tf.float32, [1, 2], name="Y")
# Model parameter variables
W = tf.Variable([[1.0, 2.0], [3.0, 4.0]], name="weight")
B = tf.Variable([[5.0, 6.0]], name="bias")
# Construct a multivariate linear model
matmul = tf.matmul(X, W, name="matrixMul")
pred = tf.add(matmul, B, name="addition")
# Mean squared error
cost = tf.reduce_sum(tf.pow(pred-Y, 2) / 2 )
# Fetch gradients
grads = tf.gradients(cost, [W, B])
I exported this graph into a protobuf and now I use tfcompile for AOT compilation. I want to use the compiled graph in a C++ program and fetch the computed gradients.
The config file for tfcompile looks like:
feed {
id { node_name: "X" }
shape {
dim { size: 1 }
dim { size: 2 }
}
name: "x"
}
feed {
id { node_name: "Y" }
shape {
dim { size: 1 }
dim { size: 2 }
}
name: "y"
}
feed {
id { node_name: "weight" }
shape {
dim { size: 2 }
dim { size: 2 }
}
name: "w"
}
feed {
id { node_name: "bias" }
shape {
dim { size: 1 }
dim { size: 2 }
}
name: "b"
}
fetch {
id { node_name: "addition"}
name: "prediction"
}
fetch {
id { node_name: "gradients/matrixMul_grad/MatMul_1"}
name: "weight_grad"
}
fetch {
id { node_name: "gradients/addition_grad/Reshape"}
name: "bias_grad"
}
Finally I run this C++ code:
obj.set_arg_x_data(x.data());
obj.set_arg_y_data(y.data());
obj.set_arg_w_data(w.data());
obj.set_arg_b_data(b.data());
obj.Run();
std::cout << "result_prediction =" << std::endl << obj.result_prediction(0,0) << " " << obj.result_prediction(0,1) << std::endl;
std::cout << "result_weight_grad =" << std::endl << obj.result_weight_grad(0,0) << " " << obj.result_weight_grad(0,1) << " " << obj.result_weight_grad(1,0) << " " << obj.result_weight_grad(1,1) << std::endl;
std::cout << "result_bias_grad =" << std::endl << obj.result_bias_grad(0,0) << " " << obj.result_bias_grad(0,1) << std::endl;
For result_prediction and result_bias_grad I get the expected values.
Just for result_weight_grad I get only 0,0,0,0.
Maybe I am fetching there the wrong node:
fetch {
id { node_name: "gradients/matrixMul_grad/MatMul_1"}
name: "weight_grad"
}
Does somebody tried already to fetch computed gradients? Tensorflow only offers examples where they using tfcompile for prediction.

Related

How to convert an xarray to std::vector?

The docs make it quite clear on how to adapt a std::vector to a tensor object.
https://xtensor.readthedocs.io/en/latest/adaptor.html
std::vector<double> v = {1., 2., 3., 4., 5., 6. };
std::vector<std::size_t> shape = { 2, 3 };
auto a1 = xt::adapt(v, shape);
But how can you do it for the other way round?
xt::xarray<double> a2 = { { 1., 2., 3.} };
std::vector<double> a2vector = ?;
You can construct a std::vector from iterators. For your example:
std::vector<double> w(a1.begin(), a1.end());
The complete example then becomes:
#include <vector>
#include <xtensor/xadapt.hpp>
#include <xtensor/xio.hpp>
int main()
{
std::vector<double> v = {1., 2., 3., 4., 5., 6.};
std::vector<std::size_t> shape = {2, 3};
auto a1 = xt::adapt(v, shape);
std::vector<double> w(a1.begin(), a1.end());
return 0;
}
References:
std::vector.
Constructors of std::vector (number (5) is the one relevant here).
xtensor documentation section 1.7.1 Adapting std::vector
Unfortunately Tom de Geus' answer does not maintain dimensionality and hence transforms the xarray of shape {2, 3} into a vector of size 6.
I stepped over this question, when attempting to construct a nested vector in order to plot a xarray with matplotlibcpp. For me it turned out, that Eigen::Matrix.. is a way more suitable class for this purpose. For the 2 dimensional case, one can comfortable convert the Eigen::Matrix to a nested std::vector. For higher dimensions, its worth to have a look here.
Code
transforms xt::xarray to Eigen::MatrixXf to nested std::vector
#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"
#include <Eigen/Dense>
//https://stackoverflow.com/questions/8443102/convert-eigen-matrix-to-c-array
Eigen::MatrixXf xarray_to_matrixXf(xt::xarray<float> arr)
{
auto shape = arr.shape();
int nrows = shape[0];
int ncols = shape[1];
Eigen::MatrixXf mat = Eigen::Map<Eigen::MatrixXf>(arr.data(), nrows, ncols);
return mat;
}
// https://stackoverflow.com/a/29243033/7128154
std::vector<std::vector<float>> matrixXf2d_to_vector(Eigen::MatrixXf mat)
{
std::vector<std::vector<float>> vec;
for (int i=0; i<mat.rows(); ++i)
{
const float* begin = &mat.row(i).data()[0];
vec.push_back(std::vector<float>(begin, begin+mat.cols()));
}
return vec;
}
// print a vector
// https://stackoverflow.com/a/31130991/7128154
template<typename T1>
std::ostream& operator <<( std::ostream& out, const std::vector<T1>& object )
{
out << "[";
if ( !object.empty() )
{
for(typename std::vector<T1>::const_iterator
iter = object.begin();
iter != --object.end();
++iter) {
out << *iter << ", ";
}
out << *--object.end();
}
out << "]";
return out;
}
int main()
{
xt::xarray<float> xArr {{nan(""), 9}, {5, -6}, {1, 77}};
std::cout << "xt::xarray<float> xArr = \n" << xArr << std::endl;
Eigen::MatrixXf eigMat = xarray_to_matrixXf(xArr);
std::cout << "Eigen::MatrixXf eigMat = \n" << eigMat << std::endl;
std::vector<std::vector<float>> vec = matrixXf2d_to_vector(eigMat);
std::cout << "std::vector<std::vector<float>> vec = " << vec << std::endl;
return 0;
}
Output
xt::xarray<float> xArr =
{{nan., 9.},
{ 5., -6.},
{ 1., 77.}}
Eigen::MatrixXf eigMat =
nan -6
9 1
5 77
std::vector<std::vector<float>> vec = [[nan, 9], [9, 5], [5, -6]]

Xamarin tensorflow

I want to develop TensorFlow on an android device, So far I trained with python and export model to Protobuf .pb file
the .pb file tested on python and its return no error
......
graph = load_graph("./frozen_model.pb")
for op in graph.get_operations():
print(op.name)
with tf.Session(graph=graph) as sess:
tf_predik = graph.get_tensor_by_name("prefix/tf_pred:0")
tf_data = graph.get_tensor_by_name("prefix/tf_data:0")
img = np.invert(Image.open("7.png").convert('L')).ravel(); image = array(img).reshape(1, 28,28,1);
fd = {tf_data: image};
test_pred = sess.run(tf_predik, feed_dict=fd); temp = np.argmax(test_pred, axis=1); print(temp)
My try on In Xamarin Android:
using Org.Tensorflow.Contrib.Android;
.....
var assets = Android.App.Application.Context.Assets;
var inferenceInterface = new TensorFlowInferenceInterface(assets, "frozen_model.pb");
using (Stream inputSteam = this.Assets.Open("7.png"))
{
byte[] bytes = inputSteam.ReadAllBytes();// convert to byte array???
inferenceInterface.Feed("tf_data", bytes, bytes.Length);
inferenceInterface.Run(new [] { "tf_pred:0" });
inferenceInterface.Fetch("tf_pred:0", predictions);
....
}
I get an error:
Java.Lang.IllegalArgumentException: Expects arg[0] to be float but uint8 is provided
Thank in advance.
Expects arg[0] to be float but uint8 is provided
TensorFlowInferenceInterface.Feed is expecting an array of float and thus you need to convert that asset-based image, decode its file encoding (jpg|png|...) to a Bitmap and obtain the float array from that.
Android Bitmap To Float Array
public float[] AndroidBitmapToFloatArray(Bitmap bitmap)
{
// Assuming a square image to sample|process, adjust based upon your model requirements
const int sizeX = 255;
const int sizeY = 255;
float[] floatArray;
int[] intArray;
using (var sampleImage = Bitmap.CreateScaledBitmap(bitmap, sizeX, sizeY, false).Copy(Bitmap.Config.Argb8888, false))
{
floatArray = new float[sizeX * sizeY * 3];
intArray = new int[sizeX * sizeY];
sampleImage.GetPixels(intArray, 0, sizeX, 0, 0, sizeX, sizeY);
sampleImage.Recycle();
}
for (int i = 0; i < intArray.Length; ++i)
{
var intValue = intArray[i];
floatArray[i * 3 + 0] = ((intValue & 0xFF) - 104);
floatArray[i * 3 + 1] = (((intValue >> 8) & 0xFF) - 117);
floatArray[i * 3 + 2] = (((intValue >> 16) & 0xFF) - 123);
}
return floatArray;
}
Example:
float[] feedArray;
using (var imageAsset = Assets.Open("someimage"))
using (var bitmappAsset = BitmapFactory.DecodeStream(imageAsset))
{
feedArray = AndroidBitmapToFloatArray(bitmappAsset);
}
inferenceInterface.Feed("tf_data", feedArray, feedArray.Length);

CGAL Cartesian grid

In my code, I organize objects into a regular Cartesian grid (such as 10x10). Often given a point, I need to test whether the point intersects grid and if so, which bins contain the point. I already have my own implementation but I don't like to hassle with precision issues.
So, does CGAL has a 2D regular Cartesian grid?
You can use CGAL::points_on_square_grid_2 to generate the grid points. CGAL kernels provide Kernel::CompareXY_2 functors, which you can use to figure out the exact location of your query point on the grid. For example you can sort your grid points and then use std::lower_bound followed by CGAL::orientation or CGAL::collinear on the appropriate elements of your range. You could also build an arrangement, but this would be an overkill.
Here is a sample code.
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/random_selection.h>
#include <CGAL/Polygon_2_algorithms.h>
using namespace CGAL;
using K= Exact_predicates_exact_constructions_kernel;
using Point =K::Point_2;
using Creator = Creator_uniform_2<double, Point>;
using Grid = std::vector<Point>;
const int gridSide = 3;
void locate_point (Point p, Grid grid);
int main ()
{
Grid points;
points_on_square_grid_2(gridSide * gridSide, gridSide * gridSide, std::back_inserter(points), Creator());
std::sort(points.begin(), points.end(), K::Less_xy_2());
std::cout << "Grid points:\n";
for (auto& p:points)
std::cout << p << '\n';
std::cout << "\ncorner points:\n";
Grid cornerPoints{points[0], points[gridSide - 1], points[gridSide * gridSide - 1],
points[gridSide * (gridSide - 1)]};
for (auto& p:cornerPoints)
std::cout << p << '\n';
std::cout << '\n';
Point p1{-8, -8};
Point p2{-10, 3};
Point p3{-9, -8};
Point p4{0, 4};
Point p5{1, 5};
locate_point(p1, points);
locate_point(p2, points);
locate_point(p3, points);
locate_point(p4, points);
locate_point(p5, points);
}
void locate_point (Point p, Grid grid)
{
if (grid.empty())
{
std::cout << "Point " << p << " not in grid";
return;
}
// check if point is in grid
Grid cornerPoints{grid[0], grid[gridSide - 1], grid[gridSide * gridSide - 1], grid[gridSide * (gridSide - 1)]};
auto point_is = CGAL::bounded_side_2(cornerPoints.begin(), cornerPoints.end(), p);
switch (point_is)
{
case CGAL::ON_UNBOUNDED_SIDE:
std::cout << "Point " << p << " not in grid\n";
return;
case CGAL::ON_BOUNDARY:
std::cout << "Point " << p << " on grid boundary\n";
return;
case CGAL::ON_BOUNDED_SIDE:
std::cout << "Point " << p << " is in grid\n";
}
auto f = std::lower_bound(grid.begin(), grid.end(), p, K::Less_xy_2());
auto g = std::find_if(f, grid.end(), [&p] (const Point& gridpoint)
{ return K::Less_y_2()(p, gridpoint); });
if (CGAL::collinear(p, *g, *(g - 1)))
{
std::cout << "Point " << p << " on grid side between points " << *(g - 1) << " and " << *g << '\n';
return;
}
std::cout << "Point " << p << " in bin whose upper right point is " << *g << '\n';
return;
}
Output:
Grid points:
-9 -9
-9 0
-9 9
0 -9
0 0
0 9
9 -9
9 0
9 9
corner points:
-9 -9
-9 9
9 9
9 -9
Point -8 -8 is in grid
Point -8 -8 in bin whose upper right point is 0 0
Point -10 3 not in grid
Point -9 -8 on grid boundary
Point 0 4 is in grid
Point 0 4 on grid side between points 0 0 and 0 9
Point 1 5 is in grid
Point 1 5 in bin whose upper right point is 9 9

mxnet (mshadow) getting the shape of a tensor

I'm a newbie in mshadow, I can not understand why I got those outpus from the following code snippet:
TensorContainer<cpu, 2> lhs(Shape2(2, 3));
lhs = 1.0;
printf("%u %u\n", lhs.size(0), lhs.size(1));
printf("%u %u\n", lhs[0].shape_[0], lhs[0].shape_[1]);
printf("%u %u\n", lhs[0].size(0), lhs[0].size(1));
The output is:
2 3
3 4
3 3
Why are the second and third outputs those numbers? Because lhs[0] is one-dimensional, I think they should be exactly the same, i.e. 3 0. Could anyone tell me where I was wrong? Thanks in advance!
You are right, Tensor lhs[0] is one dimensional, but to answer you question first let me show what is going on under the hood. TensorContainer does not override the [] operator, instead it uses the one from the parent (which is Tensor), more precisely the following one is called:
MSHADOW_XINLINE Tensor<Device, kSubdim, DType> operator[](index_t idx) const {
return Tensor<Device, kSubdim, DType>(dptr_ + this->MemSize<1>() * idx,
shape_.SubShape(), stride_, stream_);
}
As can be seen it creates a new Tensor on a stack. And while for the most of the cases it will create generic N-dimensional Tensor, here for the 1-dimensional case it will create a special 1-dimensional Tensor.
Now ,when we have established what exactly is returned by the operator [], let's look on the fields of that class:
DType *dptr_;
Shape<1> shape_;
index_t stride_;
As can be seen the shape_ here has only 1 dimension! so there is no shape_1, instead by calling shape_1 it will return stride_(or part of it). Here is the modification to the Tensor constructor that you can try to run and see what is actually going on there:
MSHADOW_XINLINE Tensor(DType *dptr, Shape<1> shape,
index_t stride, Stream<Device> *stream)
: dptr_(dptr), shape_(shape), stride_(stride), stream_(stream) {
std::cout << "shape[0]: " << shape[0] << std::endl; // 3
std::cout << "shape[1]: " << shape[1] << std::endl; // 0, as expected
std::cout << "_shape[0]: " << shape_[0] << std::endl; // 3, as expected
std::cout << "_shape[1]: " << shape_[1] << std::endl; // garbage (4)
std::cout << "address of _shape[1]: " << &(shape_[1]) << std::endl;
std::cout << "address of stride: " << &(stride_) << std::endl;
}
and the output:
shape[0]: 3
shape[1]: 0
_shape[0]: 3
_shape[1]: 4
address of _shape[1]: 0x7fffa28ec44c
address of stride: 0x7fffa28ec44c
_shape1 and stride have both the same address (0x7fffa28ec44c).

When the while loop starts the code stops calculating and outputting numbers

my code works the first time and when the loop start it stops calculating the numbers!
I want the program to ask the user to choose a material every time it finishes calculating the numbers. I used while (1!=2) { }
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
float stress, strain, area;
double diameter;
long int F = 9900;
const float pi = 3.141593f;
int i = 0;
int main() {
char meterial;
cout << "This programm calculates the stress and strain of a rod under loads from 10000N to 20000N\n\n";
while (1!=2)
{
cout << "Choose the meterial of the rod\n\n";
cout << "S For STEEL\nA For ALUMINUM\nC For COPPER\nT For TITANIUM\n\n";
cin >> meterial;
switch (meterial)
{
case 's':
cout << "\nEnter the diameter of the rod in mm: ";
cin >> diameter;
area = (pi * diameter * diameter) / 4;
while (i <= 50)
{
stress = F / area;
strain = 200 / stress;
F = F + 100;
cout << "Load = " << F << " Stress = " << stress << " N/mm^2" << " Strain = " << strain << "\n";
i++;
}
break;
case 'a':
cout << "Enter the diameter of the rod in mm: ";
cin >> diameter;
area = (pi * diameter * diameter) / 4;
while (i <= 50)
{
stress = F / area;
strain = 69 / stress;
F = F + 100;
cout << "Load = " << F << " Stress = " << stress << " N/mm^2" << " Strain = " << strain << "\n";
i++;
}
break;
case 'c':
cout << "Enter the diameter of the rod in mm: ";
cin >> diameter;
area = (pi * diameter * diameter) / 4;
while (i <= 50)
{
stress = F / area;
strain = 117 / stress;
F = F + 100;
cout << "Load = " << F << " Stress = " << stress << " N/mm^2" << " Strain = " << strain << "\n";
i++;
}
break;
case 't':
cout << "Enter the diameter of the rod in mm: ";
cin >> diameter;
area = (pi * diameter * diameter) / 4;
while (i <= 50)
{
stress = F / area;
strain = 110.3 / stress;
F = F + 100;
cout << "Load = " << F << " Stress = " << stress << " N/mm^2" << " Strain = " << strain << "\n";
i++;
}
break;
default:
cout << "You entered a wrong character";
}
}
}
http://i.stack.imgur.com/do3qc.png
I don't see that you're resetting the value of i before the next call.
But you really should have that while loop (while (i <= 50)) in a function or method somewhere unless you have studied those yet.
The variable i is never re-initialized to zero. If you replace each
while (i <= 50)
statement in the cases for your switch statement with something like:
for (int i = 0; i <= 50; ++i)
and remove the i++; lines in each corresponding block, e.g.
case 's':
cout << "\nEnter the diameter of the rod in mm: ";
cin >> diameter;
area = (pi * diameter * diameter) / 4;
for (int i = 0; i <= 50; ++i) // while (i <= 50) <-- change
{
stress = F / area;
strain = 200 / stress;
F = F + 100;
cout << "Load = " << F << " Stress = " << stress << " N/mm^2" << " Strain = " << strain << "\n";
// i++; <-- remove
}
your code should do what you expect. You might consider replacing the while (1!=2) test with something like while(1) or for(;;), but only because those are more common idioms (your test will always evaluate to true so it's still just fine).
On Edit: one more thing - you never re-initialize F, but you modify it in your calculation. Each time you run through your switch statement, you're starting with a different initial value for F.