2

我正在使用TensorflowSharp在Android手机上使用神经网络运行评估。我正在使用Unity构建项目。

我正在使用此处要求下列出的 tensorflowsharp 统一插件:https ://github.com/Unity-Technologies/ml-agents/blob/master/docs/Using-TensorFlow-Sharp-in-Unity.md 。

一切正常,但是提取结果非常慢。

我正在运行的网络是一个自动编码器,输出是一个尺寸为 128x128x16 的图像(是的,有很多输出通道)。

评估在约 0.2 秒内完成,这是可以接受的。但是,当我需要使用results[0].GetValue()它提取结果数据时非常慢。

这是我运行神经网络的代码

var runner = session.GetRunner();
runner.AddInput(graph[INPUT_NAME][0], tensor).Fetch(graph[OUTPUT_NAME][0]);
var results = runner.Run();

float[,,,] heatmaps = results[0].GetValue() as float[,,,]; // <- this is SLOW

问题: 我将结果转换为浮点数的最后一行需要大约 1.2 秒。

将结果数据读入浮点数组真的是网络实际评估时间的 5 倍以上吗?

是否有另一种方法来提取结果值?

4

1 回答 1

1

所以我找到了解决方案。我仍然不知道为什么GetValue()调用这么慢,但我找到了另一种检索数据的方法。

我选择手动读取可用的原始张量数据results[0].Data

我创建了一个小函数来处理这个作为GetValue的一个下降,(这里只是我期望硬编码的尺寸)

    private float[,,,] TensorToFLoats(TFTensor tensor)
    {

        IntPtr resData = tensor.Data;
        UIntPtr dataSize = tensor.TensorByteSize;

        byte[] s_ImageBuffer = new byte[(int)dataSize];
        System.Runtime.InteropServices.Marshal.Copy(resData, s_ImageBuffer, 0, (int)dataSize);
        int floatsLength = s_ImageBuffer.Length / 4;
        float[] floats = new float[floatsLength];
        for (int n = 0; n < s_ImageBuffer.Length; n += 4)
        {
            floats[n / 4] = BitConverter.ToSingle(s_ImageBuffer, n);
        }
        float[,,,] result = new float[1, 128, 128, 16];


        int i = 0;
        for (int y = 0; y < 128; y++)
        {
            for (int x = 0; x < 128; x++)
            {
                for (int p = 0; p < 16; p++)
                {
                    result[0, y, x, p] = floats[i++];
                }
            }
        }
        return result;
    }

鉴于此,我可以用以下代码替换我的问题中的代码

var runner = session.GetRunner();
runner.AddInput(graph[INPUT_NAME][0], tensor).Fetch(graph[OUTPUT_NAME][0]);
var results = runner.Run();

float[,,,] heatmaps = TensorToFLoats(results[0]);

这要快得多。GetValue我创建的函数花了 ~1 秒的时间在TensorToFloats~0.02 秒内获得了相同的数据

于 2018-08-13T21:50:05.790 回答