raspberry pi 1でtensorflow lite その5


概要

raspberry pi 1でtensorflow liteやってみた。
kerasモデルからtfliteファイルを作ってみた。
ラズパイで、実行。
データセットは、xor.

Makefileを書く。

CXXFLAGS ?= -I../tensorflow -I../tensorflow/tensorflow/lite/tools/make/downloads/flatbuffers/include
LDFLAGS ?= -L../tensorflow/tensorflow/lite/tools/make/gen/rpi_armv6l/lib

.PHONY: all clean

all: lite2

lite2: main.cpp
    g++ --std=c++11 main.cpp -O2 $(CXXFLAGS) $(LDFLAGS) -ltensorflow-lite -lstdc++ -lpthread -ldl -lm -o lite2

clean:
    rm -f lite2

Makeして、実行。

#include <vector>
#include <chrono>
#include <iostream>
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <math.h>
using namespace std;

bool is_error(TfLiteStatus const & status) 
{
    return status != kTfLiteOk;
}
int main(int argc, char const * argv[]) 
{
    std::string a = "sin_model.tflite";
    TfLiteStatus status;
    std::unique_ptr<tflite::FlatBufferModel> model;
    std::unique_ptr<tflite::Interpreter> interpreter;
    std::cout << "0: Loading model: " << a << std::endl;
    model = tflite::FlatBufferModel::BuildFromFile(a.c_str());
    if (!model) 
    {
      std::cerr << "0: Failed to load the model." << std::endl;
      return -1;
    }
    std::cout << "1: The model was loaded successful." << std::endl;
    tflite::ops::builtin::BuiltinOpResolver resolver;
    tflite::InterpreterBuilder(* model, resolver)(& interpreter);
    std::cout << "2: interpreter was build successful." << std::endl;
    status = interpreter->AllocateTensors();
    if (is_error(status)) 
    {
      std::cerr << "2: Failed to allocate the memory for tensors." << std::endl;
      return -1;
    }
    std::cout << "3: The model was allocated successful." << std::endl;
    ofstream fout("pred.csv");
    float * in = interpreter->typed_input_tensor<float>(0);
    float * out = interpreter->typed_output_tensor<float>(0);
    fout << "x,y,p" << endl; 
    int i;
    double x, 
        y;
    double pi = acos(-1.0);
    for (i = -20; i < 20; i++)
    {
        x = (double) i / 6;
        y = sin(x);
        in[0] = x;
        status = interpreter->Invoke();
        if (is_error(status)) 
            {
            std::cerr << "3: Failed to invoke the interpreter." << std::endl;
            return -1;
            }
        std::printf ("%2.2f\n", out[0]);
        fout << x << "," << y << "," << out[0] << endl;
    }
    cout << "ok" << endl;
    fout.close();
    return 0;
}

結果

0,1 = 0.97118
1,0 = 0.971399
0,0 = 0.0115943
1,1 = 0.0372914

以上。