【深度学习】ND4J-科学计算库

目录

简介

基础用法

基础信息

数组创建

打印数组

变更维度&堆叠

加减乘除

累加/最大/最小

转换操作

矩陈乘法

索引/迭代

深拷贝/引用传递/视图

引用传递

视图

深拷贝

其它


简介

ND4J主要是JVM的科学计算库,内置了很多计算方法,目的是以最低的RAM需求快速运行。主要特点是:

  • 一个多功能的n维数组对象。

  • 线性代数和信号处理函数。

  • 多平台功能,包括GPU。

    • 所有主要操作系统: win/linux/osx/android.

    • 架构: x86, arm, ppc.

Nd4j的主要特点是具有多功能的n维阵列接口INDArray。为了提高性能,Nd4j使用堆外内存来存储数据。INDArray不同于标准Java数组。

基础用法

基础信息

创建数值为0的N维数组

INDArray xx = Nd4j.zeros(10);
System.out.println(xx);//运行结果
[         0,         0,         0,         0,         0,         0,         0,         0,         0,         0]INDArray x = Nd4j.zeros(3, 4);
System.out.println(x);//运行结果
[[         0,         0,         0,         0], [         0,         0,         0,         0], [         0,         0,         0,         0]]

同理,也支持三维、四维等,可以通过以下方法进行维度信息的查看:

// 数组的轴数(维度)。
int dimensions = x.rank();// 数组的维数。每个维度的大小。
long[] shape = x.shape();// 元素的总数。
long length = x.length();// 数组元素的类型。 
DataType dt = x.dataType();

数组创建

要创建INDArray,可以使用ND4J类的静态工厂方法。

Nd4j.createFromArray函数通过重载,支持double、float、int、long类型,同时对各种类型最高支持四维。

double arr_2d[][]={{1.0,2.0,3.0},{4.0,5.0,6.0},{7.0,8.0,9.0}};
INDArray x_2d = Nd4j.createFromArray(arr_2d);double arr_1d[]={1.0,2.0,3.0};
INDArray  x_1d = Nd4j.createFromArray(arr_1d);

可以使用函数zerosones创建用0和1初始化的数组

可以使用rand函数建用随机值初始化的数组

创建的INDArray的默认数据类型是float,有些重载允许您设置数据类型

INDArray  x = Nd4j.zeros(5);
//运行结果
//[         0,         0,         0,         0,         0], FLOATint [] shape = {5};
x = Nd4j.zeros(DataType.DOUBLE, 5);
//运行结果
//[         0,         0,         0,         0,         0], DOUBLE// 对于更高的维度,可以提供形状数组。二维随机矩阵示例:
int[] shape = {4, 5};
INDArray x = Nd4j.rand(shape);//运行结果
[[    0.5669,    0.0576,    0.8701,    0.9598,    0.6470], [    0.2711,    0.8427,    0.2819,    0.6617,    0.5109], [    0.0602,    0.2674,    0.6586,    0.9939,    0.4781], [    0.4099,    0.9503,    0.2227,    0.4738,    0.3759]]

使用arange函数创建一个均匀空间值数组:

INDArray  x = Nd4j.arange(5);
// [         0,    1.0000,    2.0000,    3.0000,    4.0000]INDArray  x = Nd4j.arange(2, 7);
// [    2.0000,    3.0000,    4.0000,    5.0000,    6.0000]

linspace函数允许您指定生成的点数:

//开始数, 停止数, 个数.
INDArray  x = Nd4j.linspace(1, 10, 5); 
// [    1.0000,    3.2500,    5.5000,    7.7500,   10.0000]// 对函数进行多点评估。
import static org.nd4j.linalg.ops.transforms.Transforms.sin;
INDArray  x = Nd4j.linspace(0.0, Math.PI, 100, DataType.DOUBLE);
INDArray  y = sin(x);

打印数组

如上图的例子,INDArray支持Java的toString()方法,可以直接通过System.out.println打印除结果

变更维度&堆叠

可以通过reshap函数进行维度的变更

int [] shape = {4,3};
//2维数组
x = Nd4j.arange(12).reshape(shape);   
/*
[[         0,    1.0000,    2.0000], [    3.0000,    4.0000,    5.0000], [    6.0000,    7.0000,    8.0000], [    9.0000,   10.0000,   11.0000]]
*/

如果本身数据的数组不足以填满新的维度,则会报ND4JIllegalStateException异常

int [] shape = {4,3};
//2维数组
INDArray x = Nd4j.arange(11).reshape(shape);//运行结果
//org.nd4j.linalg.exception.ND4JIllegalStateException: New shape length doesn't match original length: [12] vs [11]. Original shape: [11] New Shape: [4, 3]

INDArray x = Nd4j.rand(3,4);
x.shape();
// [3, 4]INDArray x2 = x.ravel(); //转化成一列
x2.shape();
// [12]INDArray x3 = x.reshape(6,2).shape();
x3.shape();
//[6, 2]//注意x、x2和x3共享相同的数据。 
x2.putScalar(5, -1.0);System.out.println( x);
/*
[[    0.0270,    0.3799,    0.5576,    0.3086], [    0.2266,   -1.0000,    0.1107,    0.4895], [    0.8431,    0.6011,    0.2996,    0.7500]]
*/System.out.println( x2);
// [    0.0270,    0.3799,    0.5576,    0.3086,    0.2266,   -1.0000,    0.1107,    0.4895,    0.8431,    0.6011,    0.2996,    0.7500]System.out.println( x3);
/*        
[[    0.0270,    0.3799], [    0.5576,    0.3086], [    0.2266,   -1.0000], [    0.1107,    0.4895], [    0.8431,    0.6011], [    0.2996,    0.7500]]
*/

可以使用vstackhstack方法将数组堆叠在一起。

INDArray x = Nd4j.rand(2,2);
INDArray y = Nd4j.rand(2,2);x
/*
[[    0.1462,    0.5037], [    0.1418,    0.8645]]
*/y;
/*
[[    0.2305,    0.4798], [    0.9407,    0.9735]]
*/Nd4j.vstack(x, y);
/*
[[    0.1462,    0.5037], [    0.1418,    0.8645], [    0.2305,    0.4798], [    0.9407,    0.9735]]
*/Nd4j.hstack(x, y);
/*
[[    0.1462,    0.5037,    0.2305,    0.4798], [    0.1418,    0.8645,    0.9407,    0.9735]]
*/

加减乘除

使用INDArray方法对数组执行操作。

加法: arr.add(...), arr.addi(...)减法: arr.sub(...), arr.subi(...)乘法: arr.mul(...), arr.muli(...)除法 : arr.div(...), arr.divi(...)

对数组进行加减乘除操作,有两种类型

【1】in-place :在原有数组基础上变更,如add、sub

【2】复制:创建新的数组,将结果放在新数组中,如addi、subi

//复制
//返回一个新数组,并将标量添加到arr的每个元素。
arr_new = arr.add(scalar);  
//返回一个新数组,它是arr和其他arr元素级别的加法。  
arr_new = arr.add(other_arr); //In-place
arr_new = arr.addi(scalar); 
arr_new = arr.addi(other_arr);

in-place运算符可以方便地将操作链接在一起。尽可能使用(in-place)运算符来提高性能,因为

复制运算符有新的数组创建开销。

注意,执行加减乘除操作时,必须确保基础数据类型相同。

int [] shape = {5};
INDArray  x = Nd4j.zeros(shape, DataType.DOUBLE);
INDArray  x2 = Nd4j.zeros(shape, DataType.INT);
INDArray  x3 = x.add(x2);
// java.lang.IllegalArgumentException: Op.X 和 Op.Y must have the same data type, but got INT vs DOUBLE// 将x2转换为DOUBLE可以解决以下问题:
INDArray x3 = x.add(x2.castTo(DataType.DOUBLE));

累加/最大/最小

INDArray有实现累加/最值操作的方法,如 sum, min, max.

int [] shape = {2,3};
INDArray  x = Nd4j.rand(shape);
x;
x.sum();
x.min();
x.max();
/*
[[    0.8621,    0.9224,    0.8407], [    0.1504,    0.5489,    0.9584]]
4.2830
0.1504
0.9584
*/

提供维度参数以在指定维度上应用操作:

INDArray x = Nd4j.arange(12).reshape(3, 4);
/*
[[         0,    1.0000,    2.0000,    3.0000], [    4.0000,    5.0000,    6.0000,    7.0000], [    8.0000,    9.0000,   10.0000,   11.0000]]
*/        //每列的总和。
x.sum(0); 
//[   12.0000,   15.0000,   18.0000,   21.0000]//每行最小值
x.min(1); 
//[         0,    4.0000,    8.0000]//每行的累计和,
x.cumsum(1); 
/*
[[         0,    1.0000,    3.0000,    6.0000], [    4.0000,    9.0000,   15.0000,   22.0000], [    8.0000,   17.0000,   27.0000,   38.0000]]
*/

转换操作

Nd4j提供熟悉的数学函数,如sin、cos和exp,这些称为转换操作。结果作为INDArray返回。

import static org.nd4j.linalg.ops.transforms.Transforms.exp;
import static org.nd4j.linalg.ops.transforms.Transforms.sqrt;INDArray x = Nd4j.arange(3);
// [         0,    1.0000,    2.0000]
exp(x);
// [    1.0000,    2.7183,    7.3891]
sqrt(x);
// [         0,    1.0000,    1.4142]

矩陈乘法

INDArray也支持矩阵运算,如下:

INDArray x = Nd4j.arange(12).reshape(3, 4);
/*
[[         0,    1.0000,    2.0000,    3.0000], [    4.0000,    5.0000,    6.0000,    7.0000], [    8.0000,    9.0000,   10.0000,   11.0000]]
*/INDArray y = Nd4j.arange(12).reshape(4, 3);
/*
[[         0,    1.0000,    2.0000], [    3.0000,    4.0000,    5.0000], [    6.0000,    7.0000,    8.0000], [    9.0000,   10.0000,   11.0000]]
*/
// 矩阵乘积.
x.mmul(y);  
/*
[[   42.0000,   48.0000,   54.0000], [  114.0000,  136.0000,  158.0000], [  186.0000,  224.0000,  262.0000]]
*///点积
INDArray x = Nd4j.arange(12);
INDArray y = Nd4j.arange(12);
dot(x, y);  
//506.0000

索引/迭代

获取某个位置的数据

INDArray x = Nd4j.arange(12);
// [         0,    1.0000,    2.0000,    3.0000,    4.0000,    5.0000,    6.0000,    7.0000,    8.0000,    9.0000,   10.0000,   11.0000]
//单一元素访问。其他方法: getDouble, getInt, ...
float f = x.getFloat(3);  
// 3.0

转化为Java数组

//转换为Java数组。
float []  fArr = x.toFloatVector();
// [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0]

获取指定区间的数据

INDArray x2 = x.get(NDArrayIndex.interval(2, 6));
// [    2.0000,    3.0000,    4.0000,    5.0000]

在x的副本上:从开始到位置6(不包括),将每2个元素设置为-1.0 

//在x的副本上:从开始到位置6(不包括),将每2个元素设置为-1.0
INDArray y = x.dup();
y.get(NDArrayIndex.interval(0, 2, 6)).assign(-1.0);
//[   -1.0000,    1.0000,   -1.0000,    3.0000,   -1.0000,    5.0000,    6.0000,    7.0000,    8.0000,    9.0000,   10.0000,   11.0000]

y的反向副本

//y的反向副本。
INDArray y2 = Nd4j.reverse(y.dup());
//[   11.0000,   10.0000,    9.0000,    8.0000,    7.0000,    6.0000,    5.0000,   -1.0000,    3.0000,   -1.0000,    1.0000,   -1.0000]

对于多维数组,应该使用INDArray.get(NDArrayIndex...)。下面的示例演示如何遍历二维数组的行和列。注意,对于2D数组,我们可以使用getColumngetRow便利方法。

// 在2d数组的行和列上迭代。
int rows = 4;
int cols = 5;
int[] shape = {rows, cols};INDArray x = Nd4j.rand(shape);
/*
[[    0.2228,    0.2871,    0.3880,    0.7167,    0.9951], [    0.7181,    0.8106,    0.9062,    0.9291,    0.5115], [    0.5483,    0.7515,    0.3623,    0.7797,    0.5887], [    0.6822,    0.7785,    0.4456,    0.4231,    0.9157]]
*/for (int row=0; row<rows; row++) {INDArray y = x.get(NDArrayIndex.point(row), NDArrayIndex.all());}
/*
[    0.2228,    0.2871,    0.3880,    0.7167,    0.9951]
[    0.7181,    0.8106,    0.9062,    0.9291,    0.5115]
[    0.5483,    0.7515,    0.3623,    0.7797,    0.5887]
[    0.6822,    0.7785,    0.4456,    0.4231,    0.9157]
*/for (int col=0; col<cols; col++) {INDArray y = x.get(NDArrayIndex.all(), NDArrayIndex.point(col));}
/*
[    0.2228,    0.7181,    0.5483,    0.6822]
[    0.2871,    0.8106,    0.7515,    0.7785]
[    0.3880,    0.9062,    0.3623,    0.4456]
[    0.7167,    0.9291,    0.7797,    0.4231]
[    0.9951,    0.5115,    0.5887,    0.9157]
*/

深拷贝/引用传递/视图

引用传递

以下用法,仅仅只是指向x的指针,进行了引用传递,并未复制

INDArray x = Nd4j.rand(2,2);
//y和x指向同一个INDArray对象。
INDArray y = x; 

视图

一些函数将返回数组的视图,并未进行数组的复制

INDArray x = Nd4j.rand(3,4);
INDArray  x2 = x.ravel();
INDArray  x3 = x.reshape(6,2);// 修改 x, x2 和 x3
x2.putScalar(5, -1.0); x
/*
[[    0.8546,    0.1509,    0.0331,    0.1308], [    0.1753,   -1.0000,    0.2277,    0.1998], [    0.2741,    0.8257,    0.6946,    0.6851]]
*/x2
// [    0.8546,    0.1509,    0.0331,    0.1308,    0.1753,   -1.0000,    0.2277,    0.1998,    0.2741,    0.8257,    0.6946,    0.6851]x3
/*
[[    0.8546,    0.1509], [    0.0331,    0.1308], [    0.1753,   -1.0000], [    0.2277,    0.1998], [    0.2741,    0.8257], [    0.6946,    0.6851]]
*/

深拷贝

要复制数组,请使用dup方法。这将为您提供一个包含新数据的新数组。

INDArray x = Nd4j.rand(3,4);
INDArray  x2 = x.ravel().dup();//现在只改变x2。
x2.putScalar(5, -1.0); 
x
/*
[[    0.1604,    0.0322,    0.8910,    0.4604], [    0.7724,    0.1267,    0.1617,    0.7586], [    0.6117,    0.5385,    0.1251,    0.6886]]
*/x2
// [    0.1604,    0.0322,    0.8910,    0.4604,    0.7724,   -1.0000,    0.1617,    0.7586,    0.6117,    0.5385,    0.1251,    0.6886]

其它

ND4J还有很多科学计算函数,具体可以查看文档

nd4j-api 1.0.0-M2.1 javadoc (org.nd4j)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/662182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用tshark从pcap中解析http流量

使用tshark解析 安装tshark apt install tshark # 测试 tshark -r gitlab.pcap -T fields -Y http -e tcp.stream -e http.request.method -e http.request.uri -e http.request.version -e http.request.line -e http.response.version -e …

【AIGC扫盲】人工智能大模型快速入门

人工智能大模型的技术框架主要有以下几种&#xff1a; TensorFlow&#xff1a;这是一个由Google Brain团队开发的开源库&#xff0c;用于进行高性能数值计算&#xff0c;特别是用于训练和运行深度学习模型。TensorFlow提供了一种称为计算图的编程模型&#xff0c;它允许用户定义…

MS Access 函数参考手册

目录 MS Access 字符串函数 MS Access 数值函数 MS Access 日期函数 MS Access 其他函数 MS Access 字符串函数 函数描述Asc返回特定字符的 ASCII 值Chr返回指定ASCII码的字符Concat with &将两个或多个字符串加在一起CurDir返回指定驱动器的完整路径Format用指定的格…

如何在CentOS安装DataEase数据分析服务并实现远程访问管理界面

如何在CentOS安装DataEase数据分析服务并实现远程访问管理界面 前言1. 安装DataEase2. 本地访问测试3. 安装 cpolar内网穿透软件4. 配置DataEase公网访问地址5. 公网远程访问Data Ease6. 固定Data Ease公网地址 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 202…

IDEA中的Run Dashboard

Run Dashboard是IntelliJ IDEA中的工具【也就是View中的Services】&#xff0c;提供一个可视化界面&#xff0c;用于管理控制应用程序的运行和调试过程。 在Run DashBoard中&#xff0c;可以看到所有的运行配置&#xff0c;以及每个配置的运行状态&#xff08;正在运行&#xf…

【vue2源码】阶段一:Vue 初始化

文章目录 一、项目目录1、主目录2、打包入口 二、构造函数Vue的初始化1、创建 Vue 构造函数2、初始化内容分析2.1 initMixin2.2 stateMixin2.3 eventsMixin2.4 lifecycleMixin2.5 renderMixin 一、项目目录 源码版本&#xff1a;2.7.16 1、主目录 src |-- compiler # 包…

Camille-学习笔记-web基础知识

web基础1.系统架构 B/S :Browser/Server 网站 界面层&#xff08;UI&#xff09; 业务逻辑层&#xff08;业务&#xff09; 数据访问层&#xff08;数据库&#xff09; 静态网页&#xff1a;和服务器没有数据交互 动态网页&#xff1a;网页数据可以和服务器进行数据交互 URL…

python执行linux系统命令的三种方式

前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 1. 使用os.system 无法获取命令执行后的返回信息 import osos.system(ls)2. 使用os.popen 能够获取命令执行后的返回信息 impor…

Vue3+Koa2实现图片上传(不再畏惧)

大家好&#xff0c;我是勇宝&#xff0c;一个热爱前端的小学生&#xff0c;年关将至&#xff0c;提前祝大家新年快乐。今天呢&#xff0c;我们就来好好的啃一啃图片上传&#xff0c;从一个前端开发者的角度来探讨一下图片上传前后端到底都做了哪些事情。 文章目录 一、技术摘要…

《Pandas 简易速速上手小册》第7章:Pandas 文本和类别数据处理(2024 最新版)

文章目录 7.1 文本数据的基本操作7.1.1 基础知识7.1.2 重点案例&#xff1a;客户反馈分析7.1.3 拓展案例一&#xff1a;产品评论的关键词提取7.1.4 拓展案例二&#xff1a;日志文件中的日期提取 7.2 使用正则表达式处理文本7.2.1 基础知识7.2.2 重点案例&#xff1a;日志文件错…

VMware创建虚拟机

点击文件&#xff0c;新建虚拟机 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

【LeetCode】每日一题 2024_2_2 石子游戏 VI(排序、贪心)

文章目录 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01;题目&#xff1a;石子游戏 VI题目描述代码与解题思路 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 题目&#xff1a;石子游戏 VI 题目链接&#xff1a;1686. 石子游戏 VI 题目描述…

Hbase-2.4.11_hadoop-3.1.3集群_大数据集群_SSH修改默认端口22为其他端口---记录025_大数据工作笔记0185

其实修改起来非常简单,但是在大数据集群中,使用到了很多的脚步,也需要修改, 这里把,大数据集群,整体如何修改SSH端口,为22022,进行总结一下: 0.hbase-2.4.11的话,hbase集群修改默认SSH端口22,修改成22022,需要修改 需要修改/opt/module/hbase-2.4.11/conf/hbase-env.sh 这里…

自动化测试笔记

TDD 之 ATDD 之 CUCUMBER & BDD CUCUMBER 可将人类自然语言转化为&#xff08;Ruby, python, javascript, C#等&#xff09;测试代码。 可以传递参数&#xff0c;可打标签tag进行分类管理&#xff0c;&#xff0c; login Scenario: … Given ... When ... Then ... 可加…

程序人生 - ICP 备案和域名备案是一回事吗?区别是什么?

ICP备案和域名备案是两个不同的概念&#xff0c;ICP备案是指互联网信息服务提供者备案&#xff0c;也就是对于在中国境内提供互联网信息服务的网站必须进行备案登记。而域名备案是指将域名与网站的实际内容进行备案登记。 ICP备案是针对网站运营者的一种许可证&#xff0c;必须…

【Android测试】Appium是否适合用于模拟多指触控呢?

1 问题说明 对于 mobile app automation, ChatGPT4会推荐Appium作为底层的触控工具库&#xff1b;但是&#xff0c;我们一直感觉pyminitouch其实是更好的选择&#xff1b;那么&#xff0c;Appium是否适合用于模拟多指触控呢&#xff1f; 2 资料查询 2.1 Williamfzc: minitou…

pytorch调用gpu训练的流程以及示例

首先需要确保系统上安装了CUDA支持的NVIDIA GPU和相应的驱动程序。 基本步骤如下 检查CUDA是否可用&#xff1a; 使用 torch.cuda.is_available() 来检查CUDA是否可用。 指定设备&#xff1a; 可以使用 torch.device(“cuda:0”) 来指定要使用的GPU。如果系统有多个GPU&…

shell脚本之免交互

目录 一、Here Document 免交互 1、交互与免交互的概念 2、 Here Document 概述 二、Here Document 应用 1、使用cat命令多行重定向 2、使用tee命令多行重定向 3、使用read命令多行重定向 4、使用wc -l统计行数 5、使用passwd命令用户修改密码 6、Here Document 变量…

fastadmin导入excel并对导入数据处理

情景描述 fastadmin有自带的导入功能&#xff0c;但是不好用&#xff0c;它要求你的表格标题必须跟数据表的备注一致&#xff0c;而且拿到的数据是直接插入数据表&#xff0c;我们无法获取想要的数据并对数据进行处理&#xff1b;而且有时候我们只是想要单纯的读取文件功能&…

丰田再怼「纯电动」,抛出「30%上限论」背后的焦虑和矛盾

让传统车企「丢掉」燃油车的包袱&#xff0c;并不简单。一边是赚钱&#xff0c;一边是烧钱&#xff0c;如何平衡是一个不小的难题。 本周&#xff0c;丰田董事长丰田章男对外表示&#xff0c;其预测未来电动汽车的市场份额将只有30%。而在电动化进程中&#xff0c;丰田章男一直…