元素操作比矢量操作更直观,因为一个矩阵的元素清楚地映射到另一个矩阵上,为了获得结果,你只需要执行一个算术操作。(示例代码位于此处。)
对于向量矩阵运算,你必须首先建立直觉,并执行多个步骤。矩阵乘法有两种基本类型:内(点)积和外积。内积产生一个减少维度的矩阵,外部积产生一个维度扩大的矩阵。助记法:向外扩张,向内收缩。
内积
与哈达马积,哈达马积要求两个矩阵具有相等的行和列,内积只要求第一个矩阵的列数等于第二个矩阵的行数。例如,这是可行的
[3.0]
[1.0 ,2.0] * [4.0] = (1.0 * 3.0) + (2.0 * 4.0) = 11
请注意,1 x 2行乘以2 x 1列生成标量。此操作将维度减小到1,1。你可以想象将行向量[1.0,2.0]顺时针旋转以站在其末端,与列向量相对。然后两个顶部的元素相乘,底部的两个也是相乘的,两个乘积被添加到一个标量中进行合并。
在ND4J中,你可以创建如下两个向量:
INDArray nd = Nd4j.create(new float[]{1,2},new int[]{2}); //行向量
INDArray nd2 = Nd4j.create(new float[]{3,4},new int[]{2, 1}); //列向量
并像这样把它们相乘
nd.mmul(nd2);
注意,nd4j代码反映了nd*nd2是行向量乘以列向量的公式。该方法是mmul,而不是我们用于元素操作的mul,额外的“m”代表“matrix”。
现在,让我们进行相同的操作,同时向新数组添加一个额外的列,我们叫它为nd4。
INDArray nd4 = Nd4j.create(new float[]{3,4,5,6},new int[]{2, 2});
nd.mmul(nd4);
[3.0 ,5.0]
[1.0 ,2.0] * [4.0 ,6.0] = [(1.0 * 3.0) + (2.0 * 4.0), (1.0 * 5.0) + (2.0 * 6.0)] = [11, 17]
现在我们在第一个矩阵中再加一行,称之为nd3,再乘以nd4。
INDArray nd3 = Nd4j.create(new float[]{1,3,2,4},new int[]{2,2});
nd3.mmul(nd4);
方程式如下
[1.0 ,2.0] [3.0 ,5.0] [(1.0 * 3.0) + (2.0 * 4.0), (1.0 * 5.0) + (2.0 * 6.0), [11, 17]
[3.0 ,4.0] * [4.0 ,6.0] = (3.0 * 3.0) + (4.0 * 4.0), (3.0 * 5.0) + (4.0 * 6.0),] = [25, 39]
外积
我们第一次处理的两个向量的外积,就像颠倒它们的顺序一样简单。
nd2.mmul(nd);
[3.0] [(3.0 * 1.0), (3.0 * 2.0) [3.0 ,6.0] [3.0] [1.0 ,2.0]
[4.0] * [1.0 ,2.0] = (4.0 * 1.0), (4.0 * 2.0) = [4.0 ,8.0] = [4.0] * [1.0 ,2.0]
结果是,nd2乘以nd,等于它乘以叠加在一起的两个nd。这是一个外积。如你所见,外积也需要较少的操作,因为它们不会在最终矩阵中将两个积组合成一个元素。
这里应该注意到ND4J代码的一些方面。首先,该方法采用两个参数。
nd.mmul(要与之相乘的矩阵, 要分配积的矩阵);
可以这样表达
nd.mmul(nd2, ndv);
与这行相同
ndv = nd.mmul(nd2);
使用第二个参数指定积应分配到的nd数组是nd4j中常见的约定。
要了解如何使用nd4j转置和变形矩阵,请单击此处。