问题描述
我使用tensorflow的c api遇到了一个问题。基本上,我想做的是通过图像分类器模型(在本例中为mobilenetv2模型)运行图像,并为每个图像计算特征向量。下面的代码是一个简单的程序,它将目录作为参数(包含图像的目录)。该代码工作正常,除了它会随机阻塞并使系统崩溃。永远不要在同一文件上。单独提交时,它在工作时崩溃。通常,该目录包含大量文件,但是它确实以某种规律性出现。我已将该程序简化为重现该错误的基本要点。
系统死机,出现类似以下错误:
EXT4-fs error (device sda1): ext4_find_entry:1456: inode #390913: comm systemd-journal: reading directory lblock 0
唯一可能的是硬重启。我本来要提交一个错误报告,但是我想先在这里尝试。如果有人有任何见解,将不胜感激。
我的系统信息是:
Linux 4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) x86_64 GNU/Linux
您可以编译以下代码:
g++ -otest test.cpp -g -O0 -Wall -lboost_filesystem -lboost_system -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -ltensorflow
然后通过向其传递包含图像的目录来运行:./test / path / to / image / dir
有一个model_file字符串变量指向mobilenetv2张量流模型。只需将模型放在目录中,或编辑代码以获取正确的路径。此处提供模型:
https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.4_224.tgz
#include <iostream>
#include <cstdlib>
#include <string>
#include <cassert>
#include <boost/filesystem.hpp>
#include <opencv2/core/core_c.h>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/imgcodecs/imgcodecs_c.h>
#include <tensorflow/c/c_api.h>
using namespace std;
using namespace cv;
namespace fs=boost::filesystem;
static const string model_file = "mobilenet_v2_1.4_224_frozen.pb";
static const string input_layer = "input";
static const string output_layer = "MobilenetV2/Logits/AvgPool";
static int Height = 224;
static int Width = 224;
void NoOpDeAlloc(void *data,size_t len,void *arg){}
void freebuffer(void *data,size_t len){
free(data);
}
CvMat* load_image(const string &filename,const int height,const int width){
CvMat *src = cvLoadImageM(filename.c_str(),CV_LOAD_IMAGE_COLOR);
if (src == NULL) return NULL;
CvMat *img_prime = cvCreateMat(src->rows,src->cols,CV_32FC3);
CvMat *img_resized = cvCreateMat(height,width,CV_32FC3);
CvMat *dst = cvCreateMat(height,CV_32FC3);
CvMat *div = cvCreateMat(height,CV_32FC3);
/* convert to float type */
cvConvertScale(src,img_prime,1,0);
/* resize to heightxwidth */
cvResize(img_prime,img_resized,CV_INTER_CUBIC);
/* normalize values */
CvScalar norm_constant = {255,255,255};
cvSet(div,norm_constant,NULL);
cvDiv(img_resized,div,dst,1);
cvReleaseMat(&src);
cvReleaseMat(&img_resized);
cvReleaseMat(&img_prime);
cvReleaseMat(&div);
return dst;
}
TF_Buffer* readfromfile(const string &filename){
FILE *file = fopen(filename.c_str(),"rb");
if (file == NULL) return NULL;
fseek(file,SEEK_END);
size_t file_size = ftell(file);
fseek(file,SEEK_SET);
assert(file_size > 0);
unsigned char *data = (unsigned char*)malloc(file_size);
size_t n = fread(data,file_size,file);
assert(n == file_size);
TF_Buffer *buf = TF_NewBuffer();
buf->data = data;
buf->length = file_size;
buf->data_deallocator = freebuffer;
fclose(file);
return buf;
}
int ProcessFiles(const fs::path &dirname){
fs::recursive_directory_iterator dir(dirname),end;
int ndims = 4;
int64_t dims[4] = { 1,Height,Width,3};
cout << "TF Model graph setup" << endl;
TF_Graph *graph = TF_NewGraph();
TF_Status *status = TF_NewStatus();
TF_ImportGraphDefOptions *opts = TF_NewImportGraphDefOptions();
TF_Buffer *graph_def = readfromfile(model_file);
assert(graph_def != NULL);
TF_GraphImportGraphDef(graph,graph_def,opts,status);
assert(TF_GetCode(status) == TF_OK);
TF_Sessionoptions *sess_opts = TF_NewSessionoptions();
TF_Session *sess = TF_NewSession(graph,sess_opts,status);
TF_Tensor *img_tensor;
TF_Tensor *output_tensor;
TF_Output input = { TF_GraphOperationByName(graph,input_layer.c_str()),0 };
TF_Output output = { TF_GraphOperationByName(graph,output_layer.c_str()),0 };
assert(input.oper != NULL);
assert(output.oper != NULL);
TF_DeleteBuffer(graph_def);
TF_DeleteSessionoptions(sess_opts);
TF_DeleteImportGraphDefOptions(opts);
cout << "Read files " << endl;
int count = 0;
for (;dir!=end;++dir){
string filename = dir->path().string();
if (fs::is_directory(dir->status())){
cout << "directory: " << filename << endl;
} else if (fs::is_regular_file(dir->status())){
cout << dec << "(" << ++count << ") " << filename << endl;
CvMat *img = load_image(filename,Width);
int total = Height*Width*3;
img_tensor = TF_NewTensor(TF_FLOAT,dims,ndims,(void*)img->data.fl,total*sizeof(float),NoOpDeAlloc,NULL);
assert(img_tensor != NULL);
TF_SessionRun(sess,NULL,&input,&img_tensor,&output,&output_tensor,status);
if (TF_GetCode(status) != TF_OK){
cout << "unale to complete session: " << TF_Message(status) << endl;
break;
}
TF_DeleteTensor(img_tensor);
TF_DeleteTensor(output_tensor);
img_tensor = NULL;
output_tensor = NULL;
cvReleaseMat(&img);
} else {
cout << "special file: " << filename << endl;
}
}
TF_DeleteGraph(graph);
TF_DeleteSession(sess,status);
TF_DeleteStatus(status);
return count;
}
int main (int argc,char **argv){
assert(argc == 2);
string dir = argv[1];
cout << "directory: " << dir << endl;
int n = ProcessFiles(dir);
cout << "Processed files: " << n << endl;
cout << "Done" << endl;
return 0;
}
编译:
g ++ -otest test.cpp -g -O0 -Wall -lboost_filesystem -lboost_system -lopencv_core
-lopencv_imgproc -lopencv_imgcodecs -ltensorflow
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)