Related
I am looking for tips on how to debug tensor flow graph execution written in c++. In particular calls to session::Run produce the error "specified in either feed_devices or fetch_devices was not found in the Graph" and I am looking for ways to debug my graph.
// data is a std::vector
std::vector names = {"feature1","feature2","feature3","feature4"};
std::vector<std::pair<tf::string, tf::Tensor>> input_tensor;
std::vector<tf::Tensor> output_tensors;
// create the Run input tensor
for (uint i=0; i < gamma_transformed_data.size();i++)
{
tf::Tensor tensorValue(tf::DT_FLOAT, tf::TensorShape({1,1}));
tensorValue.flat<float>().data()[0] = data[i];
std::pair <tf::string, tf::Tensor> pair = std::make_pair (names[i],tensorValue);
input_tensor.push_back(pair);
}
//execute the graph
check_status(ReadBinaryProto(tf::Env::Default(),protobuf_model_filepath, &graph));
check_status(tf::NewSession(tf::SessionOptions(), &session));
check_status(session->Create(graph));
check_status(session->Run(input_tensor, {"results"}, {}, &output_tensors));
session->Run returns false and status.ToString() = //"Invalid argument: Tensor xyz:0, specified in either feed_devices or fetch_devices was not found in the Graph"
I have a string in a C++ Qt application (on Ubuntu) which contains valid GraphViz/dot graph syntax. I want to generate an image file/object from this text, similar to the images that various online tools (like this one: http://www.webgraphviz.com/) spit out. Maybe I'm using wrong search terms, but I can't seem to find relevant help with this.
What I basically want is something like this:
generate_dot_graph_image(std::string dot_text, std::string image_file_path)
Additional details: I have a Dijkstra solver whose solution (basically the original graph after removing non-used edges) I want to visualize inside my application. The solver already includes an option to convert the solution to a string that can be parsed as a dot graph using a utility such as the one I linked above. But what I want is to be able to do this from inside C++.
So I was able to do exactly what I wanted using the GraphViz libraries. You can install them on Ubuntu using sudo apt-get install graphviz-lib and sudo apt-get install libgraphviz-dev. Once that's done:
#include <graphviz/gvc.h>
bool DotGraphGenerator::saveImage()
{
std::string o_arg = std::string("-o") + "/path/to/image_file.png";
char* args[] = {const_cast<char*>("dot"), const_cast<char*>("Tpng"), const_cast<char*>("-Gsize=8,4!"), const_cast<char*>("-Gdpi=100"),
const_cast<char*>(DOT_TEXT_FILE.c_str()), //DOT_TEXT_FILE is the file path in which the graph is saved as valid DOT syntax
const_cast<char*>(o_arg.c_str()) };
const int argc = sizeof(args)/sizeof(args[0]);
Agraph_t *g, *prev = NULL;
GVC_t *gvc;
gvc = gvContext();
gvParseArgs(gvc, argc, args);
while ((g = gvNextInputGraph(gvc)))
{
if (prev)
{
gvFreeLayout(gvc, prev);
agclose(prev);
}
gvLayoutJobs(gvc, g);
gvRenderJobs(gvc, g);
prev = g;
}
return !gvFreeContext(gvc);
}
gvc is a C library, and the functions take non-const C strings as arguments, hence the const_casts in the beginning. You can also edit the image size by altering the -Gsize=8,4 and -Gdpi=100 args. With the current configuration you'll get an 8*100 x 4*100 = 800x400 image file. Anyway, these arguments are the same as you would apply when running the dot command from bash.
Other than that, this code is basically copied from one of the examples in the graphViz as a library manual: http://www.graphviz.org/pdf/libguide.pdf
I found a way, I used the following function and it works:
bool saveImageGV(std::string file_path){
GVC_t *gvc;
Agraph_t *g;
FILE *fp;
gvc = gvContext();
fp = fopen((file_path+".dot").c_str(), "r");
g = agread(fp, 0);
gvLayout(gvc, g, "dot");
gvRender(gvc, g, "png", fopen((file_path+".png").c_str(), "w"));
gvFreeLayout(gvc, g);
agclose(g);
return (gvFreeContext(gvc));
}
I am trying to understand the caffe implementation of Fully Convolutional Networks for Semantic Segmentation
. For its upscore layer implementation in fcn32 model, it sets up kernel_size=64. when reading the original paper, I did not find the description of this setup, What’s the reason that we need to setup kernel_size=64?
n.fc6, n.relu6 = conv_relu(n.pool5, 4096, ks=7, pad=0)
n.drop6 = L.Dropout(n.relu6, dropout_ratio=0.5, in_place=True)
n.fc7, n.relu7 = conv_relu(n.drop6, 4096, ks=1, pad=0)
n.drop7 = L.Dropout(n.relu7, dropout_ratio=0.5, in_place=True)
n.score_fr = L.Convolution(n.drop7, num_output=21, kernel_size=1, pad=0,
param=[dict(lr_mult=1, decay_mult=1), dict(lr_mult=2, decay_mult=0)])
n.upscore = L.Deconvolution(n.score_fr,
convolution_param=dict(num_output=21, kernel_size=64, stride=32,
bias_term=False),
param=[dict(lr_mult=0)])
n.score = crop(n.upscore, n.data)
n.loss = L.SoftmaxWithLoss(n.score, n.label,
loss_param=dict(normalize=False, ignore_label=255))
trying to fit a peak to some data like this:
import scipy
from lmfit.models import GaussianModel
x = shm.PTR_P
y = shm.PORE_V_P
mod = LorentzianModel()
pars = mod.guess(y, x=x)
out = mod.fit(y, pars, x=x)
print(out.fit_report(min_correl=0.25))
and while I can do the fit if I generate the data, if I try to read them from another source it doesn't work. Am not too good at this and have no idea what the issue is. Here is the output:
[x,y]
[(34.145490000000002, 3.4599999999999999e-08),
(29.286449999999999, 4.8399999999999997e-08),
(25.118860000000002, 0.026773140000000001),
(21.544350000000001, 0.068791409999999997),
(18.4785, 0.083200979999999994),
(15.848929999999999, 0.02123179),
(11.659139999999999, 0.01551077),
(10.0, 0.084493879999999993),
(6.3095739999999996, 2.0899999999999998e-07),
(5.4116949999999999, 0.045209140000000002),
(4.6415889999999997, 0.054789360000000002),
(3.4145489999999996, 8.9399999999999993e-08),
(2.9286449999999999, 0.01100814),
(2.5118860000000001, 0.088990659999999999),
(1.84785, 3.5799999999999995e-07),
(1.5848930000000001, 0.099999009999999999),
(1.359356, 0.075139280000000003),
(1.1659139999999999, 0.167379),
(1.0, 0.57693050000000001),
(0.85769590000000007, 1.8658159999999999),
(0.73564230000000008, 8.4961369999999992),
(0.6309574, 25.299099999999999),
(0.54116949999999997, 21.413350000000001),
(0.46415889999999999, 13.408829999999998),
(0.39810719999999999, 8.3584750000000003),
(0.34145490000000006, 5.3982010000000002),
(0.29286440000000002, 3.7518540000000002),
(0.25118859999999998, 2.5325389999999999),
(0.21544349999999998, 1.7722470000000001),
(0.18478499999999998, 1.445808),
(0.15848929999999997, 1.182083),
(0.13593559999999999, 0.94957730000000007),
(0.1165914, 0.67620849999999999),
(0.10000000000000001, 0.46631620000000001),
(0.085769590000000007, 0.41001890000000002),
(0.07356422, 0.30625920000000001),
(0.063095730000000003, 0.24040219999999998),
(0.054116949999999997, 0.1942596),
(0.046415890000000001, 0.11306760000000002),
(0.039810720000000001, 0.099998470000000006),
(0.034145490000000001, 0.099998470000000006),
(0.029286449999999999, 0.02246857),
(0.025118870000000001, 0.077529909999999994)]
I would guess that either there are NaNs in your data or that the initial guess is so far off as to produce NaNs. The initial guess of 0 for sigma seems suspicious -- this should be > 0.
Either way, plotting the data and using np.isnan() would probably help isolate the problem.
I'm trying to write a Graph into a binary file by using flatbuffers. A graph consists of nodes and edges. Every node has at least one edge and every edge consists of two nodes.
Excerpt from MyGraph.fbs:
namespace MyGraph;
table Node {
edges:[Edge];
}
table Edge {
startNode:Node;
endNode:Node;
}
table Graph {
allNodes:[Node];
}
root_type Graph;
Now I want to create a simple graph and write it into a bytefile:
FlatBufferBuilder fbb;
// create first node
auto node1mloc = DG::CreateNode(fbb, 0, 0);
// create second node
auto node2mloc = DG::CreateNode(fbb, 0, 0);
// create edge between first and second node
auto edgeloc = DG::CreateEdge(fbb, node1mloc, node2mloc);
// ???
// store the edge in the edges-vector of node1 and node2
// ???
// store nodes in graph
flatbuffers::Offset<Node> nodes[] = {node1mloc, node2mloc};
auto allNodes = fbb.CreateVector(nodes, 2);
auto graphloc = DG::CreateGraph(fbb, allNodes);
DG::FinishGraphBuffer(fbb, graphloc);
// write graph into file
auto buffer_pointer = fbb.GetBufferPointer();
SaveFile("myfile2.bin", reinterpret_cast<const char *>(buffer_pointer), fbb.GetSize(), true);
// load graph from file
string binData;
LoadFile("myfile2.bin", true, &binData);
auto graph = DG::GetGraph(binData.data());
cout << graph->allNodes()->size() << endl;
assert(graph->allNodes()->size() == 2);
The Problem is, that after creating the nodes, I can't add the edge to the edges-vector of node1 and node2. Is there a solution for that kind of cyclic dependencies between two types.
You cannot store cyclic structures in a FlatBuffer (it enforces that children always come before parents, using unsigned offsets).
You can store DAGs, however.
To encode a cyclic structure, you'll have to use indices for either Nodes or Edge references, e.g.
table Edge {
startNode:uint;
endNode:uint;
}
This means these node references are an index into allNodes.
Note that there's very few serialization formats that allow graphs, e.g. Protocol Buffers and JSON both only allow trees.
This works in FlatBuffersSwift but is not supported in the official FlatBuffers implementation.
//: Playground - noun: a place where people can play
import Foundation
var str = "Hello, playground"
let (f1, f2, f3, f4) = (Friend(), Friend(), Friend(), Friend())
f1.name = "Maxim"
f2.name = "Leo"
f3.name = "Boris"
f4.name = "Marc"
let f5 = Friend()
f5.name = "Daria"
f1.friends = [f1, f2, f3, f4]
f2.friends = [f1, f4]
f3.friends = [f2, f4]
f1.lover = Female(ref: f5)
f5.lover = Male(ref: f1)
f1.father = Friend()
f1.father?.name = "Issai"
f1.mother = Friend()
f1.mother?.name = "Margo"
let data = f1.toByteArray()
let f = Friend.fromByteArray(UnsafeBufferPointer(start:UnsafePointer<UInt8>(data), count: data.count))
print(f.friends[2]?.friends[0]?.friends[0]?.name)
print(((f.lover as? Female)?.ref?.lover as? Male)?.ref?.name)
let lazyF = Friend.Fast(data)
let girlFriend = (lazyF.lover as! Female.Fast).ref
let boyFriend = (girlFriend?.lover as! Male.Fast).ref
lazyF == boyFriend
I asked in the google groups chat if it would be of interest for main project.
Seems like it will not happen any time soon.
https://groups.google.com/forum/#!topic/flatbuffers/Y9K9wRKSHxg