首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法在Kotlin中得到适当的TFLite模型输出

无法在Kotlin中得到适当的TFLite模型输出
EN

Stack Overflow用户
提问于 2022-08-06 15:54:02
回答 1查看 116关注 0票数 1

我使用了卡格尔的FER2013数据集,并训练了一个CNN模型。将模型保存为TFLite。用它做了一个Kotlin应用程序。现在我无法得到适当的输出。模型的示例输出:[0. 0. 0. 1. 0. 0. 0.]表示高兴

请检查MainActivity.kt的代码。我是纯粹的努比。非常感谢你对我的支持。

代码语言:javascript
运行
复制
package com.example.mooddetector

import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.example.mooddetector.databinding.ActivityMainBinding
import com.example.mooddetector.ml.MoodDetector
import org.tensorflow.lite.DataType
import org.tensorflow.lite.support.image.ColorSpaceType
import org.tensorflow.lite.support.image.TensorImage
import org.tensorflow.lite.support.image.ops.TransformToGrayscaleOp
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer


class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var imageView: ImageView
    private lateinit var button: Button
    private lateinit var tvOutput: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        imageView = binding.imageView
        button = binding.btnCaptureImage
        tvOutput = binding.tvOutput
        val buttonLoad = binding.btnLoadImage
        button.setOnClickListener {
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)
                == PackageManager.PERMISSION_GRANTED
            ) {
                takePicturePreview.launch(null)
            } else {
                requestPermission.launch(android.Manifest.permission.CAMERA)
            }
        }

    }

        private val requestPermission = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
            if (granted) {
                takePicturePreview.launch(null)
            } else {
                Toast.makeText(this, "Permission Denied.", Toast.LENGTH_SHORT).show()
            }
        }

        private val takePicturePreview = registerForActivityResult(ActivityResultContracts.TakePicturePreview()){bitmap->
             if(bitmap!=null){
                 imageView.setImageBitmap(bitmap)
                 outputGenerator(bitmap)
                 }
            }


    private fun outputGenerator(bitmap: Bitmap){
        val model = MoodDetector.newInstance(this)
        
        val newBitmap = Bitmap.createScaledBitmap(bitmap, 48, 48, true)
        val tfimage = TensorImage(DataType.FLOAT32)
        tfimage.load(newBitmap)
        val tfimagegrayscale = TransformToGrayscaleOp().apply(tfimage)
        val tensorbuffr=tfimagegrayscale.tensorBuffer
        val tensorimg = TensorImage(DataType.FLOAT32)
        tensorimg.load(tensorbuffr,ColorSpaceType.GRAYSCALE)
        val byteBuffer = tensorimg.buffer

        // Creates inputs for reference.
        val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 48, 48, 1), DataType.FLOAT32)
        inputFeature0.loadBuffer(byteBuffer)
        
        // Runs model inference and gets result.
        val outputs = model.process(inputFeature0)
        val outputFeature0 = outputs.outputFeature0AsTensorBuffer
        tvOutput.text = outputFeature0.toString()
        Log.d("TAG", outputs.toString())
        Log.d("TAG", outputFeature0.toString())
        
//        val data1 = outputFeature0.floatArray
//        Log.d("TAG2", outputFeature0.dataType.toString())
//        Log.d("TAG2", data1[0].toString())

//        val probabilityBuffer = TensorBuffer.createFixedSize(intArrayOf(1, 1001), DataType.UINT8)

        // Releases model resources if no longer used.
        model.close()

    }
}

最后两个日志文件的输出是: com.example.mooddetector.ml.MoodDetector$Outputs@a04fe1 org.tensorflow.lite.support.tensorbuffer.TensorBufferFloat@ca3b548

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-06 16:39:02

对于您可能有用的TensorBufferFloat列表2方法的文档

float[] getFloatArray() 返回存储在此缓冲区中的值的浮点数组。浮点getFloatValue(int absIndex) 返回给定索引处的浮点值。

文档是for Java的,这意味着在Kotlin中,所有getter(和setter)只是成为正常的字段/属性访问,即.getFloatArray()变成了.floatArray

因此,如果您使用.floatArray获得整个数组,您只需将值与一些分隔符连接起来,就可以得到一个字符串表示。

代码语言:javascript
运行
复制
val output = outputFeature0.floatArray.joinToString(", ", "[", "]")

Log.d("TAG", output)

如果要控制格式设置,请使用DecimalFormat

代码语言:javascript
运行
复制
val pattern = "#.0#" // rounds to 2 decimal places if needed
val locale = Locale.ENGLISH
val formatter = DecimalFormat(pattern, DecimalFormatSymbols(locale))
formatter.roundingMode = RoundingMode.HALF_EVEN // this is the default rounding mode anyway    

val output = outputFeature0.floatArray.joinToString(", ", "[", "]") { value ->
    formatter.format(value)
}

Log.d("TAG", output)

如果需要在不同的地方执行这种格式设置,则可以将逻辑移到扩展方法中。

代码语言:javascript
运行
复制
fun FloatArray.joinToFormattedString(): String {
    val pattern = "#.0#" // rounds to 2 decimal places if needed
    val locale = Locale.ENGLISH
    val formatter = DecimalFormat(pattern, DecimalFormatSymbols(locale))
    formatter.roundingMode = RoundingMode.HALF_EVEN // this is the default rounding mode anyway
    return this.joinToString(
        separator = ", ",
        prefix = "[",
        postfix = "]",
    ) { value ->
        formatter.format(value)
    }
}

然后你可以简单的打电话

代码语言:javascript
运行
复制
Log.d("TAG", outputFeature0.floatArray.joinToFormattedString())
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73261241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档