【DL4J速成】Deeplearning4j图像分类从模型自定义到测试
文章首發(fā)于微信公眾號(hào)《有三AI》
【DL4J速成】Deeplearning4j圖像分類從模型自定義到測(cè)試
歡迎來(lái)到專欄《2小時(shí)玩轉(zhuǎn)開(kāi)源框架系列》,這是我們第九篇,前面已經(jīng)說(shuō)過(guò)了caffe,tensorflow,pytorch,mxnet,keras,paddlepaddle,cntk,chainer。
今天說(shuō)Deeplearning4j(DL4J),本文所用到的數(shù)據(jù),代碼請(qǐng)參考我們官方git
https://github.com/longpeng2008/LongPeng_ML_Course
作者&編輯?|?胡郡郡?言有三??
?
1?Deeplearning4j(DL4J)是什么
不同于深度學(xué)習(xí)廣泛應(yīng)用的語(yǔ)言Python,DL4J是為java和jvm編寫的開(kāi)源深度學(xué)習(xí)庫(kù),支持各種深度學(xué)習(xí)模型。
DL4J最重要的特點(diǎn)是支持分布式,可以在Spark和Hadoop上運(yùn)行,支持分布式CPU和GPU運(yùn)行。DL4J是為商業(yè)環(huán)境,而非研究所設(shè)計(jì)的,因此更加貼近某些生產(chǎn)環(huán)境。
?
2?DL4J訓(xùn)練準(zhǔn)備
2.1?DL4J安裝
系統(tǒng)要求:
-
Java:開(kāi)發(fā)者版7或更新版本(僅支持64位版本)
-
Apache?Maven:Maven是針對(duì)Java的項(xiàng)目管理工具,兼容IntelliJ等IDE,可以讓我們輕松安裝DL4J項(xiàng)目庫(kù)
-
IntelliJ?IDEA?(建議)或?Eclipse
-
Git
官方提供了很多DL4J的示例。可以通過(guò)以下命令下載安裝:
$?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中,點(diǎn)擊自己想要試的例子進(jìn)行運(yù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)過(guò)向量化。向量化后的結(jié)果就是一個(gè)行數(shù)不限的單列矩陣。
熟悉Hadoop/MapReduce的朋友肯定知道它的輸入用InputFormat來(lái)確定具體的InputSplit和RecordReader。DataVec也有自己FileSplit和RecordReader,并且對(duì)于不同的數(shù)據(jù)類型(文本、CSV、音頻、圖像、視頻等),有不同的RecordReader,下面是一個(gè)圖像的例子。
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);// 測(cè)試數(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)備的過(guò)程分成以下幾個(gè)步驟:
1)通過(guò)FileSplit處理輸入文件,FileSplit決定了文件的分布式的分發(fā)和處理。
2)ParentPathLabelGenerator通過(guò)父目錄來(lái)直接生成標(biāo)簽,這個(gè)生成標(biāo)簽的接口非常方便,比如說(shuō)如果是二分類,我們先將兩個(gè)父目錄設(shè)定為0和1,然后再分別在里面放置對(duì)應(yīng)的圖像就行。
3)通過(guò)ImageRecordReader讀入輸入圖像。RecordReader是DataVec中的一個(gè)類,ImageRecordReader是RecordReader中的一個(gè)子類,這樣就可以將輸入圖像轉(zhuǎn)成向量化的帶有索引的數(shù)據(jù)。
4)生成DataSetIterator,實(shí)現(xiàn)了對(duì)輸入數(shù)據(jù)集的迭代。
2.3?網(wǎng)絡(luò)定義
在Deeplearning4j中,添加一個(gè)層的方式是通過(guò)NeuralNetConfiguration.Builder()調(diào)用layer,指定其在所有層中的輸入及輸出節(jié)點(diǎn)數(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)是一樣的,都是一個(gè)3層的神經(jīng)網(wǎng)絡(luò)。
?
3?模型訓(xùn)練
數(shù)據(jù)準(zhǔn)備好了,網(wǎng)絡(luò)也建好了,接下來(lái)就可以訓(xùn)練了。
//?新建一個(gè)多層網(wǎng)絡(luò)模型MultiLayerNetwork?net?=?new?MultiLayerNetwork(conf); net.init();//?訓(xùn)練的過(guò)程中同時(shí)進(jìn)行評(píng)估 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)練的過(guò)程非常簡(jiǎn)單直觀,直接通過(guò)net.fit()加載trainIter就可以,其中trainIter在數(shù)據(jù)準(zhǔn)備中已經(jīng)定義好了。
通過(guò)net.evaluate(trainIter)和net.evaluate(testIter)的方式來(lái)評(píng)估訓(xùn)練和測(cè)試的表現(xiàn),這里我們將每個(gè)epoch的準(zhǔn)確率打印出來(lái)。
?
4?可視化
DL4J提供的用戶界面可以在瀏覽器中看到實(shí)時(shí)的訓(xùn)練過(guò)程。
第一步:
將用戶界面依賴項(xiàng)添加到pom文件中:
<dependency><groupId>org.deeplearning4j</groupId><artifactId>deeplearning4j-ui_2.10</artifactId><version>${dl4j.version}</version></dependency>第二步:
在項(xiàng)目中啟動(dòng)用戶界面
//初始化用戶界面后端,獲取一個(gè)UI實(shí)例 UIServer?uiServer?=?UIServer.getInstance(); //設(shè)置網(wǎng)絡(luò)信息(隨時(shí)間變化的梯度、分值等)的存儲(chǔ)位置。這里將其存儲(chǔ)于內(nèi)存。 StatsStorage?statsStorage?=?new?InMemoryStatsStorage();? //將StatsStorage實(shí)例連接至用戶界面,讓StatsStorage的內(nèi)容能夠被可視化 uiServer.attach(statsStorage); //添加StatsListener來(lái)在網(wǎng)絡(luò)定型時(shí)收集這些信息 net.setListeners(new?StatsListener(statsStorage));首先我們初始化一個(gè)用戶界面后端,設(shè)置網(wǎng)絡(luò)信息的存儲(chǔ)位置。
這里將其存儲(chǔ)于內(nèi)存,也可以放入文件中,通過(guò)new?FileStatsStorage(File)的方式實(shí)現(xiàn)。
再將StatsStorage實(shí)例連接至用戶界面,讓StatsStorage的內(nèi)容能夠被可視化。
最后添加StatsListener監(jiān)聽(tīng),在網(wǎng)絡(luò)定型時(shí)收集這些信息。
默認(rèn)的瀏覽器地址是:http://localhost:9000/train/overview
下面可視化一下?lián)p失函數(shù)值隨迭代次數(shù)的變化曲線
模型頁(yè)面中可以直觀感受我們建立的模型
看一下最后的訓(xùn)練集和測(cè)試集的準(zhǔn)確率
有一些過(guò)擬合,主要原因還是數(shù)據(jù)太少。
以上就是我們用自己的數(shù)據(jù)在DL4J框架上實(shí)踐的內(nèi)容,完整代碼可以參考官方git。
?
總結(jié)
本文講解了如何使用DL4J深度學(xué)習(xí)框架完成一個(gè)分類任務(wù),雖然這個(gè)框架不是很熱門,但是它是唯一集成java和大數(shù)據(jù)平臺(tái)的,您在用嗎?如果您在用,可以聯(lián)系我們一起交流下!另外,還有想讓我們介紹的框架嗎?歡迎留言。
轉(zhuǎn)載文章請(qǐng)后臺(tái)聯(lián)系
侵權(quán)必究
本系列完整文章:
第一篇:【caffe速成】caffe圖像分類從模型自定義到測(cè)試
第二篇:【tensorflow速成】Tensorflow圖像分類從模型自定義到測(cè)試
第三篇:【pytorch速成】Pytorch圖像分類從模型自定義到測(cè)試
第四篇:【paddlepaddle速成】paddlepaddle圖像分類從模型自定義到測(cè)試
第五篇:【Keras速成】Keras圖像分類從模型自定義到測(cè)試
第六篇:【mxnet速成】mxnet圖像分類從模型自定義到測(cè)試
第七篇:【cntk速成】cntk圖像分類從模型自定義到測(cè)試
第八篇:【chainer速成】chainer圖像分類從模型自定義到測(cè)試
第九篇:【DL4J速成】Deeplearning4j圖像分類從模型自定義到測(cè)試
第十篇:【MatConvnet速成】MatConvnet圖像分類從模型自定義到測(cè)試
第十一篇:【Lasagne速成】Lasagne/Theano圖像分類從模型自定義到測(cè)試
第十二篇:【darknet速成】Darknet圖像分類從模型自定義到測(cè)試
感謝各位看官的耐心閱讀,不足之處希望多多指教。后續(xù)內(nèi)容將會(huì)不定期奉上,歡迎大家關(guān)注有三公眾號(hào) 有三AI!
總結(jié)
以上是生活随笔為你收集整理的【DL4J速成】Deeplearning4j图像分类从模型自定义到测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【技术综述】基于弱监督深度学习的图像分割
- 下一篇: 【杂谈】从GitHub上星星最多的男人开