我正在尝试使用TF 2.0beta C api(c_api.h)实现fashion-mnist教程的培训部分。
简而言之,按照前面提到的教程使用python创建模型。然后将模型另存为.pb文件,然后将其与训练数据(28 * 28灰度图像)和训练标签(标量范围为[0-9])一起加载到我的C程序中。
您可能知道,TF C api的文档质量很差(充满挫败感的插入物here),并且在互联网上here,here经过大量阅读和搜索之后, here和here等许多其他地方,我仍然无法完成此任务(详情请参见下文)。
我不想在代码中淹没这个问题,但我希望您能够访问我已经完成的工作。
生成模型的python script通过以下方式将其保存: keras.experimental.export_saved_model。
要简单地执行代码: python3 createModel.py。
已保存的模型将存储在一个名为“ saved_model”的新文件夹中。 这很重要,因为此名称在C代码中进行了硬编码
Data也可以通过python TF获得训练模型的方法。
再次:python getData.py。
将数据和相应的标签另存为data.txt和labels.txt ,这些名称很重要,因为它们是在我的C代码中硬编码的
所有代码都驻留在single文件中,并提供了我认为必要的注释。只要您具有libtensorflow.so.2和libtensorflow_framework.so.2.0.0
,编译就应该很简单 gcc -Wall -I /path/to/TFlib/include -L /path/to/TFlib/lib -o trainMnist trainMnist.c
在x86_64系统中,不应有警告(至少在我尝试过的两台计算机中)
编译后执行:
LD_LIBRARY_PATH=/path/to/TFlib/lib ./trainMnist
如果.so文件已经可以访问,则可以跳过LD_LIBRARY_PATH。
如果您没有TF共享对象文件,那么如果您敢于信任某个随机人士的编译代码,我很乐意与任何人共享它们。您可以使用以下方法自己生成它:
git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow
git checkout r2.0
./configure
bazel build -c opt //tensorflow/tools/lib_package:libtensorflow
头文件和.so文件将位于bazel-bin / tensorflow / tensorflow / tools / lib_package / libtensorflow.tar.gz
假设saved_model
,data.txt
和labels.txt
与./trainMnist运行所在的目录相同,则仅应打印TF警告,并从代码本身输出一些详细信息。
但感兴趣的功能是:
int Belly_ModelTrain(model_t *model,
float **train_data,
float **label_data,
int numPoints)
model
是容纳重要成员以开始TF会话的结构
train_data
包含28 * 28 = 784个浮点数的numPoints数组(图像的像素值)
label_data
包含10个浮点数的numPoints数组(除该图像的真实标签外,其余均为0)。
numPoints
是已加载的图像数。 numPoints
的值在main中进行了硬编码。
在此功能中,训练通过以下方式进行:
// The actual tensors that will hold the data and be passed to TF_SessionRun
TF_Tensor *x, *y;
// Establish the dimentions of the input data
const int64_t dimTrain[] = {numPoints, 784}; //pixel values
const int64_t dimLabel[] = {numPoints, 10}; //labels
{
//Boilerplate allocation code happens here
size_t nbytesT = (numPoints*784) * sizeof(float);
x = TF_AllocateTensor(TF_FLOAT, dimTrain, 2, nbytesT);
size_t nbytesL = (numPoints*10) * sizeof(float);
y = TF_AllocateTensor(TF_FLOAT, dimLabel, 2, nbytesL);
}
//Copy the data in my arrays to the tensors
memcpy(TF_TensorData(x), train_data, nbytesT);
memcpy(TF_TensorData(y), label_data, nbytesL);
//TBH I really don't know what is going on in these two lines
//Establish model inputs and model targets(labels)
TF_Output inputs[2] = {model->input, model->target};
TF_Tensor* input_values[2] = {x, y};
//training operation defined in model
const TF_Operation* train_op[1] = {model->train_op};
//Run the model with the data
TF_SessionRun(model->session,
NULL,
inputs, input_values, 2,
NULL, NULL, 0,
train_op, 1,
NULL, model->status);
TF_DeleteTensor(x);
TF_DeleteTensor(y);
//Return 0 on success
return Belly_CheckStatus(model->status);
我希望该函数运行良好,并根据模型的状态返回TF_OK,返回0。当然这失败了,我得到了:
从错误消息中我了解到我的target
输入的格式错误。我尝试更改label_data
的传递方式以及更改dimL
都没有成功。
答案 0 :(得分:0)
因此,事实证明我在使用C api时仍在用python进行思考。
在trainMnist.c中,数据被读入一个数组数组(浮点数):
int Belly_ReadData(float **points, int numSamples) {
...
...
...
for(int i = 0; i < numSamples; i++) {
//Allocate memory for datapoint
points[i] = (float *)malloc(784*sizeof(float));
...
...
...
//Read other 783 pixels
for(int j = 0; j < 783; j++) {
point = strtok(NULL,"\t");
points[i][j+1] = strtof(point,&err);
if(*err != 0) return -1;
}
...
}
}
此后,将这个数组数组馈入输入张量“ x”:
int Belly_ModelTrain(model_t *model,
float **train_data,
float **label_data,
int numPoints) {
...
...
...
// Allocate data for tensors
x = TF_AllocateTensor(TF_FLOAT, dimTrain, 2, nbytesT);
if(x==NULL) {
printf("ERROR allocate x\n");
return -1;
}
y = TF_AllocateTensor(TF_FLOAT, dimLabel, 2, nbytesL);
if(y==NULL) {
printf("ERROR allocate y\n");
return -1;
}
// Copy data from arrays into tensors
memcpy(TF_TensorData(x), train_data, nbytesT); //<===== "train_data should be an array of floats"
memcpy(TF_TensorData(y), label_data, nbytesL); //<===== "label_data should be an array of floats"
...
...
...
按照我理解的方式,我将垃圾数据同时传递到张量x和y。
将为想要尝试的任何人发布更正的代码。