Выход модели uTensor не равен ожидаемому выходу - PullRequest
2 голосов
/ 23 сентября 2019

В настоящее время я работаю над проектом, где требуется uTensor .uTensor, кажется, работает правильно, однако я столкнулся с проблемой, которую я (очевидно) не могу исправить самостоятельно.

Определение проблемы

Я создал простой скрипт на python, который генерирует и сохраняет модель в файл.Эта сохраненная модель впоследствии может быть преобразована в код C ++ с помощью uTensor-cli .Сгенерированный код C ++ будет запущен на плате разработчиков ARM.

Все работает нормально, ошибок нет.Однако, когда я создаю модель наподобие «xW + b», вывод модели на devboard всегда равен некоторому статическому значению, которое не равно выводу модели из скрипта python.

Дело в том, что когда используется простая модель, такая как "W + b" (здесь не используется входной тензор), вывод на панели управления ARM равен выводу скрипта Python.И все работает как положено.

Мои выводы

При использовании входного тензора (ничего большого, только одномерный массив, например, [1,0]), приборная панель ARM всегда выводит какое-то странное значение по сравнению с выводом питонаскрипт.Когда не используется входной тензор, все работает как положено.

Другая информация

Поскольку в uTensor пока нет вики, я использовал учебник, чтобы узнать о uTensor.Учебное пособие, которое я использовал, можно найти здесь: https://blog.hackster.io/simple-neural-network-on-mcus-a7cbd3dc108c Код, который я написал, основан на учебном пособии и не включает в себя какую-либо функцию затрат / потерь и не способен «научиться» чему-либо.Код только для отладки.

Вопрос

По какой причине входной тензор заставляет приложение выводить неожиданные значения?Как я могу это исправить?

Код и вывод

Сценарий Python

import tensorflow as tf
import numpy as np
from tensorflow.python.framework import graph_util as gu

def weightVariable(shape, name):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial, name=name)

def createLayer(layerInput, inputSize, outputSize, layerNumber, dropout = -1):
    layerNumber = str(layerNumber)

    #Define weight and bias
    W_fc = weightVariable([inputSize, outputSize], 'W_fc' + layerNumber)

    #Formula Wx+b=y
    a_fc = tf.matmul(layerInput, W_fc, name='y_pred' + layerNumber)
    return a_fc

def saveGraph(saver, sess, y_pred):
    outNodes = [y_pred.op.name]
    subGraphDef = gu.remove_training_nodes(sess.graph_def)
    subGraphDef = gu.convert_variables_to_constants(sess, subGraphDef, outNodes)

    #Save the checkpoint
    ckptPath = saver.save(sess, "./chkps/model.ckpt")

    #Save the graph
    graphPath = tf.train.write_graph(subGraphDef, "./graph", "mlp.pb", as_text=False)

    #Print some usefull messages
    print("Saved checkpoint to: " + ckptPath)
    print("Saved graph to: " + graphPath)
    print("Output tensor: " + y_pred.op.name)

    def restoreGraph(saver, sess):
    tf.reset_default_graph()
    saver.restore(sess, "./chkps/model.ckpt")

def main():
    data = [
        [0,0],
        [0,1],
        [1,0],
        [1,1]
    ]
    labels = [
        [0],
        [1],
        [1],
        [0]
    ]
    inputSize = 2
    outputSize = 1

    #Placeholders for the input and output
    x_input = tf.placeholder(tf.float32, [None, inputSize], name='x_input')
    y_output = tf.placeholder(tf.float32, [None, outputSize], name='y_output')

    #Layers with relu activation
    inputLayer = createLayer(x_input, inputSize, outputSize, 0)

    #Start a session
    sess = tf.Session()
    saver = tf.train.Saver()

    #Run the session
    sess.run(tf.global_variables_initializer())
    feed_dict = {x_input: data, y_output: labels}
    sess.run(inputLayer, feed_dict=feed_dict)

    #Save the graph
    saveGraph(saver, sess, inputLayer)

    #Test the algorithm
    for i in range(0,4):
        testInput = [data[i]]
        output = sess.run(inputLayer, feed_dict={x_input: testInput})[0][0]
        print("Test output " + str(i) + ": " + str(output))

    #End the session
    sess.close()

#Execute the main function
main()

Вывод

Saved checkpoint to: ./chkps/model.ckpt
Saved graph to: ./graph/mlp.pb
Output tensor: y_pred0
Test output 0: 0.0
Test output 1: 0.0034507334
Test output 2: 0.07698402
Test output 3: 0.080434754

Преобразование в C ++

utensor-cli convert graph/mlp.pb --output-nodes=y_pred0

Код C ++

#include "models/mlp.hpp"
#include "tensor.hpp"
#include "mbed.h"
#include <stdio.h>

const int testData[4][2] = {{0,0},{0,1},{1,0},{1,1}};

Serial uart(USBTX, USBRX, 115200);

int main(void){
    printf("Compiled at: ");
    printf(__TIME__);
    printf("\n");

    for(int i = 0; i < 4; i++){
        //Create the context class. 
        Context ctx;
        Tensor *input_x = new WrappedRamTensor<int>({1, 2}, (int*) testData[i]);

        get_mlp_ctx(ctx, input_x);          //Pass the tensor to the context
        S_TENSOR pred_tensor = ctx.get("y_pred0:0");    //Get the output tensor
        ctx.eval();                 //Trigger the inference

        float prediction = *(pred_tensor->read<float>(0,0));    //Get the result
        printf("Test output %d: %f \r\n", i,  prediction);  //Print the result

    }

    printf("\n");
    return 0;
}

Последовательный выход

Compiled at: (Compile time)
Test output 0: 0.000000 
Test output 1: 0.000000 
Test output 2: 0.000000 
Test output 3: 0.000000 

1 Ответ

0 голосов
/ 24 сентября 2019

Смена типа данных в коде C ++ на float сделала свое дело!Я все еще не совсем уверен, как я не думал об этом.

...