Tensorflow Lite-输入形状必须为5维误差

时间:2020-06-10 20:28:51

标签: android tensorflow2.0 tensorflow-lite

我正在尝试将tensorflow模型移植到tensorflow lite以在android应用程序中使用它。转换成功,除Internal error: Failed to run on the given Interpreter: input must be 5-dimensional以外的所有内容都可以运行。原始模型的输入为input_shape=(20, 320, 240, 1),它是20 320 x 240灰度图像(因此...,1)。这是重要的代码:

List<Mat> preprocessedFrames = preprocFrames(buf);
//has length of 20 -> no problem there (shouldn't affect dimensionality either...)

        int[] output = new int[2];
        float[][][] inputMatrices = new float[preprocessedFrames.toArray().length][320][240];

        for(int i = 0; i < preprocessedFrames.toArray().length; i++) {
            Mat inpRaw = preprocessedFrames.get(i);

            Bitmap data = Bitmap.createBitmap(inpRaw.cols(), inpRaw.rows(), Bitmap.Config.ARGB_8888);
            Utils.matToBitmap(inpRaw, data);

            int[][] pixels = pixelsFromBitmap(data);
            float[][] inputMatrix = inputMatrixFromIntPixels(pixels);
            // returns float[][] with floats from 0 to 1

            inputMatrices[i] = inputMatrix;
        }

        try{

            detector.run(inputMatrices, output);
            Debug("results: " + output.toString());
        }

该模型为我提供了2个神经元的输出,并转换为2个标签。 模型代码如下:

model = tf.keras.Sequential(name='detector')
    model.add(tf.keras.layers.Conv3D(filters=(56), input_shape=(20, 320, 240, 1), strides=(2,2,2), kernel_size=(3,11,11), padding='same', activation="relu"))
    model.add(tf.keras.layers.AveragePooling3D(pool_size=(1,4,4)))
    model.add(tf.keras.layers.Conv3D(filters=(72), kernel_size=(4,7,7), strides=(1,2,2), padding='same'))
    model.add(tf.keras.layers.Conv3D(filters=(81), kernel_size=(2,4,4), strides=(2,2,2), padding='same'))
    model.add(tf.keras.layers.Conv3D(filters=(100), kernel_size=(1,2,2), strides=(3,2,2), padding='same'))
    model.add(tf.keras.layers.Conv3D(filters=(128), kernel_size=(1,2,2), padding='same'))
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(768, activation='tanh', kernel_regularizer=tf.keras.regularizers.l2(0.011)))
    model.add(tf.keras.layers.Dropout(rate=0.1))
    model.add(tf.keras.layers.Dense(256, activation='sigmoid', kernel_regularizer=tf.keras.regularizers.l2(0.012)))
    model.add(tf.keras.layers.Dense(2, activation='softmax'))

    model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.00001), loss=tf.keras.losses.CategoricalCrossentropy(),
        metrics=['accuracy'])

编辑:我按如下所示打印了第一个输入张量:

int[] shape = detector.getInputTensor(0).shape();
            for(int r = 0; r < shape.length; r++){
                Log.d("********" + r, "*******: " + r + " : " + shape[r]);
            }

首先,我得到输出[1,20,320,240,1],然后我仅得到[20,320,240]。我现在真的很绝望...

1 个答案:

答案 0 :(得分:0)

所以,我自己弄清楚了,看来我真的只需要通过将内容放到第一维并将每个像素放到第五维来使输入5维。我不知道为什么,但是我会接受那个xD。

float[][] output = new float[1][2];
            float[][][][][] inputMatrices = new float[1][preprocessedFrames.toArray().length][320][240][1];

            for(int i = 0; i < preprocessedFrames.toArray().length; i++) {
                Mat inpRaw = preprocessedFrames.get(i);

                Bitmap data = Bitmap.createBitmap(inpRaw.cols(), inpRaw.rows(), Bitmap.Config.ARGB_8888);
                Utils.matToBitmap(inpRaw, data);

                int[][] pixels = pixelsFromBitmap(data);
                float[][] inputMatrix = inputMatrixFromIntPixels(pixels);

                for (int j = 0; j < inputMatrix.length - 1; j++) {
                    for(int k = 0; k < inputMatrix[0].length - 1; k++) {
                        inputMatrices[0][i][k][j][0] = inputMatrix[j][k];
                    }
                }
            }