在学习nd4j的过程中,还有其他一些基本的矩阵操作要突出显示。(示例代码)
转置
矩阵的转置是它的镜像。矩阵A第1行第2列中的元素将位于矩阵A转置后的第2行第1列中,其数学符号为a到t或a^t。请注意,沿正方形矩阵对角线的元素不会移动-它们位于反射的铰链。在nd4j中,矩阵转置就像这样:
INDArray nd = Nd4j.create(new float[]{1, 2, 3, 4}, new int[]{2, 2});
[1.0 ,3.0]
[2.0 ,4.0]
nd.transpose();
[1.0 ,2.0]
[3.0 ,4.0]
像这样的长矩阵
[1.0 ,3.0 ,5.0 ,7.0 ,9.0 ,11.0]
[2.0 ,4.0 ,6.0 ,8.0 ,10.0 ,12.0]
转置后像这样子:
[1.0 ,2.0]
[3.0 ,4.0]
[5.0 ,6.0]
[7.0 ,8.0]
[9.0 ,10.0]
[11.0 ,12.0]
实际上,转置只是更一般操作的一个重要子集:变形。
变形
是的,矩阵可以变形。你可以更改它们的行数和列数。变形矩阵必须满足一个条件:其行和列的乘积必须等于原始矩阵的行和列的乘积。例如,继续按列排列,可以将3×4矩阵变形为2×6矩阵:
INDArray nd2 = Nd4j.create(new float[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, new int[]{2, 6});
数组nd2如下所示
[1.0 ,3.0 ,5.0 ,7.0 ,9.0 ,11.0]
[2.0 ,4.0 ,6.0 ,8.0 ,10.0 ,12.0]
变形它是很容易的,并且遵循我们赋予它形状的相同约定
nd2.reshape(3,4);
[1.0 ,4.0 ,7.0 ,10.0]
[2.0 ,5.0 ,8.0 ,11.0]
[3.0 ,6.0 ,9.0 ,12.0]
线性视图
这是任意nd数组的直视图。你可以像向量一样,线性地通过nd数组,把它压缩成一条长线。线性视图允许你执行非破坏性操作(由于元素在nd数组中发生了更改,因此变形和其他操作可能具有破坏性)。线性视图只适用于元素操作(而不是矩阵操作),因为视图不保留缓冲区的顺序。
nd2.linearView();
[1.0 ,2.0 ,3.0 ,4.0 ,5.0 ,6.0 ,7.0 ,8.0 ,9.0 ,10.0 ,11.0 ,12.0]
广播
广播是高级的。它通常发生在后台,不需要调用。理解它的最简单方法是使用一个长行向量,如上面的向量。
nd2 = Nd4j.create(new float[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
广播实际上会复制该行向量的多个副本,并将它们组合成一个较大的矩阵。第一个参数是你想要“广播”的拷贝数,也是所涉及的行数。为了避免抛出编译器错误,请使广播的第二个参数等于行向量中的元素数。
//3个副本并有3行
nd2.broadcast(new int[]{3,12});
[1.0 ,4.0 ,7.0 ,10.0 ,1.0 ,4.0 ,7.0 ,10.0 ,1.0 ,4.0 ,7.0 ,10.0]
[2.0 ,5.0 ,8.0 ,11.0 ,2.0 ,5.0 ,8.0 ,11.0 ,2.0 ,5.0 ,8.0 ,11.0]
[3.0 ,6.0 ,9.0 ,12.0 ,3.0 ,6.0 ,9.0 ,12.0 ,3.0 ,6.0 ,9.0 ,12.0]
//6个副本并有6行
nd2.broadcast(new int[]{6,12});
[1.0 ,7.0 ,1.0 ,7.0 ,1.0 ,7.0 ,1.0 ,7.0 ,1.0 ,7.0 ,1.0 ,7.0 ]
[2.0 ,8.0 ,2.0 ,8.0 ,2.0 ,8.0 ,2.0 ,8.0 ,2.0 ,8.0 ,2.0 ,8.0 ]
[3.0 ,9.0 ,3.0 ,9.0 ,3.0 ,9.0 ,3.0 ,9.0 ,3.0 ,9.0 ,3.0 ,9.0 ]
[4.0 ,10.0 ,4.0 ,10.0 ,4.0 ,10.0 ,4.0 ,10.0 ,4.0 ,10.0 ,4.0 ,10.0]
[5.0 ,11.0 ,5.0 ,11.0 ,5.0 ,11.0 ,5.0 ,11.0 ,5.0 ,11.0 ,5.0 ,11.0]
[6.0 ,12.0 ,6.0 ,12.0 ,6.0 ,12.0 ,6.0 ,12.0 ,6.0 ,12.0 ,6.0 ,12.0]