From c1e8bd2e8f90076962d3aa9d54a6c082305a2846 Mon Sep 17 00:00:00 2001 From: therealansh Date: Fri, 17 Dec 2021 19:06:32 +0530 Subject: [PATCH 1/2] init: merge layer test and dot layer fix --- .../kotlinx/dl/api/core/layer/merge/Dot.kt | 2 +- .../dl/api/core/layer/MergeLayerTest.kt | 125 ++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 api/src/test/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/MergeLayerTest.kt diff --git a/api/src/main/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/merge/Dot.kt b/api/src/main/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/merge/Dot.kt index 6ecfb6745..153a4bd9d 100644 --- a/api/src/main/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/merge/Dot.kt +++ b/api/src/main/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/merge/Dot.kt @@ -30,7 +30,7 @@ public class Dot( var x2 = input[1] val axes: IntArray = IntArray(2) val scope: Scope = tf.scope() - for (i in 0..2) { + for (i in 0 until 2) { if (axis[i] < 0) { axes[i] = axis[i] % input[i].asOutput().shape().numDimensions() } else { diff --git a/api/src/test/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/MergeLayerTest.kt b/api/src/test/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/MergeLayerTest.kt new file mode 100644 index 000000000..60c6b311c --- /dev/null +++ b/api/src/test/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/MergeLayerTest.kt @@ -0,0 +1,125 @@ +package org.jetbrains.kotlinx.dl.api.core.layer + +import org.jetbrains.kotlinx.dl.api.core.KGraph +import org.jetbrains.kotlinx.dl.api.core.layer.merge.* +import org.jetbrains.kotlinx.dl.api.core.shape.flattenFloats +import org.jetbrains.kotlinx.dl.api.core.shape.shape +import org.jetbrains.kotlinx.dl.api.core.shape.toLongArray +import org.jetbrains.kotlinx.dl.api.extension.convertTensorToFlattenFloatArray +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.tensorflow.* +import org.tensorflow.op.Ops +import java.nio.FloatBuffer + +internal class MergeLayerTest { + + private fun getInputOp(tf:Ops, input:Array<*>): List> = + input.map { tf.constant(input.shape.toLongArray(), FloatBuffer.wrap(input.flattenFloats())) } + + private fun getLayerOutputOp( + tf: Ops, + layer: AbstractMerge, + input: Array<*>, + kGraph: KGraph, + ): Output<*> { + val inputShape = input.shape + layer.build(tf, kGraph, inputShape) + val inputOp = getInputOp(tf, input) + val isTraining = tf.constant(true) + val numberOfLosses = tf.constant(1.0f) + val output = layer.forward(tf, inputOp, isTraining, numberOfLosses).asOutput() + return output + } + + private fun runLayerInEagerMode( + layer: AbstractMerge, + input: Array<*>, + ): Tensor<*> { + EagerSession.create().use { + val tf = Ops.create() + val kGraph = KGraph(Graph().toGraphDef()) + val outputOp = getLayerOutputOp(tf, layer, input, kGraph) + return outputOp.tensor() + } + } + + protected fun assertLayerOutputIsCorrect( + layer:AbstractMerge, + input: Array<*>, + expectedOutput: Array<*>, + ) { + val output = runLayerInEagerMode(layer,input) + output.use { + val outputShape = output.shape() + val expectedShape = expectedOutput.shape.toLongArray() + Assertions.assertArrayEquals(expectedShape, outputShape) + val result = it.convertTensorToFlattenFloatArray() + result.forEach { i -> println(i) } + val expected = expectedOutput.flattenFloats() + Assertions.assertArrayEquals(expected, result) + } + } + + @Test + fun add() { + val x1 = FloatArray(10) { it.toFloat() } + val x2 = FloatArray(10) { it.toFloat() } + val input = arrayOf(x1, x2) + val expected = Array(2) { FloatArray(10) { 2*it.toFloat() } } + assertLayerOutputIsCorrect(Add(), input, expected) + } + + @Test + fun subtract() { + val x1 = FloatArray(10) { it.toFloat() } + val x2 = FloatArray(10) { it.toFloat() } + val input = arrayOf(x1, x2) + val expected = Array(2) { FloatArray(10) { 0f } } + assertLayerOutputIsCorrect(Subtract(), input, expected) + } + + @Test + fun average() { + val x1 = Array(2) { FloatArray(2) { 0f } } + val x2 = Array(2){ FloatArray(2) { 1f } } + val input = arrayOf(x1,x2) + val expected = Array(2){ Array(2) { FloatArray(2) { 0.5f } } } + assertLayerOutputIsCorrect(Average(), input, expected) + } + + @Test + fun concat(){} + + @Test + fun maximum(){} + + @Test + fun minimum(){ + val x1 = Array(5) { FloatArray(1) { it.toFloat() } } + val x2 = Array(5){ FloatArray(1) { it.toFloat()+5 } } + val input = arrayOf(x1, x2) + val expected = Array(2){ Array(5) { FloatArray(1) { it.toFloat() } } } + assertLayerOutputIsCorrect(Minimum(), input, expected) + } + + @Test + fun multiply(){} + + @Test + fun dot(){ + val x = arrayOf( + arrayOf( + floatArrayOf(0f, 1f), + floatArrayOf(2f, 3f), + floatArrayOf(4f, 5f), + floatArrayOf(6f, 7f), + floatArrayOf(8f, 9f) + ) + ) + val y = arrayOf(arrayOf(floatArrayOf(10f, 11f, 12f, 14f, 15f), floatArrayOf(15f, 16f, 17f, 18f, 19f))) + val input = arrayOf(x, y) + val expected = arrayOf(arrayOf(floatArrayOf(260f, 360f), floatArrayOf(320f, 445f))) + assertLayerOutputIsCorrect(Dot(axis = intArrayOf(1, 2)), input, expected) + } +} From 1addb307c0fd6c06d47ad791065d635943cce347 Mon Sep 17 00:00:00 2001 From: therealansh Date: Thu, 23 Dec 2021 21:10:21 +0530 Subject: [PATCH 2/2] add: few merge layer test cases --- .../dl/api/core/layer/MergeLayerTest.kt | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/api/src/test/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/MergeLayerTest.kt b/api/src/test/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/MergeLayerTest.kt index 60c6b311c..3c853e4fb 100644 --- a/api/src/test/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/MergeLayerTest.kt +++ b/api/src/test/kotlin/org/jetbrains/kotlinx/dl/api/core/layer/MergeLayerTest.kt @@ -14,18 +14,19 @@ import java.nio.FloatBuffer internal class MergeLayerTest { - private fun getInputOp(tf:Ops, input:Array<*>): List> = - input.map { tf.constant(input.shape.toLongArray(), FloatBuffer.wrap(input.flattenFloats())) } + private fun getInputOp(tf:Ops, input:Array<*>): Operand = + tf.constant(input.shape.toLongArray(), FloatBuffer.wrap(input.flattenFloats())) private fun getLayerOutputOp( tf: Ops, layer: AbstractMerge, - input: Array<*>, + input: List>, kGraph: KGraph, ): Output<*> { - val inputShape = input.shape + val inputShape = input.first().shape layer.build(tf, kGraph, inputShape) - val inputOp = getInputOp(tf, input) + val inputOp = mutableListOf>() + input.forEach { inputOp.add(getInputOp(tf,it)) } val isTraining = tf.constant(true) val numberOfLosses = tf.constant(1.0f) val output = layer.forward(tf, inputOp, isTraining, numberOfLosses).asOutput() @@ -34,7 +35,7 @@ internal class MergeLayerTest { private fun runLayerInEagerMode( layer: AbstractMerge, - input: Array<*>, + input: List>, ): Tensor<*> { EagerSession.create().use { val tf = Ops.create() @@ -46,7 +47,7 @@ internal class MergeLayerTest { protected fun assertLayerOutputIsCorrect( layer:AbstractMerge, - input: Array<*>, + input: List>, expectedOutput: Array<*>, ) { val output = runLayerInEagerMode(layer,input) @@ -63,19 +64,19 @@ internal class MergeLayerTest { @Test fun add() { - val x1 = FloatArray(10) { it.toFloat() } - val x2 = FloatArray(10) { it.toFloat() } - val input = arrayOf(x1, x2) - val expected = Array(2) { FloatArray(10) { 2*it.toFloat() } } + val x1 = Array(1){ FloatArray(10) { it.toFloat() } } + val x2 = Array(1){ FloatArray(10) { it.toFloat() } } + val input = listOf(x1, x2) + val expected = Array(1) { FloatArray(10) { 2 * it.toFloat() } } assertLayerOutputIsCorrect(Add(), input, expected) } @Test fun subtract() { - val x1 = FloatArray(10) { it.toFloat() } - val x2 = FloatArray(10) { it.toFloat() } - val input = arrayOf(x1, x2) - val expected = Array(2) { FloatArray(10) { 0f } } + val x1 = Array(1){ FloatArray(10) { it.toFloat() } } + val x2 = Array(1){ FloatArray(10) { it.toFloat() } } + val input = listOf(x1, x2) + val expected = Array(1) { FloatArray(10) { 0f } } assertLayerOutputIsCorrect(Subtract(), input, expected) } @@ -83,8 +84,8 @@ internal class MergeLayerTest { fun average() { val x1 = Array(2) { FloatArray(2) { 0f } } val x2 = Array(2){ FloatArray(2) { 1f } } - val input = arrayOf(x1,x2) - val expected = Array(2){ Array(2) { FloatArray(2) { 0.5f } } } + val input = listOf(x1, x2) + val expected = Array(2) { FloatArray(2) { 0.5f } } assertLayerOutputIsCorrect(Average(), input, expected) } @@ -92,19 +93,31 @@ internal class MergeLayerTest { fun concat(){} @Test - fun maximum(){} + fun maximum(){ + val x1 = Array(5) { FloatArray(1) { it.toFloat() } } + val x2 = Array(5){ FloatArray(1) { it.toFloat()+5 } } + val input = listOf(x1, x2) + val expected = Array(5) { FloatArray(1) { it.toFloat()+5 } } + assertLayerOutputIsCorrect(Maximum(), input, expected) + } @Test fun minimum(){ val x1 = Array(5) { FloatArray(1) { it.toFloat() } } val x2 = Array(5){ FloatArray(1) { it.toFloat()+5 } } - val input = arrayOf(x1, x2) - val expected = Array(2){ Array(5) { FloatArray(1) { it.toFloat() } } } + val input = listOf(x1, x2) + val expected = Array(5) { FloatArray(1) { it.toFloat() } } assertLayerOutputIsCorrect(Minimum(), input, expected) } @Test - fun multiply(){} + fun multiply(){ + val x1 = Array(2) { FloatArray(2) { 0f } } + val x2 = Array(2){ FloatArray(2) { 1f } } + val input = listOf(x1, x2) + val expected = Array(2) { FloatArray(2) { 0f } } + assertLayerOutputIsCorrect(Multiply(), input, expected) + } @Test fun dot(){ @@ -118,7 +131,7 @@ internal class MergeLayerTest { ) ) val y = arrayOf(arrayOf(floatArrayOf(10f, 11f, 12f, 14f, 15f), floatArrayOf(15f, 16f, 17f, 18f, 19f))) - val input = arrayOf(x, y) + val input = listOf(x, y) val expected = arrayOf(arrayOf(floatArrayOf(260f, 360f), floatArrayOf(320f, 445f))) assertLayerOutputIsCorrect(Dot(axis = intArrayOf(1, 2)), input, expected) }