执行SVD时ND4J出现运行时错误



我正在学习ND4J的基础知识,以提高其线性代数功能的速度。

我在Macbook Pro上运行,使用nd4j api和nd4j本机依赖关系版本1.0.0-M2.1、Open JDK版本17、Kotlin 1.7.20和IntelliJ 2022.2.2终极版。

我正在编写JUnit5测试来执行简单的操作:对2x2矩阵和标量进行加法、减法、乘法和除法;矩阵加法、减法、乘法;LU和QR分解。所有人都很成功,通过得很好。

当我为SVD:运行这个JUnit测试时,我遇到了一个问题

@Test
fun `singular value decomposition`() {
// setup
// https://stackoverflow.com/questions/19763698/solving-non-square-linear-system-with-r/19767525#19767525
val a = Nd4j.create(doubleArrayOf(
0.0, 1.0, -2.0, 3.0,
5.0, -3.0, 1.0, -2.0,
5.0, -2.0, -1.0, 1.0
), intArrayOf(3, 4))
val b = Nd4j.create(doubleArrayOf(-17.0, 28.0, 11.0), intArrayOf(3, 1))
val u = Nd4j.create(doubleArrayOf(
-0.1295469, -0.8061540,  0.5773503,
0.7629233,  0.2908861,  0.5773503,
0.6333764, -0.5152679, -0.5773503
), intArrayOf(3, 3))
val v = Nd4j.create(doubleArrayOf(
0.87191556, -0.2515803, -0.1764323,
-0.46022634, -0.1453716, -0.4694190,
0.04853711,  0.5423235,  0.6394484,
-0.15999723, -0.7883272,  0.5827720
), intArrayOf(3, 4))
val d = Nd4j.create(doubleArrayOf(
8.007081e+00, 4.459446e+00, 4.022656e-16
), intArrayOf(3))
// exercise
val actual = NDLinalg().svd(a, true, true)
// assert
// Temporary assertion; I'll replace this after I see what SVD returns to me.
Assertions.assertTrue(true)
}

我很惊讶地看到这个错误:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
org.nd4j.linalg.exception.ND4JIllegalStateException: Op name svd - no output arrays were provided and calculateOutputShape failed to execute
at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.exec(NativeOpExecutioner.java:1513)
at org.nd4j.linalg.factory.Nd4j.exec(Nd4j.java:6545)
at org.nd4j.linalg.factory.ops.NDLinalg.svd(NDLinalg.java:309)
at ie.duffymo.fea.MatrixTest.singular value decomposition(MatrixTest.kt:353)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

More in the stack trace.    
Process finished with exit code 255

我不知道如何解决我没有提供输出数组的警告。我已经提供了方法签名所需的内容。

关于如何解决这个问题有什么建议吗?

我所指的示例解决方案是使用R为另一个SO问题创建的。

这是一个初始化错误。您可以在此处找到修复方法:https://github.com/deeplearning4j/deeplearning4j/pull/9823

我们的函数基本上有两个阶段:计算输出结果的输出形状和操作的实际执行。

它在第一部分就陷入了预期中的争论。在这种情况下,需要一个int参数,但由于构造函数的初始化方式,并不是所有的参数都在下面传递。

在未来你可以做:

Nd4j.getExecutioner().enableDebugMode(true);
Nd4j.getExecutioner().enableVerboseMode(true);
var a = Nd4j.create(new double[]{
0.0, 1.0, -2.0, 3.0,
5.0, -3.0, 1.0, -2.0,
5.0, -2.0, -1.0, 1.0
}, new int[]{3, 4});
var b = Nd4j.create(new double[]{-17.0, 28.0, 11.0}, new int[]{3, 1});
var u = Nd4j.create(new double[]{
-0.1295469, -0.8061540, 0.5773503,
0.7629233, 0.2908861, 0.5773503,
0.6333764, -0.5152679, -0.5773503
}, new int[]{3, 3});
var v = Nd4j.create(new double[]{
0.87191556, -0.2515803, -0.1764323,
-0.46022634, -0.1453716, -0.4694190,
0.04853711, 0.5423235, 0.6394484,
-0.15999723, -0.7883272, 0.5827720
}, new int[]{3, 4});
var d = Nd4j.create(new double[]{
8.007081e+00, 4.459446e+00, 4.022656e-16
}, new int[]{3});
// exercise
var actual = DynamicCustomOp.builder("svd")
.addInputs(a)
.addIntegerArguments(1,1, Svd.DEFAULT_SWITCHNUM)
.build();
Nd4j.linalg().svd(a,true,true);

请注意,我只是在那里使用了Nd4j.linalg((。

解决方法:

var actual = DynamicCustomOp.builder("svd")
.addInputs(a)
.addIntegerArguments(1,1, Svd.DEFAULT_SWITCHNUM)
.build();
Nd4j.getExecutioner().exec(actual);

相关内容

最新更新