【DL4J速成】Deeplearning4j图像分类从模型自定义到测试
文章首發(fā)于微信公眾號《有三AI》
【DL4J速成】Deeplearning4j圖像分類從模型自定義到測試
歡迎來到專欄《2小時玩轉(zhuǎn)開源框架系列》,這是我們第九篇,前面已經(jīng)說過了caffe,tensorflow,pytorch,mxnet,keras,paddlepaddle,cntk,chainer。
今天說Deeplearning4j(DL4J),本文所用到的數(shù)據(jù),代碼請參考我們官方git
https://github.com/longpeng2008/LongPeng_ML_Course
作者&編輯?|?胡郡郡?言有三??
?
1?Deeplearning4j(DL4J)是什么
不同于深度學(xué)習(xí)廣泛應(yīng)用的語言Python,DL4J是為java和jvm編寫的開源深度學(xué)習(xí)庫,支持各種深度學(xué)習(xí)模型。
DL4J最重要的特點是支持分布式,可以在Spark和Hadoop上運行,支持分布式CPU和GPU運行。DL4J是為商業(yè)環(huán)境,而非研究所設(shè)計的,因此更加貼近某些生產(chǎn)環(huán)境。
?
2?DL4J訓(xùn)練準(zhǔn)備
2.1?DL4J安裝
系統(tǒng)要求:
-
Java:開發(fā)者版7或更新版本(僅支持64位版本)
-
Apache?Maven:Maven是針對Java的項目管理工具,兼容IntelliJ等IDE,可以讓我們輕松安裝DL4J項目庫
-
IntelliJ?IDEA?(建議)或?Eclipse
-
Git
官方提供了很多DL4J的示例。可以通過以下命令下載安裝:
$?git?clone?https://github.com/deeplearning4j/dl4j-examples.git $?cd?dl4j-examples/$?mvn?clean?installmvn?clean?install?目的是為了安裝所依賴的相關(guān)包。
然后將下載的dl4j-examples導(dǎo)入到IntelliJ?IDEA中,點擊自己想要試的例子進(jìn)行運行。
2.2?數(shù)據(jù)準(zhǔn)備
DL4J有自己的特殊的數(shù)據(jù)結(jié)構(gòu)DataVec,所有的輸入數(shù)據(jù)在進(jìn)入神經(jīng)網(wǎng)絡(luò)之前要先經(jīng)過向量化。向量化后的結(jié)果就是一個行數(shù)不限的單列矩陣。
熟悉Hadoop/MapReduce的朋友肯定知道它的輸入用InputFormat來確定具體的InputSplit和RecordReader。DataVec也有自己FileSplit和RecordReader,并且對于不同的數(shù)據(jù)類型(文本、CSV、音頻、圖像、視頻等),有不同的RecordReader,下面是一個圖像的例子。
int height = 48; // 輸入圖像高度 int width = 48; // 輸入圖像寬度 int channels = 3; // 輸入圖像通道數(shù) int outputNum = 2; // 2分類 int batchSize = 64; int nEpochs = 100; int seed = 1234; Random randNumGen = new Random(seed);// 訓(xùn)練數(shù)據(jù)的向量化 File trainData = new File(inputDataDir + "/train"); FileSplit trainSplit = new FileSplit(trainData, NativeImageLoader.ALLOWED_FORMATS, randNumGen); ParentPathLabelGenerator labelMaker = new ParentPathLabelGenerator(); // parent path as the image label ImageRecordReader trainRR = new ImageRecordReader(height, width, channels, labelMaker); trainRR.initialize(trainSplit); DataSetIterator trainIter = new RecordReaderDataSetIterator(trainRR, batchSize, 1, outputNum);// 將像素從0-255縮放到0-1 (用min-max的方式進(jìn)行縮放) DataNormalization scaler = new ImagePreProcessingScaler(0, 1); scaler.fit(trainIter); trainIter.setPreProcessor(scaler);// 測試數(shù)據(jù)的向量化 File testData = new File(inputDataDir + "/test"); FileSplit testSplit = new FileSplit(testData, NativeImageLoader.ALLOWED_FORMATS, randNumGen); ImageRecordReader testRR = new ImageRecordReader(height, width, channels, labelMaker); testRR.initialize(testSplit); DataSetIterator testIter = new RecordReaderDataSetIterator(testRR, batchSize, 1, outputNum); testIter.setPreProcessor(scaler); // same normalization for better results數(shù)據(jù)準(zhǔn)備的過程分成以下幾個步驟:
1)通過FileSplit處理輸入文件,FileSplit決定了文件的分布式的分發(fā)和處理。
2)ParentPathLabelGenerator通過父目錄來直接生成標(biāo)簽,這個生成標(biāo)簽的接口非常方便,比如說如果是二分類,我們先將兩個父目錄設(shè)定為0和1,然后再分別在里面放置對應(yīng)的圖像就行。
3)通過ImageRecordReader讀入輸入圖像。RecordReader是DataVec中的一個類,ImageRecordReader是RecordReader中的一個子類,這樣就可以將輸入圖像轉(zhuǎn)成向量化的帶有索引的數(shù)據(jù)。
4)生成DataSetIterator,實現(xiàn)了對輸入數(shù)據(jù)集的迭代。
2.3?網(wǎng)絡(luò)定義
在Deeplearning4j中,添加一個層的方式是通過NeuralNetConfiguration.Builder()調(diào)用layer,指定其在所有層中的輸入及輸出節(jié)點數(shù)nIn和nOut,激活方式activation,層的類型如ConvolutionLayer等。
//?設(shè)置網(wǎng)絡(luò)層及超參數(shù) MultiLayerConfiguration?conf?=?new?NeuralNetConfiguration.Builder().seed(seed).l2(0.0005).updater(new?Adam(0.0001)).weightInit(WeightInit.XAVIER).list().layer(0,?new?ConvolutionLayer.Builder(3,?3).nIn(channels).stride(2,?2).nOut(12).activation(Activation.RELU).weightInit(WeightInit.XAVIER).build()).layer(1,?new?BatchNormalization.Builder().nIn(12).nOut(12).build()).layer(2,?new?ConvolutionLayer.Builder(3,?3).nIn(12).stride(2,?2).nOut(24).activation(Activation.RELU).weightInit(WeightInit.XAVIER).build()).layer(3,?new?BatchNormalization.Builder().nIn(24).nOut(24).build()).layer(4,?new?ConvolutionLayer.Builder(3,?3).nIn(24).stride(2,?2).nOut(48).activation(Activation.RELU).weightInit(WeightInit.XAVIER).build()).layer(5,?new?BatchNormalization.Builder().nIn(48).nOut(48).build()).layer(6,?new?DenseLayer.Builder().activation(Activation.RELU).nOut(128).build()).layer(7,?new?OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD).nOut(outputNum).activation(Activation.SOFTMAX).build()).setInputType(InputType.convolutionalFlat(48,?48,?3))?//?InputType.convolutional?for?normal?image.backprop(true).pretrain(false).build();這里的網(wǎng)絡(luò)結(jié)構(gòu)和之前的caffe、tensorflow、pytorch等框架采用的網(wǎng)絡(luò)結(jié)構(gòu)是一樣的,都是一個3層的神經(jīng)網(wǎng)絡(luò)。
?
3?模型訓(xùn)練
數(shù)據(jù)準(zhǔn)備好了,網(wǎng)絡(luò)也建好了,接下來就可以訓(xùn)練了。
//?新建一個多層網(wǎng)絡(luò)模型MultiLayerNetwork?net?=?new?MultiLayerNetwork(conf); net.init();//?訓(xùn)練的過程中同時進(jìn)行評估 for?(int?i?=?0;?i?<?nEpochs;?i++)?{net.fit(trainIter);log.info("Completed?epoch?"?+?i);Evaluation?trainEval?=?net.evaluate(trainIter);Evaluation?eval?=?net.evaluate(testIter);log.info("train:?"?+?trainEval.precision());log.info("val:?"?+?eval.precision());trainIter.reset();testIter.reset(); }//保存模型ModelSerializer.writeModel(net,?new?File(modelDir?+?"/mouth-model.zip"),?true);訓(xùn)練的過程非常簡單直觀,直接通過net.fit()加載trainIter就可以,其中trainIter在數(shù)據(jù)準(zhǔn)備中已經(jīng)定義好了。
通過net.evaluate(trainIter)和net.evaluate(testIter)的方式來評估訓(xùn)練和測試的表現(xiàn),這里我們將每個epoch的準(zhǔn)確率打印出來。
?
4?可視化
DL4J提供的用戶界面可以在瀏覽器中看到實時的訓(xùn)練過程。
第一步:
將用戶界面依賴項添加到pom文件中:
<dependency><groupId>org.deeplearning4j</groupId><artifactId>deeplearning4j-ui_2.10</artifactId><version>${dl4j.version}</version></dependency>第二步:
在項目中啟動用戶界面
//初始化用戶界面后端,獲取一個UI實例 UIServer?uiServer?=?UIServer.getInstance(); //設(shè)置網(wǎng)絡(luò)信息(隨時間變化的梯度、分值等)的存儲位置。這里將其存儲于內(nèi)存。 StatsStorage?statsStorage?=?new?InMemoryStatsStorage();? //將StatsStorage實例連接至用戶界面,讓StatsStorage的內(nèi)容能夠被可視化 uiServer.attach(statsStorage); //添加StatsListener來在網(wǎng)絡(luò)定型時收集這些信息 net.setListeners(new?StatsListener(statsStorage));首先我們初始化一個用戶界面后端,設(shè)置網(wǎng)絡(luò)信息的存儲位置。
這里將其存儲于內(nèi)存,也可以放入文件中,通過new?FileStatsStorage(File)的方式實現(xiàn)。
再將StatsStorage實例連接至用戶界面,讓StatsStorage的內(nèi)容能夠被可視化。
最后添加StatsListener監(jiān)聽,在網(wǎng)絡(luò)定型時收集這些信息。
默認(rèn)的瀏覽器地址是:http://localhost:9000/train/overview
下面可視化一下?lián)p失函數(shù)值隨迭代次數(shù)的變化曲線
模型頁面中可以直觀感受我們建立的模型
看一下最后的訓(xùn)練集和測試集的準(zhǔn)確率
有一些過擬合,主要原因還是數(shù)據(jù)太少。
以上就是我們用自己的數(shù)據(jù)在DL4J框架上實踐的內(nèi)容,完整代碼可以參考官方git。
?
總結(jié)
本文講解了如何使用DL4J深度學(xué)習(xí)框架完成一個分類任務(wù),雖然這個框架不是很熱門,但是它是唯一集成java和大數(shù)據(jù)平臺的,您在用嗎?如果您在用,可以聯(lián)系我們一起交流下!另外,還有想讓我們介紹的框架嗎?歡迎留言。
轉(zhuǎn)載文章請后臺聯(lián)系
侵權(quán)必究
本系列完整文章:
第一篇:【caffe速成】caffe圖像分類從模型自定義到測試
第二篇:【tensorflow速成】Tensorflow圖像分類從模型自定義到測試
第三篇:【pytorch速成】Pytorch圖像分類從模型自定義到測試
第四篇:【paddlepaddle速成】paddlepaddle圖像分類從模型自定義到測試
第五篇:【Keras速成】Keras圖像分類從模型自定義到測試
第六篇:【mxnet速成】mxnet圖像分類從模型自定義到測試
第七篇:【cntk速成】cntk圖像分類從模型自定義到測試
第八篇:【chainer速成】chainer圖像分類從模型自定義到測試
第九篇:【DL4J速成】Deeplearning4j圖像分類從模型自定義到測試
第十篇:【MatConvnet速成】MatConvnet圖像分類從模型自定義到測試
第十一篇:【Lasagne速成】Lasagne/Theano圖像分類從模型自定義到測試
第十二篇:【darknet速成】Darknet圖像分類從模型自定義到測試
感謝各位看官的耐心閱讀,不足之處希望多多指教。后續(xù)內(nèi)容將會不定期奉上,歡迎大家關(guān)注有三公眾號 有三AI!
總結(jié)
以上是生活随笔為你收集整理的【DL4J速成】Deeplearning4j图像分类从模型自定义到测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【技术综述】基于弱监督深度学习的图像分割
- 下一篇: 有三AI知识星球官宣,BAT等大咖等你来