java五子棋代码详解_代码详解:Java和Valohai的深度学习之旅
全文共10735字,預(yù)計學習時長22分鐘或更長
有一款生命周期管理工具(也稱云服務(wù))叫做Valohai,它有著友好的用戶界面和簡潔的布局設(shè)計。
許多有關(guān)Valohai的案例和文檔都是基于Python和R及其相應(yīng)的框架和數(shù)據(jù)庫的,但是基于Java或JVM的卻很少,所以本文打算借此機會一探究竟。
需要什么以及怎么做?
對任何一類機器學習或深度學習項目(想法)來說,代碼和基礎(chǔ)架構(gòu)這兩樣東西(對于高級項目來說)必不可少,有代碼就可以打造模型;有基礎(chǔ)架構(gòu),生命周期就有遵循的軌跡。
當然了,該過程的前中后期也是需要一些步驟和工具的。那么為了一切從簡,我們暫且說需要的是代碼和基礎(chǔ)架構(gòu)。
代碼
針對代碼,筆者選擇了一個使用DL4J改進的例子。該MNist項目的訓練集含6萬張鏡像,測試集含1萬張手寫數(shù)字的鏡像。在DL4J庫中這些數(shù)據(jù)集都是可用的(就像Keras儲存的大量數(shù)據(jù)集)。大家可以通過DL4J Cheatsheet在DatasetIterators上找一下MnistDataSetIterator,了解更多有關(guān)該數(shù)據(jù)集的詳細信息。
在開始之前,先看一下會用到的源代碼,主Java類稱為org.deeplearning4j.feedforward.mnist.MLPMnistSingleLayerRunner。
基礎(chǔ)架構(gòu)
我們已經(jīng)決定把Valohai當作基礎(chǔ)架構(gòu)來試行Java(訓練和評估模型)。Valohai會辯識git repositories,然后直接導入,允許代碼、無關(guān)平臺或無關(guān)語言的操作。(在后面我們會看到這些是如何進行的)同時這也意味著,假如你是GitOps或Infrastructure-As-Code的鐵桿粉絲,你會被Valohai的工作流驚到的。
此時只需注冊一個Valohai賬戶,可以是免費注冊的,登錄后就能瀏覽一些有關(guān)各種構(gòu)形的實例。其實免費賬戶就可以完全滿足我們的需求。
Java和Valohai的深度學習之旅
將必備的部件和運行依賴項捆綁至Docker image中,并用其構(gòu)建Java應(yīng)用程序、訓練模型。Valohai上的評估借助一個簡單的valohai.yaml文件即可,可以在項目儲存庫的根文件夾中找到該文件。
Java深度學習:DL4J
這一塊處理起來很簡單,無需過多操作,建立一個jar文件再將數(shù)據(jù)集下載到Docker container中就行了。之前我們已經(jīng)建立了Docker image,這里面涵括了構(gòu)建應(yīng)用程序需要的所有依賴項。該鏡像已存到Docker Hub(庫)(https://hub.docker.com/)中,搜索dl4j-mnist-single-layer(https://hub.docker.com/r/neomatrix369/dl4j-mnist-single-layer) 可以找到它(到時候會采用YAML文件中的特殊標記命名)。GraalVM 19.1.1(https://github.com/oracle/graal)會在此項目的Java構(gòu)建和運行時發(fā)揮作用,而且它是會嵌入到Docker image中的(參見Docker文件:https://github.com/valohai/mlpmnist-dl4j-example/blob/master/Dockerfile,以查看Docker image的定義)。
編制
命令行出現(xiàn)調(diào)用uber jar時,進入MLPMnistSingleLayerRunner 類,然后根據(jù)傳入的參數(shù)導向預(yù)期操作:
public static void main(String[] args) throws Exception {
MLPMnistSingleLayerRunner mlpMnistRunner = new MLPMnistSingleLayerRunner();
JCommander.newBuilder()
.addObject(mlpMnistRunner)
.build()
.parse(args);
mlpMnistRunner.execute();
}
傳入uber jar的參數(shù)就是由該類接收的,采用的是execute() 法。
我們可以通過傳遞給Java應(yīng)用(uber jar)的--action train參數(shù)創(chuàng)建模型,再用傳遞的--action evaluate參數(shù)評估模型。
上述Java應(yīng)用的核心操作會在下文的兩個Java類中有所體現(xiàn)。
訓練模型
可以通過下述方法從命令行調(diào)用:
./runMLPMnist.sh --action train --output-dir ${VH_OUTPUTS_DIR}
or
java -Djava.library.path=""
-jar target/MLPMnist-1.0.0-bin.jar
--action train --output-dir ${VH_OUTPUTS_DIR}
模型會創(chuàng)建到由--output-dir(執(zhí)行初始傳入的參數(shù))指定的文件夾中,命名為mlpmnist-single-layer.pb。對于Valohai,則是創(chuàng)建到${VH_OUTPUTS_DIR}中,這也正是我們所要做的(可參見valohai.yaml 文件:https://github.com/valohai/mlpmnist-dl4j-example/blob/master/valohai.yaml)。
想要查看源代碼,請看類MLPMNistSingleLayerTrain.java:https://github.com/valohai/mlpmnist-dl4j-example/blob/master/src/main/java/org/deeplearning4j/feedforward/mnist/MLPMnistSingleLayerTrain.java。
評估模型
可以通過下述方法從命令行調(diào)用:
./runMLPMnist.sh --action evaluate --input-dir ${VH_INPUTS_DIR}/model
or
java -Djava.library.path=""
-jar target/MLPMnist-1.0.0-bin.jar
--action evaluate --input-dir ${VH_INPUTS_DIR}/model
此處最好是名為mlpmnist-single-layer.pb 的模型(訓練步驟中創(chuàng)建)可以在--input-dir (應(yīng)用程序調(diào)用時傳入)指定的文件夾中顯示。
想要查看源代碼,請看MLPMNistSingleLayerEvaluate.java:https://github.com/valohai/mlpmnist-dl4j-example/blob/master/src/main/java/org/deeplearning4j/feedforward/mnist/MLPMnistSingleLayerEvaluate.java
筆者希望上述簡短闡述可以讓大家清楚地了解到Java應(yīng)用大致是如何進行訓練和評估的。
需要的就是這些,不過大家想嘗試其他的代碼(https://github.com/valohai/mlpmnist-dl4j-example/blob/master/Dockerfile)也是可以的(以及README.md和bash腳本),那就來滿足你的好奇心,搞清楚這些東西都是怎么操作的吧!
Valohai
在Valohai上,我們可以自由組合運行環(huán)境、代碼以及數(shù)據(jù)集,正如下文所示的YAML文件結(jié)構(gòu)。這樣一來,不同部件在升級時無需依賴另一方就可暢通無阻,Docker container中也就只有生成和運行組件。
執(zhí)行期間,在Docker container中生成uber jar,再將其上傳到某些內(nèi)部或外部存儲中,然后在另一個執(zhí)行步驟中下載儲存內(nèi)(也可以是另一個位置)的uber jar和數(shù)據(jù)集以便訓練模型。這樣兩個執(zhí)行步驟就會解耦;我們可以一次建立一個jar文件,然后在同一文件中運行數(shù)百個訓練步驟。生成和運行環(huán)境按理說不會變化得很頻繁,所以可以緩存下來,而且執(zhí)行期間代碼、數(shù)據(jù)集和模型資源都可隨時調(diào)用。
valohai.yaml
Java項目與Valohai服務(wù)硬件資源集成的核心在于確定 valohai.yaml 文件中的執(zhí)行步驟,該文件位于項目文件夾的根目錄中。valohai.yaml 大概是這個樣子:
---
- step:
name: Build-dl4j-mnist-single-layer-java-app
image: neomatrix369/dl4j-mnist-single-layer:v0.5
command:
- cd ${VH_REPOSITORY_DIR}
- ./buildUberJar.sh
- echo "~~~ Copying the build jar file into ${VH_OUTPUTS_DIR}"
- cp target/MLPMnist-1.0.0-bin.jar ${VH_OUTPUTS_DIR}/MLPMnist-1.0.0.jar
- ls -lash ${VH_OUTPUTS_DIR}
environment: aws-eu-west-1-g2-2xlarge
- step:
name: Run-dl4j-mnist-single-layer-train-model
image: neomatrix369/dl4j-mnist-single-layer:v0.5
command:
- echo "~~~ Unpack the MNist dataset into ${HOME} folder"
- tar xvzf ${VH_INPUTS_DIR}/dataset/mlp-mnist-dataset.tgz -C ${HOME}
- cd ${VH_REPOSITORY_DIR}
- echo "~~~ Copying the build jar file from ${VH_INPUTS_DIR} to current location"
- cp ${VH_INPUTS_DIR}/dl4j-java-app/MLPMnist-1.0.0.jar .
- echo "~~~ Run the DL4J app to train model based on the the MNist dataset"
- ./runMLPMnist.sh {parameters}
inputs:
- name: dl4j-java-app
description: DL4J Java app file (jar) generated in the previous step 'Build-dl4j-mnist-single-layer-java-app'
- name: dataset
default: https://github.com/neomatrix369/awesome-ai-ml-dl/releases/download/mnist-dataset-v0.1/mlp-mnist-dataset.tgz
description: MNist dataset needed to train the model
parameters:
- name: --action
pass-as: '--action {v}'
type: string
default: train
description: Action to perform i.e. train or evaluate
- name: --output-dir
pass-as: '--output-dir {v}'
type: string
default: /valohai/outputs/
description: Output directory where the model will be created, best to pick the Valohai output directory
environment: aws-eu-west-1-g2-2xlarge
- step:
name: Run-dl4j-mnist-single-layer-evaluate-model
image: neomatrix369/dl4j-mnist-single-layer:v0.5
command:
- cd ${VH_REPOSITORY_DIR}
- echo "~~~ Copying the build jar file from ${VH_INPUTS_DIR} to current location"
- cp ${VH_INPUTS_DIR}/dl4j-java-app/MLPMnist-1.0.0.jar .
- echo "~~~ Run the DL4J app to evaluate the trained MNist model"
- ./runMLPMnist.sh {parameters}
inputs:
- name: dl4j-java-app
description: DL4J Java app file (jar) generated in the previous step 'Build-dl4j-mnist-single-layer-java-app'
- name: model
description: Model file generated in the previous step 'Run-dl4j-mnist-single-layer-train-model'
parameters:
- name: --action
pass-as: '--action {v}'
type: string
default: evaluate
description: Action to perform i.e. train or evaluate
- name: --input-dir
pass-as: '--input-dir {v}'
type: string
default: /valohai/inputs/model
description: Input directory where the model created by the previous step can be found created
environment: aws-eu-west-1-g2-2xlarge
如何構(gòu)建dl4j的mnist單層java應(yīng)用程序
由YAML文件可看出,這一步首先調(diào)用了Docker image,然后運行生成腳本來構(gòu)建uber jar。Docker image中含有生成環(huán)境依賴項的設(shè)置(即GraalVM JDK、Maven等),從而實現(xiàn)Java應(yīng)用的構(gòu)建。不需要指定任何的輸入內(nèi)容或參數(shù),因為這本身就是生成步驟。一旦生成結(jié)束,我們就會將名為 MLPMnist-1.0.0-bin.jar(原名稱)的uber jar復(fù)制到/valohai/outputs文件夾內(nèi)(表示為${VH_OUTPUTS_DIR})。此文件夾中的所有內(nèi)容都會自動保存在項目存儲中,比如AWS S3 bucket。最后,設(shè)定為AWS環(huán)境下運行。
注:Valohai免費用戶沒有Docker container的內(nèi)部訪問權(quán)限(默認情況下是這樣),可以訪問幫助以啟用此選項(筆者就是這么辦的),不然的話就無法在生成過程中下載Maven和其他依賴項了。
如何運行dl4j的mnist單層訓練模型
這一部分與先前步驟的差不多,無非就是指定了兩個輸入內(nèi)容,一個針對uber jar(MLPMnist-1.0.0.jar),一個針對數(shù)據(jù)集(解壓縮到${HOME}/.deeplearning4j文件夾中)。該過程中將傳遞兩個參數(shù),--action train 和--output-dir /valohai/outputs,此間創(chuàng)建的模型會存到 /valohai/outputs/model文件夾中(表示為 ${VH_OUTPUTS_DIR}/model)。
注:在Valohai Web UI的執(zhí)行選項卡中,除了可以通過datum:// or http:// URLs選擇先前執(zhí)行步驟中的輸入內(nèi)容,也可利用執(zhí)行數(shù)字(即#1或#2)。在鍵盤上敲文件名的幾個字母也可以助力全面搜索。
如何運行dl4j的mnist單層評估模型
這個步驟還是跟之前相似,不同之處在于會傳遞兩個參數(shù)--action evaluate 和 --input-dir /valohai/inputs/model。此外,我們也會再一次指定兩項輸入內(nèi)容:dl4j-java-app和model ,它們在YAML文件中定義而且都沒有默認設(shè)置。這樣一來操作者就可以選擇想要評估的uber jar和模型——二者是在web界面運行dl4j的mnist單層評估模型時創(chuàng)建的。
筆者希望這可以解釋上述定義文件的步驟,但如果你想進一步尋求幫助,別猶豫了,請查看這里的文件(https://docs.valohai.com/index.html)和教程(https://docs.valohai.com/tutorials/index.html)。
Valohai網(wǎng)頁界面
有了賬戶,就可以登錄繼續(xù)創(chuàng)建項目,命名為mlpmnist-single-layer ,鏈接至git儲存庫 https://github.com/valohai/mlpmnist-dl4j-example,保存項目。
現(xiàn)在可以執(zhí)行一下看看是怎么個操作法!
構(gòu)建DL4J Java應(yīng)用程序
點擊網(wǎng)頁界面的執(zhí)行選項卡,再復(fù)制現(xiàn)有執(zhí)行或者使用[創(chuàng)建執(zhí)行]按鈕創(chuàng)建新執(zhí)行。所有的默認選項都會涉及到。選擇構(gòu)建dl4j的mnist單層java應(yīng)用程序。
至于說環(huán)境,筆者會選擇AWS eu-west-1 g2.2xlarge,然后再在網(wǎng)頁最下方點擊[創(chuàng)建執(zhí)行]來看看執(zhí)行的啟動。
訓練模型
點擊網(wǎng)頁界面的執(zhí)行選項卡,重復(fù)上一步操作,然后選擇運行dlj4的mnist單層訓練模型。大家需要選擇的是之前步驟中生成的Java應(yīng)用程序(就是filed類中的jar文件)。而數(shù)據(jù)集已經(jīng)提前通過valohai.yaml文件預(yù)填充過了:
點擊[創(chuàng)建執(zhí)行]啟動這一項。
在log console中可以看到模型概要的變化:
[]
11:17:05 =========================================================================
11:17:05 LayerName (LayerType) nIn,nOut TotalParams ParamsShape
11:17:05 =========================================================================
11:17:05 layer0 (DenseLayer) 784,1000 785000 W:{784,1000}, b:{1,1000}
11:17:05 layer1 (OutputLayer) 1000,10 10010 W:{1000,10}, b:{1,10}
11:17:05 -------------------------------------------------------------------------
11:17:05 Total Parameters: 795010
11:17:05 Trainable Parameters: 795010
11:17:05 Frozen Parameters: 0
11:17:05 =========================================================================
[]
執(zhí)行期間以及結(jié)束時,可以在執(zhí)行主選項卡中的輸出子選項卡下找到已創(chuàng)建的模型:
你也許已經(jīng)注意到輸出選項卡中有幾個artifacts文件。那是因為我們在每一回epoch的最后一步都保存了一個checkpoint!從執(zhí)行記錄里能看到它們:
[]
11:17:14 o.d.o.l.CheckpointListener - Model checkpoint saved: epoch 0, iteration 469, path: /valohai/outputs/checkpoint_0_MultiLayerNetwork.zip
[]
Checkpoint壓縮包內(nèi)有每一節(jié)點處模型訓練的狀態(tài),可在下面三個文件中查詢:
configuration.json
coefficients.bin
updaterState.bin
訓練模型>元數(shù)據(jù)
大家也許在執(zhí)行記錄中注意到這些符號了:
[]
11:17:05 {"epoch": 0, "iteration": 0, "score (loss function)": 2.410047}
11:17:07 {"epoch": 0, "iteration": 100, "score (loss function)": 0.613774}
11:17:09 {"epoch": 0, "iteration": 200, "score (loss function)": 0.528494}
11:17:11 {"epoch": 0, "iteration": 300, "score (loss function)": 0.400291}
11:17:13 {"epoch": 0, "iteration": 400, "score (loss function)": 0.357800}
11:17:14 o.d.o.l.CheckpointListener - Model checkpoint saved: epoch 0, iteration 469, path: /valohai/outputs/checkpoint_0_MultiLayerNetwork.zip
[]
這些符號會觸發(fā)Valohai挑選這些值(JSON格式)以形成執(zhí)行指標,這些指標在執(zhí)行中及執(zhí)行后都可以在執(zhí)行主選項卡中的元數(shù)據(jù)子選項下找到:
通過將listener類(被稱為Valohai元數(shù)據(jù)生成器)鏈接到模型中來完成這一步的操作。這樣一來,訓練中每一次迭代結(jié)束之時,都可以集中于listener類上,打印出元計數(shù)、迭代計數(shù)和分數(shù)(丟失的功能值)。下面是這個類的代碼片段:
public void iterationDone(Model model, int iteration, int epoch) {
if (printIterations <= 0)
printIterations = 1;
if (iteration % printIterations == 0) {
double score = model.score();
System.out.println(String.format(
"{"epoch": %d, "iteration": %d, "score (loss function)": %f}
總結(jié)
以上是生活随笔為你收集整理的java五子棋代码详解_代码详解:Java和Valohai的深度学习之旅的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实现二叉树以及遍历二叉树
- 下一篇: curl命令java_Java中的cur