写点什么

DL4J 实战之五:矩阵操作基本功,微服务架构技术栈

用户头像
极客good
关注
发布于: 刚刚

<dependencies>


<dependency>


<groupId>org.nd4j</groupId>


<artifactId>${nd4j.backend}</artifactId>


</dependency>


<dependency>


<groupId>ch.qos.logback</groupId>


<artifactId>logback-classic</artifactId>


</dependency>


</dependencies>


</project>


  • 接下来的代码都写在 ndarray-experience 工程中

最基本的方法

  • 先列出两个最基本的方法,后面学习时会频繁用到它们:

  • rand:秩,维数,例如 2 行 3 列的二维矩阵,rand 方法返回值等于 2

  • shape:矩阵每个维度的大小,如 2 行 3 列的二维矩阵,shape 方法返回值等于[2, 3]

  • 准备一个静态方法,可以将 INDArray 实例的详情打印出来,用的就是 rand 和 shape 方法:


private static void disp(String type, INDArray indArray) {


StringBuilder stringBuilder = new StringBuilder("*****************************************************\n");


stringBuilder.append(type)


.append("\n 维度 : ").append(indArray.rank())


.append("\n 形状 : ").append(Arrays.toString(indArray.shape()))


.append("\n 完整矩阵 : \n").append(indArray);


System.out.println(stringBuilder);


}

创建矩阵

  1. 全零矩阵:zeros


// 创建 2 行 3 列的全零矩阵


INDArray indArray0 = Nd4j.zeros(2, 3);


disp("全零矩阵", indArray0);


  • 执行结果


全零矩阵


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 0, 0, 0],


[ 0, 0, 0]]


  1. 全 1 矩阵:ones


// 创建 2 行 3 列的全一矩阵


INDArray indArray1 = Nd4j.ones(2, 3);


disp("全一矩阵", indArray1);


  • 执行结果


全一矩阵


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 1.0000, 1.0000, 1.0000],


[ 1.0000, 1.0000, 1.0000]]


  1. 全是指定值的矩阵:valueArrayOf


// 创建 2 行 3 列的全是指定值的矩阵


INDArray indArray2 = Nd4j.valueArrayOf(new int[] {2, 3}, 888);


disp("全是指定值(888)的矩阵", indArray2);


  • 执行结果


全是指定值(888)的矩阵


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 888.0000, 888.0000, 888.0000],


[ 888.0000, 888.0000, 888.0000]]


  1. rand:随机矩阵(0 到 1 之间的随机数)


// 创建 2 行 3 列的随机矩阵


INDArray indArray2 = Nd4j.rand(2, 3);


disp("随机矩阵", indArray2);


  • 执行结果


随机矩阵


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 0.7236, 0.5159, 0.1908],


[ 0.9458, 0.4413, 0.4173]]


  1. 随机高斯分布的矩阵(平均值为 0,标准差为 1):randn


// 创建 2 行 3 列的随机高斯分布矩阵


INDArray indArray3 = Nd4j.randn(2, 3);


disp("随机高斯分布矩阵", indArray3);


  • 执行结果


随机高斯分布矩阵


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ -0.4287, -0.5790, 0.5004],


[ -0.5122, 1.0551, -0.1998]]


  1. 等差数列:linspace


// 创建等差数列,


// 从 1 到 6、长度为 10 的等差数列


INDArray indArray4 = Nd4j.linspace(1,6, 10);


disp("等差数列", indArray4);


  • 执行结果


等差数列


维度 : 1


形状 : [10]


完整矩阵 :


[ 1.0000, 1.5556, 2.1111, 2.6667, 3.2222, 3.7778, 4.3333, 4.8889, 5.4444, 6.0000]


  1. 根据数组创建矩阵:create(float[] data, int[] shape)


// 根据数组创建 2 行 3 列的矩阵


INDArray indArray6 = Nd4j.create(new float[] {1, 2, 3, 4, 5, 6}, new int[] {2,3});


disp("根据数组创建矩阵", indArray6);


  • 执行结果


根据数组创建矩阵


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 1.0000, 2.0000, 3.0000],


[ 4.0000, 5.0000, 6.0000]]


  1. 三维矩阵


// 三维矩阵


INDArray indArray7 = Nd4j.valueArrayOf(new int[] {2, 2, 3}, 888);


disp("三维矩阵", indArray7);


三维矩阵


维度 : 3


形状 : [2, 2, 3]


完整矩阵 :


[[[ 888.0000, 888.0000, 888.0000],


[ 888.0000, 888.0000, 888.0000]],


[[ 888.0000, 888.0000, 888.0000],


[ 888.0000, 888.0000, 888.0000]]]


  1. 创建正方形二维矩阵,并且对角线上的元素值都是 1.0:


// 创建 3 行 3 列的二维矩阵,对角线值为 1.0


INDArray indArray10 = Nd4j.eye(3);


disp("3*3 矩阵,且对角线都是 1.0", indArray10);


  • 执行结果


3*3 矩阵,且对角线都是 1.0


维度 : 2


形状 : [3, 3]


完整矩阵 :


[[ 1.0000, 0, 0],


[ 0, 1.0000, 0],


[ 0, 0, 1.0000]]

读操作

  • 接下来试试读取相关的操作,回顾前面用数组创建的 2 行 3 列的矩阵,内容如下:


[[ 1.0000, 2.0000, 3.0000],


[ 4.0000, 5.0000, 6.0000]]


  1. 读取指定位置:


System.out.println("读取第一行第一列位置的值 : " + indArray6.getDouble(1,1));


  • 执行结果


读取第一行第一列位置的值 : 5.0


  1. 指定行:


System.out.println("读取第一行 : " + indArray6.getRow(1));


  • 执行结果


读取第一行 : [ 4.0000, 5.0000, 6.0000]


  1. 指定列:


System.out.println("读取第二列 : " + indArray6.getColumn(2));


  • 执行结果


读取第二列 : [ 3.0000, 6.0000]


  1. 指定多列:


System.out.println("读取第二、三列 : " + indArray6.getColumns(1,2));


  • 执行结果


读取第二、三列 : [[ 2.0000, 3.0000],


[ 5.0000, 6.0000]]

写操作

  • 接下来试试读取相关的操作,回顾前面用数组创建的 2 行 3 列的矩阵,内容如下:


[[ 1.0000, 2.0000, 3.0000],


[ 4.0000, 5.0000, 6.0000]]


  1. 修改指定位置,查看了源码后发现,put 方法内容实际上是在调用 putScalar 方法:


indArray6.put(1,1, 123);


indArray6.putScalar(0,0, 456);


disp("a. 修改后", indArray6);


  • 执行结果


a. 修改后


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 456.0000, 2.0000, 3.0000],


[ 4.0000, 123.0000, 6.0000]]


  1. 修改整行:


// 准备一维数组


INDArray row1 = Nd4j.create(new float[] {9,8,7});


// 用一维数组替换矩阵的整行


indArray6.putRow(1, row1);


disp("b. 修改后", indArray6);


  • 执行结果


b. 修改后


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 456.0000, 2.0000, 3.0000],


[ 9.0000, 8.0000, 7.0000]]

矩阵计算

  • 矩阵计算,咱们从最基本的四则运算开始


  1. 加减乘除,入参是一个标量,会与矩阵中的所有元素做计算


// 准备好原始数据,2 行 3 列矩阵


indArray6 = Nd4j.create(new float[] {1, 2, 3, 4, 5, 6}, new int[] {2,3});


// 加法


disp("加法", indArray6.add(1));


// 减法


disp("减法", indArray6.sub(1));


// 乘法


disp("乘法", indArray6.mul(2));


// 除法


disp("除法", indArray6.div(2));


  • 执行结果


加法


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 2.0000, 3.0000, 4.0000],


[ 5.0000, 6.0000, 7.0000]]




【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


减法


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 0, 1.0000, 2.0000],


[ 3.0000, 4.0000, 5.0000]]




乘法


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 2.0000, 4.0000, 6.0000],


[ 8.0000, 10.0000, 12.0000]]




除法


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 0.5000, 1.0000, 1.5000],


[ 2.0000, 2.5000, 3.0000]]


  1. 前面的 add 方法,执行完毕后会生成一个新的 NDArray 实例,不影响原对象,但如果调用的是 addi,就会修改原对象的内容:


INDArray indArray8 = Nd4j.create(new float[] {1, 2, 3, 4, 5, 6}, new int[] {2,3});


disp("替换前", indArray8);


indArray8.addi(1);


disp("替换后", indArray8);


  • 执行结果


替换前


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 1.0000, 2.0000, 3.0000],


[ 4.0000, 5.0000, 6.0000]]




替换后


维度 : 2


形状 : [2, 3]


完整矩阵 :


[[ 2.0000, 3.0000, 4.0000],


[ 5.0000, 6.0000, 7.0000]]


  1. 展开:Nd4j.toFlattened,2 行 3 列的二维矩阵展开后成了一维的


disp("展开", Nd4j.toFlattened(indArray6));


  • 执行结果

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
DL4J实战之五:矩阵操作基本功,微服务架构技术栈