#c #c #tensorflow #c-api
#c #c #tensorflow #c-api
Вопрос:
Я пытаюсь реализовать Tensorflow C API для среды плагинов C , но результаты сегментации отличаются от графика Python. Мне сказали, что, возможно, нужно что-то сделать с правильным приведением к float / uint8, потому что результирующее изображение немного похоже на сетку 3×3 правильного изображения, но, как новичок в C / C , я не вижу, где именно ошибка. Он работает для простых задач классификации, таких как MNIST или сегментация с вводом в оттенках серого, но не работает для задач сегментации для изображений RGB.
Мы используем нашу собственную среду для представления изображений, но она эквивалентна OpenCV Mat. Я преобразую изображение в тензор, подобный этому:
void* tensor_data = image->Buffer().Ptr();
int64_t dims4[]={1,512,512,3};
int ndims = 4;
std::shared_ptr<TF_Tensor> tensor = TF_NewTensor(
TF_FLOAT, dims4, ndims, tensor_data, 3*512*512*sizeof(float) , noDealloc, nullptr
);
Так что, возможно, ошибка может быть здесь, если, например, данные RGB неправильно считаны. Но я попытался сегментировать изображение с одинаковыми каналами, то есть изображение в 3D-оттенках серого, но это все равно не сработало.
Затем я запускаю модель, где все должно быть правильно, поскольку она работает для определенных задач, если только нет ошибки с Tensorflow.
//********* Read model
TF_Graph* Graph = TF_NewGraph();
TF_Status* Status = TF_NewStatus();
TF_SessionOptions* SessionOpts = TF_NewSessionOptions();
TF_Buffer* RunOpts = NULL;
const char* saved_model_dir = m_path.c_str(); // Path of the model
const char* tags = "serve"; // default model serving tag; can change in future
int ntags = 1;
TF_Session* Session = TF_LoadSessionFromSavedModel(SessionOpts, RunOpts, saved_model_dir, amp;tags, ntags, Graph, NULL, Status);
tf_utils::throw_status(Status);
//****** Get input tensor operation
int NumInputs = 1;
TF_Output* Input = (TF_Output*)malloc(sizeof(TF_Output) * NumInputs);
const std::string in_param_name = "input_op:" std::to_string(0);
const std::string in_op_name = m_params.GetString(in_param_name.c_str(), "").c_str();
TF_Output t0 = {TF_GraphOperationByName(Graph, in_op_name.c_str()), 0};
if(t0.oper == NULL){
printf("ERROR: Failed TF_GraphOperationByName Inputn");
}
Input[0] = t0;
//********* Get Output tensor operation
int NumOutputs = 1;
TF_Output* Output = (TF_Output*)malloc(sizeof(TF_Output) * NumOutputs);
const std::string out_param_name = "output_op:" std::to_string(0);
const std::string out_op_name = m_params.GetString(out_param_name.c_str(), "").c_str();
TF_Output t2 = {TF_GraphOperationByName(Graph, out_op_name.c_str()), 0};
if(t2.oper == NULL){
printf("ERROR: Failed TF_GraphOperationByName Outputn");
}
Output[0] = t2;
//********* Allocate data for inputs amp; outputs
TF_Tensor** InputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*NumInputs);
TF_Tensor** OutputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*NumOutputs);
InputValues[0] = tensor.get();
// //Run the Session
TF_SessionRun(Session, NULL, Input, InputValues, NumInputs, Output, OutputValues, NumOutputs, NULL, 0,NULL , Status);
tf_utils::throw_status(Status);
// //Free memory
TF_DeleteGraph(Graph);
TF_DeleteSession(Session, Status);
TF_DeleteSessionOptions(SessionOpts);
TF_DeleteStatus(Status);
std::shared_ptr<TF_Tensor> out_tensor(OutputValues[0], TF_DeleteTensor);
Затем я конвертирую его обратно в изображение, где, я думаю, ошибка может быть:
const TF_DataType tensor_type = TF_TensorType(out_tensor.get());
itwm_type = amp;ITWM::IMAGE_GREY_F; //Float image
// Create the image and copy the buffer.
const float* data = reinterpret_cast<float*>(TF_TensorData(out_tensor.get()));
const std::size_t byte_size = TF_TensorByteSize(out_tensor.get());
const std::size_t size = byte_size/sizeof(float);
ITWM::CImage* image = new ITWM::CImage(*itwm_type, ITWM::CSize(size));
memcpy(image->Buffer().Ptr(), data, byte_size);
Я попытался преобразовать его в разные форматы, но ошибка та же или результаты NaN. Я также попытался изменить входные данные на три изображения в оттенках серого и сложить их вместе, но это все равно не сработало.
Я был бы очень благодарен, если вы поможете мне найти ошибку!
PS: Извините, что вы не можете запустить его, и это немного запутанно, я скопировал его из трех разных плагинов.
Комментарии:
1. Хорошо, я мог бы это решить, поэтому, если кто-то наткнется на ту же проблему, API Tensorflow C нуждается в чередовании для изображений RGB. Это означает, что сначала мне нужно переключить оси X и Z (здесь первый канал и цветовой канал, на изображение (3x512x512)), а затем создать тензор с нормальными размерами (здесь (512x512x3)).
Ответ №1:
Из комментариев,
API Tensorflow C требует чередования для изображений RGB. Это означает, что сначала необходимо переключить оси X и Z (здесь первый канал и цветовой канал, на изображение (3x512x512)), а затем создать тензор с нормальными размерами (здесь (512x512x3)) (перефразировано из Mathematicus)