-1

I'm trying to migrate deep learning process in python and now need to convert it into kotlin (android studio) but struglling with this part for few days :(

can someone help me to convert python code to kotlin?

The type of out is Tensor. IMAGE_SIZE is 350 and half is 175.

    out = torch.argmax(out, dim=1, keepdims=True).permute(0, 2, 3, 1)[0].numpy().squeeze().astype(np.int32)
    r_H, r_W = out.shape

    _out_extended = np.zeros((IMAGE_SIZE + r_H, IMAGE_SIZE + r_W), dtype=out.dtype)
    _out_extended[half : half + IMAGE_SIZE, half : half + IMAGE_SIZE] = out * 255
    out = _out_extended.copy()

I also tried to use argmax function from Multik library but the input type is not the same. (not Tensor, but MultiArray).

Any other suggestion for migration from python to kotlin would be welcomed!

3 Answers3

0

Here's a Kotlin code snippet that should be equivalent to the Python code you provided:

val out = tensor.argmax(1, true).permute(0, 2, 3, 1)[0].numpy().squeeze().astype(IntArray::class.java)
val (r_H, r_W) = out.shape
val half = 175

val _out_extended = Array(IMAGE_SIZE + r_H) { IntArray(IMAGE_SIZE + r_W) }
_out_extended.fill(0)

for (i in half until half + IMAGE_SIZE) {
    for (j in half until half + IMAGE_SIZE) {
        _out_extended[i][j] = out[i - half][j - half] * 255
    }
}

val out = _out_extended

Note that you will need to replace the variable tensor with your own implementation of the input tensor. Also, you will need to import the necessary libraries for this code to work.

Deva
  • 3
  • 5
  • Thank you so much for your answer! to use argmax function for tensor, can you tell me which dependency that I should add? I've added implementation `org.pytorch:pytorch_android:1.13.0` , `org.pytorch:pytorch_android_torchvision:1.13.0`, `org.jetbrains.kotlinx:multik-core:0.2.0` and `org.jetbrains.kotlinx:multik-default:0.2.0` but I still can't use argmax function :( – kiyoungNoona Apr 21 '23 at 05:55
  • check the below answer – Deva Apr 24 '23 at 04:45
0

To use argmax function on tensors, you can use the PyTorch library. You can install PyTorch using the following command:

pip install torch

Then, you can use the argmax function in your code as follows:

import torch

# Create a tensor
t = torch.tensor([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]])

# Get the index of the maximum value
index = torch.argmax(t)
print(index)  # Output: tensor(5)

# Get the index of the maximum value along a specific dimension
index = torch.argmax(t, dim=1)
print(index)  # Output: tensor([2, 2])

Note that this is for using PyTorch in Python. If you want to use PyTorch in Android, you can use the PyTorch Android library, but I'm not sure if argmax function is currently available in it.

Deva
  • 3
  • 5
0

I kinda figured it out by myself.
In kotlin, I was not able to use argmax function so had to convert it somehow.

'outputs' are equivalent to the 'out' from my question.

        val outTensors = module.forward(IValue.from(inputTensor)).toDictStringKey()

        // the key "out" of the output tensor contains the semantic masks
        val outputTensor = outTensors["out"]!!.toTensor()
        val outputs = outputTensor .dataAsFloatArray

        val width: Int = imageModel.width
        val height: Int = imageModel.height

        val intVal = IntArray(width * height)

        // output processing
        // go through each element in the output of size [WIDTH, HEIGHT] and
        // set different color(black&white) for different classnum
        for (j in 0 until width) {
            for (k in 0 until height) {
                // maxi: the index of the 2 classnum with the max probability
                var maxi = 0
                var maxj = 0
                var maxk = 0
                var maxnum = -100000.0
                for (i in 0 until classnum) {
                    if (outputs[i * (width * height) + j * width + k] > maxnum) {
                        maxnum = outputs[i * (width * height) + j * width + k].toDouble()
                        maxi = i
                        maxj = j
                        maxk = k
                    }
                }
                // color coding for paper in white
                // black color for background and others
                if (maxi == 1)
                    intVal[maxj * width + maxk] = -0x000f // white
                else
                    intVal[maxj * width + maxk] = 0x1000000 // black
            }
        }

And for the _out_extended part, after I convert the intVal to mat (= originalImage), I used this method in order to extend the output.

val padding = 255 
Core.copyMakeBorder(
            originalImage,
            borderImage,
            padding, padding, padding, padding,
            Core.BORDER_CONSTANT, Scalar(0.0)
        )