欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java深度學習庫DJL實現(xiàn)Python的NumPy方式

 更新時間:2025年02月14日 11:17:52   作者:趙廣陸  
本文介紹了DJL庫的背景和基本功能,包括NDArray的創(chuàng)建、數(shù)學運算、數(shù)據(jù)獲取和設置等,同時,還展示了如何使用NDArray進行數(shù)據(jù)預處理和模型推理部署

1 NDArray 的背景介紹

在Python的世界,調用NDArray的標準包叫做NumPy。為了給Java開發(fā)者創(chuàng)造同一種工具,亞馬遜云服務開源了DJL,一個基于Java的深度學習庫。盡管它包含了深度學習模塊,但是它最核心的NDArray庫可以被用作NumPy的java替代工具庫。

官網(wǎng):https://djl.ai/

同時它具備優(yōu)良的可擴展性,全平臺支持,以及強大的后端引擎支持 TensorFlowPaddlePaddle, PyTorch, Apache MXNet等)。無論是CPU還是GPU, PC還是安卓,DJL都可以輕而易舉的完成任務。

1.1 架構

在這個系列文章中,我們將帶你了解NDArray,并且教你如何寫與Numpy同樣簡單的Java代碼以及如何將NDArray使用在現(xiàn)實中的應用之中。

NDArray相當于python numpy的java實現(xiàn),解決復雜的矩陣運算問題。多維數(shù)組存在于native C++ 內存里,如此可以方便調用下面的加速庫:

  • 矩陣加速庫:LAPACK, BLAS
  • CPU加速庫:oneDNN(MKLDNN)
  • GPU加速庫:CUDA, cuDNN

NDArray提供了豐富的api,如:

  • 四則運算: add, sub, mul, div, …
  • 矩陣運算:matMul
  • 比較運算:eq, gt, ….
  • 歸約運算:sum, max, min, …
  • 其它運算:abs, exp,…
  • 改變形狀:reshape, swapAxes, …

為了更好的管理NDArray,管理數(shù)據(jù)的創(chuàng)建及生命周期, 創(chuàng)建所有NDArray都需要通過NDManager。如此可以高效的利用內存,防止內存泄露等問題。

NDManager是DJL中的一個class可以幫助管理NDArray的內存使用。通過創(chuàng)建NDManager,可以及時的對內存進行清理。當這個block里的任務運行完成時,內部產(chǎn)生的NDArray都會被清理掉。這個設計保證了我們在大規(guī)模使用NDArray的過程中,可以更高效的利用內存。

try (NDManager manager = NDManager.newBaseManager()) {
  ...
}

熟練掌握了NDArray的使用后,除了可以完成復雜的矩陣處理,計算外,如何用于模型的推理部署呢?

模型的推理可以概括為三個步驟:

  • 數(shù)據(jù)預處理
  • 推理
  • 數(shù)據(jù)后處理

在預處理過程中,我們需要完成把圖片轉成RGB數(shù)組,把文字轉換成索引id,把音頻轉換成float數(shù)組,數(shù)據(jù)歸一化等操作。

在后處理過程中,我們需要完成把概率轉換為對應的標簽,把文字索引轉換回文字等操作。

在數(shù)據(jù)預處理/數(shù)據(jù)后處理過程中,NDArray起了最關鍵的作用。

DJL為了統(tǒng)一代碼處理邏輯,增加代碼的復用性,提供了高級接口Translator:

public NDList processInput(TranslatorContext ctx, I)
public O processOutput(TranslatorContext ctx, NDList list)
12

對NDArray有了基本的了解后,通過學習后續(xù)的教程,可以進一步掌握NDArray的使用。

2 JavaDJL使用

隨著數(shù)據(jù)科學在生產(chǎn)中的應用逐步增加,使用N維數(shù)組靈活的表達數(shù)據(jù)變得愈發(fā)重要。我們可以將過去數(shù)據(jù)科學運算中的多維循環(huán)嵌套運算簡化為簡單幾行。由于進一步釋放了計算并行能力,這幾行簡單的代碼運算速度也會比傳統(tǒng)多維循環(huán)快很多。這種數(shù)學計算的包已經(jīng)成為于數(shù)據(jù)科學,圖形學以及機器學習領域的標準。同時它的影響力還在不斷的擴大到其他領域。

在Python的世界,調用NDArray的標準包叫做NumPy。但是如今在Java領域中,并沒有與之同樣標準的庫。為了給Java開發(fā)者創(chuàng)造同一種使用環(huán)境,亞馬遜云服務開源了DJL,一個基于Java的深度學習庫。盡管它包含了深度學習模塊,但是它最核心的NDArray系統(tǒng)可以被用作N維數(shù)組的標準。它具備優(yōu)良的可擴展性,全平臺支持,以及強大的后端引擎支持(TensorFlow、PyTorch、Apache MXNet)。無論是CPU還是GPU,PC還是安卓,DJL都可以輕而易舉的完成任務。

2.1 安裝DJL

可以通過下方的配置來配置gradle項目,或者也可以跳過設置直接使用我們的

plugins {
id 'java'
}
repositories {
jcenter()
}
dependencies {
implementation "ai.djl:api:0.6.0"
// PyTorch
runtimeOnly "ai.djl.pytorch:pytorch-engine:0.6.0"
runtimeOnly "ai.djl.pytorch:pytorch-native-auto:1.5.0"
}

然后,我們就可以開始上手寫代碼了。

2.2 基本操作

首先嘗試建立一個Try block來包含我們的代碼(如果使用在線JShell可跳過此步):

try(NDManager manager = NDManager.newBaseManager()) {
}

NDManager是DJL中的一個Class,可以幫助管理NDArray的內存使用。通過創(chuàng)建NDManager,我們可以更及時地對內存進行清理。當這個Block里的任務運行完成時,內部產(chǎn)生的NDArray都會被清理掉。這個設計保證了我們在大規(guī)模使用NDArray的過程中,可以通過清理其中的NDManager來更高效地利用內存。為了做對比,我們可以參考NumPy在Python之中的應用。

import numpy as np

2.3 創(chuàng)建NDArray

Ones是一個創(chuàng)建全是1的N維數(shù)組操作。

Python (Numpy)

nd = np.ones((2, 3))
[[1. 1. 1.]
[1. 1. 1.]]

Java (DJL NDArray)

NDArray nd = manager.ones(new Shape(2, 3));
/*
ND: (2, 3) cpu() float32
[[1., 1., 1.],
[1., 1., 1.],
]
*/

我們也可以嘗試生成隨機數(shù)。比如需要生成一些從0到1的隨機數(shù):

Python (Numpy)

nd = np.random.uniform(0, 1, (1, 1, 4))
# [[[0.7034806 0.85115891 0.63903668 0.39386125]]]

Java (DJL NDArray)

NDArray nd = manager.randomUniform(0, 1, new Shape(1, 1, 4));
/*
ND: (1, 1, 4) cpu() float32
[[[0.932 , 0.7686, 0.2031, 0.7468],
],
]
*/

這只是簡單演示一些常用功能?,F(xiàn)在NDManager支持多達20種在NumPy中創(chuàng)建NDArray的方法。

2.4 數(shù)學運算

我們可以使用NDArray進行一系列數(shù)學操作。假設想對數(shù)據(jù)做一個轉置操作,然后對所有數(shù)據(jù)加一個數(shù)的操作。可以參考如下的實現(xiàn):

Python (Numpy)

nd = np.arange(1, 10).reshape(3, 3)
nd = nd.transpose()
nd = nd + 10
[[11 14 17]
[12 15 18]
[13 16 19]]

Java (DJL NDArray)

NDArray nd = manager.arange(1, 10).reshape(3, 3);
nd = nd.transpose();
nd = nd.add(10);
/*
ND: (3, 3) cpu() int32
[[11, 14, 17],
[12, 15, 18],
[13, 16, 19],
]
*/

DJL現(xiàn)在支持60多種不同的NumPy數(shù)學運算,基本涵蓋了大部分的應用場景。

2.5 Get和Set

其中一個對于NDArray最重要的亮點就是它輕松簡單的數(shù)據(jù)設置/獲取功能。我們參考了NumPy的設計,將Java過去對于數(shù)據(jù)表達中的困難做了精簡化處理。假設想篩選一個N維數(shù)組所有小于10的數(shù):

Python (Numpy)

nd = np.arange(5, 14)
nd = nd[nd >= 10]
# [10 11 12 13]

Java (DJL NDArray)

NDArray nd = manager.arange(5, 14);
nd = nd.get(nd.gte(10));
/*
ND: (4) cpu() int32
[10, 11, 12, 13]
*/

是不是非常簡單?接下來,我們看一個稍微復雜一些的應用場景。假設現(xiàn)在有一個3×3的矩陣,然后我們想把第二列的數(shù)據(jù)都乘以2:

Python (Numpy)

nd = np.arange(1, 10).reshape(3, 3)
nd[:, 1] *= 2
[[ 1 4 3]
[ 4 10 6]
[ 7 16 9]]

Java (DJL NDArray)

NDArray nd = manager.arange(1, 10).reshape(3, 3);
nd.set(new NDIndex(":, 1"), array -> array.mul(2));
/*
ND: (3, 3) cpu() int32
[[ 1, 4, 3],
[ 4, 10, 6],
[ 7, 16, 9],
]
*/

在上面的案例中,我們在Java引入了一個NDIndex的Class。它復刻了大部分在NumPy中對于NDArray支持的get/set操作。只需要簡單的放進去一個字符串表達式,開發(fā)者在Java中可以輕松玩轉各種數(shù)組的操作。

現(xiàn)實中的應用場景

上述的操作對于龐大的數(shù)據(jù)集是十分有幫助的。現(xiàn)在我們來看一下這個應用場景:基于單詞的分類系統(tǒng)訓練。在這個場景中,開發(fā)者想要利用從用戶中獲取的數(shù)據(jù)來進行情感分析預測。NDArray被應用在了對于數(shù)據(jù)進行前后處理的工作中。

2.6 分詞操作

在輸入到NDArray數(shù)據(jù)前,我們需要對于輸入的字符串進行分詞操作并編碼成數(shù)字。

下面代碼中看到的Tokenizer是一個Map<String, Integer>。它是一個單詞到字典位置的映射。

String text = "The rabbit cross the street and kick the fox";
String[] tokens = text.toLowerCase().split(" ");
int[] vector = new int[tokens.length];
/*
String[9] { "the", "rabbit", "cross", "the", "street",
"and", "kick", "the", "fox" }
*/
for (int i = 0; i < tokens.length; i++) {
vector[i] = tokenizer.get(tokens[i]);
}
vector
/*
int[9] { 1, 6, 5, 1, 3, 2, 8, 1, 12 }
*/

2.7 NDArray處理

經(jīng)過編碼操作后,我們創(chuàng)建了NDArray。然后需要轉化數(shù)據(jù)的結構:

NDArray array = manager.create(vector);
array = array.reshape(new Shape(vector.length, 1)); // form a batch
array = array.div(10.0);
/*
ND: (9, 1) cpu() float64
[[0.1],
[0.6],
[0.5],
[0.1],
[0.3],
[0.2],
[0.8],
[0.1],
[1.2],
]
*/

最后,我們將數(shù)據(jù)傳入深度學習模型中。如果使用Java要達到這些需要更多的工作量:如果需要實現(xiàn)類似于Reshape的方法,我們需要創(chuàng)建一個N維數(shù)組:List<List<List<…List…>>>來保證不同維度的可操作性。同時我們需要能夠支持插入新的List來創(chuàng)建最終的數(shù)據(jù)格式。

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

最新評論