在 Spring 中使用 TensorFlow 模型进行推理/预测 - Kotlin

using TensorFlow Model in Spring for inference/predictions - Kotlin

提问人:Saher Al-Sous 提问时间:10/17/2023 最后编辑:Saher Al-Sous 更新时间:10/19/2023 访问量:58

问:

我正在尝试找到一种在 我成功加载了模型,并创建了所需的张量,但由于此错误,我无法调用模型以获取结果:tensorflowSpring Boot

原因:org.tensorflow.exceptions.TFInvalidArgumentException:期望 arg[0] 为浮点数,但提供了 uint8

我检查了模型签名,它是这样的:

Signature for "serving_default":
    Method: "tensorflow/serving/predict"
    Inputs:
        "input_1": dtype=DT_FLOAT, shape=(-1, 299, 299, 3)
    Outputs:
        "dense_3": dtype=DT_FLOAT, shape=(-1, 41)

Signature for "__saved_model_init_op":
    Outputs:
        "__saved_model_init_op": dtype=DT_INVALID, shape=()

我的张量详细信息是 .DT_UINT8 tensor with shape [299, 299, 3]

当我将张量数据类型更改为浮点数时,如下所示:

val imageShape = TFloat32.tensorOf(runner.fetch(decodeImage).run()[0].shape())
        val reshape = tf.reshape(
            decodeImage,
            tf.array(
                -1.0f,
                imageShape[0].getFloat(),
                imageShape[1].getFloat(),
                imageShape[2].getFloat())
            )

我收到此错误:

org.tensorflow.exceptions.TFInvalidArgumentException:浮点数的 attr 'Tshape' 的值不在允许的值列表中:int32、int64

如何解决此问题?

如果有人好奇我是如何加载模型、创建张量并调用它的,这里是下面的代码

在以下位置加载模型:TFServices

fun model(): SavedModelBundle  {
        return SavedModelBundle
            .loader("/home/***/src/main/resources/pd/")
            .withRunOptions(RunOptions.getDefaultInstance())
            .load()
    }

构建张量并调用模型

        val graph = Graph()
        val session = Session(graph)
        val tf = Ops.create(graph)
        val fileName = tf.constant("/home/***/src/main/resources/keyframe_1294.jpg")
        val readFile = tf.io.readFile(fileName)
        val runner = session.runner()
        val decodingOptions = DecodeJpeg.channels(3)
        val decodeImage = tf.image.decodeJpeg(readFile.contents(), decodingOptions)
        val imageShape = runner.fetch(decodeImage).run()[0].shape()
        val reshape = tf.reshape(
            decodeImage,
            tf.array(
                -1,
                imageShape.asArray()[0],
                imageShape.asArray()[1],
                imageShape.asArray()[2])
            )
        val tensor = runner.fetch(reshape).run()[0]
        val inputMap = mutableMapOf("input_tensor" to tensor)
        println(tensor.shape())
        println(tensor.dataType())
        println(tensor.asRawTensor())
        val result = tfService.model().function("serving_default").call(inputMap)

更新:

我更改了整个代码,并使用了 Kotlin Tensorflow 依赖项

implementation("org.jetbrains.kotlinx:kotlin-deeplearning-api:0.5.2")
implementation("org.jetbrains.kotlinx:kotlin-deeplearning-tensorflow:0.5.2")

我加载了模型:

fun myModel(): SavedModel {
        return SavedModel.load("/home/***/src/main/resources/pd/")
    }

并呼吁进行预测:

val file = File("/home/***/src/main/resources/keyframe_1294.jpg")
val byteArray = ImageIO.read(file)
val floatArray = ImageConverter.toRawFloatArray(byteArray)
val myResult = tfService.myModel().predictSoftly(floatArray, "dense_3")
println(myResult)

但是我收到这个错误:

原因:org.tensorflow.TensorFlowException:操作类型未在我的计算机上运行的二进制文件中注册“DisableCopyOnRead”。确保在此过程中运行的二进制文件中注册了 Op 和 Kernel。请注意,如果您要加载一个使用 tf.contrib 运算的已保存图,则应在导入图之前进行访问(例如),因为 contrib 运算在首次访问模块时会延迟注册。tf.contrib.resampler

spring-boot kotlin tensorflow2.0 张量 dtype

评论


答:

0赞 Saher Al-Sous 10/19/2023 #1

我不停地环顾四周,发现有一种方法可以将内容转换为 Float32,并处理图像以适应所需的数据形状和类型。 这是下面的解决方案

val graph = Graph()
val session = Session(graph)
val tf = Ops.create(graph)
val fileName = tf.constant("/home/saher/kotlin/Spring/machinelearning/src/main/resources/20220821_203556.jpg")
val readFile = tf.io.readFile(fileName)
val runner = session.Runner()
val decodingOptions = DecodeJpeg.channels(3)
val decodeImage = tf.image.decodeJpeg(readFile.contents(), decodingOptions)
//Cast the data type in the image.
val castedImage = tf.dtypes.cast(decodeImage, TFloat32::class.java)
// Add an extra dimension to make it 4-dimensional
val expandedImage = tf.expandDims(castedImage, tf.constant(0))
// Resize the image
val reshapedImage =
            tf.image.resizeBilinear(expandedImage, tf.constant(intArrayOf(299, 299)))
val tensor = runner.fetch(reshapedImage).run()[0]
val inputMap = mutableMapOf("input_1" to tensor)
val result = tfService.model().function("serving_default").call(inputMap)

祝您编码愉快。