Issue
I have written code base on https://github.com/Neargye/hello_tf_c_api but I have to transpose input tensor and extend its dimensions. On output tensor I have to perform arg_max.
auto graph = tf_utils::LoadGraph("D:\\projects\\vive\\Vive_Model_4_classes_frozen\\frozen_graph.pb");
SCOPE_EXIT{ tf_utils::DeleteGraph(graph); }; // Auto-delete on scope exit.
if (graph == nullptr) {
std::cout << "Can't load graph" << std::endl;
return 1;
}
const std::vector<TF_Output> input_ops = { {TF_GraphOperationByName(graph, "x"), 0} };
const std::vector<TF_Tensor*> input_tensors = { tf_utils::CreateTensor(TF_FLOAT, shape, floatv) };
SCOPE_EXIT{ tf_utils::DeleteTensors(input_tensors); }; // Auto-delete on scope exit.
const std::vector<TF_Output> out_ops = { {TF_GraphOperationByName(graph, "Identity"), 0} };
std::vector<TF_Tensor*> output_tensors = { nullptr };
SCOPE_EXIT{ tf_utils::DeleteTensors(output_tensors); }; // Auto-delete on scope exit.
auto session = tf_utils::CreateSession(graph);
SCOPE_EXIT{ tf_utils::DeleteSession(session); }; // Auto-delete on scope exit.
if (session == nullptr) {
std::cout << "Can't create session" << std::endl;
return 2;
}
auto code = tf_utils::RunSession(session, input_ops, input_tensors, out_ops, output_tensors);
if (code == TF_OK) {
auto result = tf_utils::GetTensorData<float>(output_tensors[0]);
outImage = avl::Image(width, height, avl::PlainType::UInt8, 3, atl::NIL);
//auto values = output.get_data<int64_t>();
for (int w = 0; w < width; ++w) {
for (int h = 0; h < height; ++h) {
//int data = result[width * height * width * h + w];
int idx = getMaxIndex(result, 5, width, height, w, h);
uint8_t* pixel = outImage.Ptr<uint8_t>(w, h);
*pixel = (uint8_t)inColors[idx].X();
*(pixel + 1) = (uint8_t)inColors[idx].Y();
*(pixel + 2) = (uint8_t)inColors[idx].Z();
}
}
//std::cout << "Output vals: " << result[0] << ", " << result[1] << ", " << result[2] << ", " << result[3] << std::endl;
}
else {
std::cout << "Error run session TF_CODE: " << code;
return code;
}
But I can not wrap my head around how to perform operations on tensors in C API and documentation is non existing.
Solution
Ok, I managed to found the answer by reading this repo.
First you have to create:
TF_Tensor* input_tensor = tf_utils::CreateTensor(TF_FLOAT, shape, floatv);
TF_Status* status = TF_NewStatus();
TFE_TensorHandle* input_tensor_tfe_handle = TFE_NewTensorHandle(input_tensor, status);
TFE_ContextOptions* contx_opts = TFE_NewContextOptions();//, &TFE_DeleteContextOptions);
TFE_Context* tfe_context = TFE_NewContext(contx_opts, status);
Than you have to pass this variables into something like:
TFE_TensorHandle* TransposeTensor(TF_Status* status, TFE_TensorHandle* tfe_tensor, TFE_Context* context, std::vector<int> perm) {
TFE_Op* op = TFE_NewOp(context, "Transpose", status);
TFE_OpAddInput(op, tfe_tensor, status);
int shape = perm.size();
TF_Tensor* perm_tensor = tf_utils::CreateTensor(TF_INT32, { shape }, perm);
TFE_TensorHandle* perm_tfe = TFE_NewTensorHandle(perm_tensor, status);
TFE_OpAddInput(op, perm_tfe, status);
TF_DataType Tperm = static_cast<TF_DataType>(3);
//// Attributes
TFE_OpSetAttrType(op, "Tperm", Tperm);
SCOPE_EXIT{
TFE_DeleteTensorHandle(perm_tfe);
TF_DeleteTensor(perm_tensor);
};
//// Execute Op
int num_outputs_op = 1;
TFE_TensorHandle* res[1] = { nullptr };
TFE_Execute(op, res, &num_outputs_op, status);
TF_Code code = TF_GetCode(status);
return res[0];
}
This code basicaly construct egear operation, by first creating op, than adding arguments and arguments type and finally exacuting the operation. To get transformed tensor you have to do:
TF_Tensor* tensor = TFE_TensorHandleResolve(handle, status);
Answered By - TheDude
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.