The java code :
public class Neuron implements Comparable<Neuron>, Serializable {
public interface Activation extends Function<Float, Float>, Serializable {
Activation SIGMOID = z -> 1 / (1 (float) Math.exp(-z));
Activation LINEAR = z -> z;
Activation TANH = x -> (float) Math.tanh(x);
}
...
somehow, i managed to translate it to this kotlin code (with the help of various answer i found on stackoverflow) :
class Neuron(
val id: Int,
val inputs: Array<Neuron?>,
val weights: FloatArray,
var type: Type?,
private var activation: (Float) -> Float,
val label: String?
) : Comparable<Neuron>, Serializable {
interface Activation : Function<Float?, Float?>, Serializable {
companion object {
val SIGMOID = fun(z: Float): Float { return 1 / (1 exp(-z)) }
val LINEAR = fun(z: Float): Float { return z }
val TANH = fun(x: Float): Float { return tanh(x) }
}
}
I'm probably doing it wrong and i still have some error when i try to use it. The very good news is that, while my code is still a mix of java and kotlin, this code is only called by kotlin code. So there could be a way to solve it all in a proper way.
I fixed a lot of stuff here and there to fix argument type in various method/function but i'm stuck with this one :
fun tick() {
nextState = 0.0f
for (i in inputs.indices) nextState = inputs[i]!!.state * weights[i]
nextState = activation!!.apply(nextState)!!
}
the errors, on the same line :
Type mismatch: inferred type is (Float) -> Float but Float? was expected
Type mismatch: inferred type is Float but TypeVariable(T).() -> Unit was expected
The first error is probably related to the type of "nextState" (which is indeed a Float), but apply is supposed to return a Float so i assume that solving the 2nd error will fix the 1st one. I don't understand the 2nd error.
Considering that SIGMOID, LINEAR, TANH, are (as far as i know) only called from Kotlin code, is there a way to fix it all in a graceful way ?
A temporary fix i just found :
nextState = activation.invoke(nextState)
is this the proper way to solve it all ? is there perhaps a nicer solution without interface and companion ? should i leave it as is and call it a day ?
CodePudding user response:
If you are working in android studio then a good way is to just copy the java code into a Kotlin file. You will be prompted to turn the code into kotlin. This worked for me when I had to copy code from online. I hope this works for you.
CodePudding user response:
You can drop this Activation interface in Kotlin because you never use it.
Instead you said in code you want your var activation to be of type (Float) -> Float. So you can do it like this
val SIGMOID: (Float) -> (Float) = { 1 / (1 exp(-it)) }
...
Oh, and then you can use activation(...) syntax.
CodePudding user response:
Probably change to
interface Activation : (Float?) -> Float?, Serializable {
}
Then the instances
companion object {
val SIGMOID = (Float) -> Float = { return 1 / (1 exp(-z)) }
val LINEAR = (Float) -> Float = { return z }
val TANH = (Float) -> Float = { return tanh(x) }
}
and usage to
activation(nextState)
which is equvalent to .invoke(nextState)
CodePudding user response:
I am answering my own question since the full, clean, solution is a mixture of multiple answers and comments.
I replaced nextState = activation!!.apply(nextState)!!
with nextState = activation(nextState)
using nextState = activation.invoke(nextState)
also worked but wasn't necessary.
I replaced
interface Activation : Function<Float?, Float?>, Serializable {
companion object {
val SIGMOID = fun(z: Float): Float { return 1 / (1 exp(-z)) }
val LINEAR = fun(z: Float): Float { return z }
val TANH = fun(x: Float): Float { return tanh(x) }
}
}
with
interface Activation : (Float) -> Float, Serializable {
companion object {
val SIGMOID: (Float) -> (Float) = { 1 / (1 exp(-it)) }
val LINEAR : (Float) -> (Float) = { it }
val TANH : (Float) -> (Float) = { tanh(it) }
}
}
And got rid of the java import.
Then i realized that i didn't need this interface since it was only called from Kotlin code.
I changed all reference to the Activation
type to (Float) -> Float
and removed the interface. I already had a companion object declared in this class so i moved it all in this companion object.
companion object {
private const val serialVersionUID = 1L // this one was already there
val SIGMOID: (Float) -> (Float) = { 1 / (1 exp(-it)) }
val LINEAR : (Float) -> (Float) = { it }
val TANH : (Float) -> (Float) = { tanh(it) }
}
I changed all my reference to theses function from Neuron.Activation.LINEAR
to Neuron.LINEAR
eg :
var defaultActivation = Neuron.Activation.LINEAR // with interface
var defaultActivation = Neuron.LINEAR // without interface
Thank you everyone. I hope this will help, it seems to be a common problem because intellij failed to convert automatically this kind code from java to kotlin using the builtin functionality.