คำนำ
ในการเรียนรู้ของเครื่องจักรเครือข่ายประสาทแบบ Convolutional เป็นเครือข่ายประสาทเทียมที่ได้รับการป้อนไปข้างหน้าอย่างลึกล้ำซึ่งได้นำไปใช้กับการจดจำภาพได้อย่างประสบความสำเร็จ ในปัจจุบันการจดจำหมายเลขป้ายทะเบียนจำนวนมากการจดจำใบหน้า ฯลฯ ใช้เครือข่ายประสาทแบบ Convolutional อาจกล่าวได้ว่าเครือข่ายประสาทของ Convolutional ประสบความสำเร็จอย่างมากในการรับรู้ภาพ มีกรอบการเรียนรู้ที่ลึกล้ำของโอเพ่นซอร์สมากมายเช่นคาเฟอีน, เทนเซอร์โฟล, ไฟฉาย, ฯลฯ กรอบการเรียนรู้ที่ลึกซึ้งเหล่านี้รวมถึงการใช้งานเครือข่ายประสาทที่สมบูรณ์แบบ ดังนั้นทำไมเรายังต้องเขียนเครือข่ายประสาทแบบ convolutional ด้วยตัวเอง? เป็นการดีกว่าที่จะใช้เฟรมเวิร์กการเรียนรู้ลึกโอเพ่นซอร์สเหล่านี้โดยตรงซึ่งรวดเร็วและง่ายต่อการจัดการมีประสิทธิภาพที่ดีและมีข้อบกพร่องน้อย ใช่ถ้าคุณเพียงแค่ใช้เครือข่ายนิวรัลคอลการทำแอปพลิเคชันบางอย่างและไม่สนใจหลักการทำงานของมันคุณไม่ต้องทำงานอย่างหนักเพื่อเขียนเครือข่ายประสาทแบบ Convolutional แต่ถ้าคุณต้องการควบคุมหลักการทำงานของเครือข่ายประสาทแบบ Convolutional อย่างเต็มที่สมัยก่อนกล่าวว่า: สิ่งที่คุณได้รับบนกระดาษจะตื้นเสมอและคุณต้องฝึกฝนการรับรู้ในเวลานี้ ดังนั้นจึงจำเป็นอย่างยิ่งที่คุณจะต้องใช้เครือข่ายประสาทแบบ Convolutional ด้วยตัวคุณเองเพื่อให้เข้าใจลึกซึ้งยิ่งขึ้น
Cupcnn คืออะไร
Cupcnn เป็นเครือข่ายประสาทที่เขียนใน Java นอกเหนือจากการทำงานแล้วฉันยังตระหนักถึงมันเพื่อให้เข้าใจถึงเครือข่ายประสาทเทียมที่ลึกซึ้งยิ่งขึ้น มันง่ายพอและทำงานได้ดีทำให้เหมาะสำหรับผู้เริ่มต้นที่จะอ้างถึง ซอร์สโค้ดสามารถดาวน์โหลดได้จาก GitHub: Cupcnn
คุณไม่ต้องกังวลเกี่ยวกับข้อ จำกัด ของโปรโตคอลหรืออะไรบางอย่าง คุณสามารถใช้มันเพื่อทำทุกอย่างและแก้ไขโดยพลการ ถ้ามันสามารถช่วยคุณได้ฉันหวังว่ามันจะให้ดาวคุณ! - -
-
แนวคิดการออกแบบ
ฉันหวังว่ามันจะเป็นเครือข่ายประสาทที่ง่ายพอที่จะช่วยให้ผู้เริ่มต้นเรียนรู้ ดังนั้นฉันจึงไม่ได้ใช้สิ่งที่เร่งความเร็วพร้อมกันซึ่งรับประกันลักษณะเบื้องต้นของรหัส เมื่อออกแบบฉันแบ่งเครือข่ายประสาทแบบ convolutional ออกเป็นสี่โมดูล: เครือข่าย (Layer Blob Loss Active) ซึ่งสามารถมองเห็นได้จากชื่อแพ็คเกจ เลเยอร์การสูญเสียและการใช้งานทั้งหมดมีคลาสพื้นฐานและการเขียนโปรแกรมของเครือข่ายประสาททั้งหมดมุ่งเน้นไปที่คลาสฐาน เครือข่ายเป็นศูนย์กลางที่รวมโมดูลทั้งสี่นี้พิกัดและจัดส่งทรัพยากร แต่ละเลเยอร์จะมีอินสแตนซ์ของเครือข่ายเพื่อให้ข้อมูลต่าง ๆ สามารถรับได้อย่างง่ายดายผ่านเครือข่ายเช่นการได้รับเอาต์พุตของแต่ละเลเยอร์แตกต่าง ฯลฯ ฯลฯ
แผนภาพบล็อกการออกแบบมีดังนี้:
การบันทึกพารามิเตอร์นั้นง่ายมากสำหรับ Java การใช้อินเทอร์เฟซแบบ serializable สามารถใช้งานการทำให้เป็นอนุกรมและ deserialization ของพารามิเตอร์ได้อย่างรวดเร็ว Cupcnn ใช้เฉพาะอินเตอร์เฟส serializable สำหรับ blob และ blobparams ในไดเรกทอรีข้อมูลและพารามิเตอร์ทั้งหมดจะถูกนำไปใช้โดยทั้งสอง
ประสิทธิภาพปัจจุบัน
เครือข่ายประสาทที่เชื่อมต่ออย่างสมบูรณ์
ขณะนี้ในชุดข้อมูล MNIST เครือข่ายประสาทที่เชื่อมต่ออย่างสมบูรณ์ (การเชื่อมต่อเต็ม (100) + การเชื่อมต่อเต็ม (30) + การเชื่อมต่อเต็ม (10) + Softmax) ได้รับการฝึกฝนด้วย 30 epoes ด้วยอัตราความแม่นยำ 96.76
เครือข่ายประสาท
เครือข่ายนิวรัลแบบ Convolutional (6 คุณสมบัติ) + การรวมตัวสูงสุด + convolution (6 คุณสมบัติ) + การเชื่อมต่อเต็มรูปแบบ (512) + การเชื่อมต่อเต็มรูปแบบ (30) + การเชื่อมต่อเต็มรูปแบบ (10) + softmax) เมื่ออัตราการเรียนรู้คือ 0.2, 30 epoes ได้รับการฝึกฝนอัตราความแม่นยำคือ 97.79 ฉันเชื่อว่าหลังจากการปรับค่าพารามิเตอร์เพิ่มเติมอัตราความแม่นยำอาจสูงขึ้นภายใต้การฝึกอบรมที่เพียงพอ
ภาพรวมการฝึกอบรมของเครือข่ายประสาท Convolutional มีดังนี้:
เริ่มรถไฟ
Epoe: 0 Lossvalue: 2.3019369891560455 LR: 0.2 ความแม่นยำคือ 0.13
Epoe: 0 Lossvalue: 2.0722489482105195 LR: 0.2 ความแม่นยำคือ 0.44
Epoe: 0 Lossvalue: 1.2423286194012682 LR: 0.2 ความแม่นยำคือ 0.72
Epoe: 0 Lossvalue: 0.7860529560675255 LR: 0.2 ความแม่นยำคือ 0.79
Epoe: 0 Lossvalue: 0.6272194196176664 LR: 0.2 ความแม่นยำคือ 0.87
Epoe: 0 Lossvalue: 0.5240051326725808 LR: 0.2 ความแม่นยำคือ 0.84
Epoe: 0 Lossvalue: 0.27637563581928026 LR: 0.2 ความแม่นยำคือ 0.95
Epoe: 0 Lossvalue: 0.35585388987055083 LR: 0.2 ความแม่นยำคือ 0.92
Epoe: 0 Lossvalue: 0.441971528417802 LR: 0.2 ความแม่นยำคือ 0.92
Epoe: 0 Lossvalue: 0.25637710325999674 LR: 0.2 ความแม่นยำคือ 0.95
Epoe: 0 Lossvalue: 0.39872273532502 LR: 0.2 ความแม่นยำคือ 0.9
Epoe: 1 Lossvalue: 0.264085484522027 LR: 0.160000000000000000003 ความแม่นยำคือ 0.91
Epoe: 1 Lossvalue: 0.22754066024803088 LR: 0.1600000000000000003 ความแม่นยำคือ 0.96
Epoe: 1 Lossvalue: 0.30256420975577103 LR: 0.160000000000000000003 ความแม่นยำคือ 0.96
Epoe: 1 Lossvalue: 0.181496486222985948 LR: 0.16000000000000000003 ความแม่นยำคือ 0.99
Epoe: 1 Lossvalue: 0.177239938748327 LR: 0.1600000000000000003 ความแม่นยำคือ 0.96
Epoe: 1 Lossvalue: 0.15041993009777443 LR: 0.1600000000000000003 ความแม่นยำคือ 0.98
Epoe: 1 Lossvalue: 0.10759545752665524 LR: 0.1600000000000000000003 ความแม่นยำคือ 1.0
การใช้ cupcnn
ในปัจจุบัน Cupcnn ใช้การทดสอบในชุดข้อมูล MNIST ภายใต้ SRC/การทดสอบ Mnisttest เป็นทางเข้าสู่ฟังก์ชั่นหลักและเครือข่ายประสาทเฉพาะถูกสร้างขึ้นในคลาส Mnistnetwork ในคลาส Mnistnetwork, BuildConvNetwork และ BuildFCNetwork ตามลำดับนำการก่อสร้างเครือข่ายประสาทแบบ convolutional และการสร้างเครือข่ายประสาทที่เชื่อมต่ออย่างเต็มที่ ต้องขอบคุณคุณสมบัติข้ามแพลตฟอร์มที่ดีของ Java หลังจากที่คุณดาวน์โหลดซอร์สโค้ดของ Cupcnn ใช้ Eclipse เพื่อเปิดโครงการแล้วเรียกใช้โดยตรงคุณควรเริ่มการฝึกอบรมและทดสอบในชุดข้อมูล MNIST
การสร้างเครือข่ายประสาท
โมฆะสาธารณะ buildNetwork () {// แรกสร้างวัตถุเครือข่ายประสาทและตั้งค่าพารามิเตอร์เครือข่าย = เครือข่ายใหม่ (); Network.setBatch (100); Network.setLoss (ใหม่ loglikehoodloss ()); //network.setloss( ใหม่ Crossentropyloss ()); Optimizer = ใหม่ sgdoptimizer (0.2); Network.setOptimizer (Optimizer); // buildfcnetwork (); buildConvNetwork (); Network.Prepare (); - ฟังก์ชั่น setBatch () กำหนดจำนวนรูปภาพในชุด
SetLoss () ตั้งค่าฟังก์ชั่นการสูญเสียที่จะใช้ Cupcnn ใช้ฟังก์ชั่นการสูญเสียเอนโทรปีข้ามและฟังก์ชั่นการสูญเสียความน่าจะเป็นของบันทึก
ควรใช้ setoptimizer () เพื่อตั้งค่าเครื่องมือเพิ่มประสิทธิภาพ Cupcnn ใช้เฉพาะเครื่องมือเพิ่มประสิทธิภาพ SGD หากคุณใช้เครื่องมือเพิ่มประสิทธิภาพที่ดีกว่าและยินดีที่จะส่งไปยัง Cupcnn ฉันขอต้อนรับอย่างลึกซึ้ง
สร้างเครือข่ายประสาทที่เชื่อมต่ออย่างสมบูรณ์
โมฆะส่วนตัว buildfcnetwork () {// เพิ่มเลเยอร์เครือข่ายไปยังเครือข่ายอินพุตเลย์เลอร์ layer1 = new InputLayer (เครือข่าย, blobparams ใหม่ (network.getBatch (), 1,28,28)); network.addlayer (layer1); FullConnectionLayer Layer2 = ใหม่ FullConnectionLayer (เครือข่าย, blobparams ใหม่ (network.getBatch (), 784,1,1)); layer2.SetActivationFunc (ใหม่ reluactivationFunc ()); Network.addlayer (Layer2); FullConnectionLayer Layer3 = ใหม่ FullConnectionLayer (เครือข่าย, blobparams ใหม่ (network.getBatch (), 100,1,1)); Layer3.SetActivationFunc (ใหม่ ReluactivationFunc ()); network.addlayer (layer3); FullConnectionLayer Layer4 = ใหม่ FullConnectionLayer (เครือข่าย, blobparams ใหม่ (network.getBatch (), 30,1,1)); layer4.SetActivationFunc (SigmodactivationFunc () ใหม่); network.addlayer (layer4); FullConnectionLayer Layer5 = ใหม่ FullConnectionLayer (เครือข่าย, blobparams ใหม่ (network.getBatch (), 10,1,1)); Layer5.SetActivationFunc (ใหม่ ReluactivationFunc ()); network.addlayer (layer5); softmaxlayer sflayer = softmaxlayer ใหม่ (เครือข่าย, blobparams ใหม่ (network.getBatch (), 10,1,1)); network.addlayer (sflayer); -ดังที่แสดงในรหัสข้างต้นแต่ละเลเยอร์ต้องการเครือข่ายซึ่งเป็นอินสแตนซ์ของเครือข่าย เครือข่ายเป็นผู้ดูแลระบบทั่วโลกและผู้มอบหมายทรัพยากร ด้วยการอ้างอิงของเครือข่ายเราสามารถรับข้อมูลเอาต์พุตข้อผิดพลาดเอาต์พุต ฯลฯ ของแต่ละเลเยอร์ได้อย่างง่ายดาย นอกจากนี้แต่ละเลเยอร์ต้องการพารามิเตอร์ที่ระบุขนาดของบล็อกข้อมูลเอาต์พุตของเลเยอร์ปัจจุบันซึ่งจะบอกเลเยอร์ที่แน่นอนว่าคุณต้องการข้อมูลเท่าใดในการส่งออก ตัวอย่างเช่นเลเยอร์สุดท้ายของเครือข่ายประสาทคือ softmaxlayer ซึ่งต้องมีการส่งออกหมายเลขใด หมายเลขนี้แสดงโดยเวกเตอร์ที่มีความยาว 10 เช่นหมายเลข 7 ดังนั้น softmaxlayer ควรส่งออกค่าขององค์ประกอบที่ 8 เป็น 1 และค่าขององค์ประกอบอื่น ๆ เป็น 0 ชั้น convolution และชั้นการรวมต้องการพารามิเตอร์มากขึ้นเพราะทั้งคู่มีเคอร์เนล สำหรับเลเยอร์ Convolution มันถูกเรียกว่าเคอร์เนล convolution การก้าวย่างของแต่ละทิศทางของเลเยอร์ convolution คือ 1 ซึ่งยังคงเป็นที่ว่างสำหรับการปรับปรุง สำหรับเลเยอร์การรวมตัวกันนอกเหนือจากการผ่านพารามิเตอร์ของแกนการรวมคุณต้องผ่านขั้นตอนแนวนอนและแนวตั้งซึ่งเป็นสิ่งจำเป็น
การฝึกอบรมและการทดสอบ
หลังจากสร้างเครือข่ายประสาทคุณต้องเรียกเมธอดเครือข่าย PREPARE () ซึ่งจะสร้างบล็อกข้อมูลเอาต์พุตและบล็อกข้อมูลข้อผิดพลาดตามพารามิเตอร์ข้อมูลของแต่ละเลเยอร์ ดังนั้นการเรียกใช้วิธีนี้จึงเป็นสิ่งจำเป็น
โมฆะสาธารณะรถไฟสาธารณะ (รายการ <igitimage> imglist, int epoes) {system.out.println ("เริ่มรถไฟ"); int batch = network.getBatch (); double loclalr = optimizer.getLr (); สำหรับ (int e = 0; e <epoes; e ++) {collections.shuffle (imglist); สำหรับ (int i = 0; i <imglist.size ()-batch; i+= batch) {list <blob> inputandlabel = buildblobbyimageList (imglist, i, batch, 1,28,28); double lossvalue = network.train (inputandlabel.get (0), inputandlabel.get (1)); if (i> batch && i/batch%50 == 0) {system.out.print ("epoe:"+e+"lossvalue:"+lossvalue+""+"lr:"+optimizer.getlr ()+""); testinner (inputandlabel.get (0), inputandlabel.get (1)); }} if (loclalr> 0.001) {loclalr*= 0.8; optimizer.setlr (loclalr); }}} การทดสอบโมฆะสาธารณะ (รายการ <gatimage> imglist) {system.out.println ("เริ่มทดสอบ"); int batch = network.getBatch (); int credentCount = 0; int i = 0; สำหรับ (i = 0; i <imglist.size ()-batch; i+= batch) {list <blob> inputandlabel = buildblobbyimageList (imglist, i, batch, 1,28,28); blob output = network.predict (inputandlabel.get (0)); int [] caloutlabels = getBatchOutputLabel (output.getData ()); int [] realLabels = getBatchOutputLabel (inputandlabel.get (1) .getData ()); สำหรับ (int kk = 0; kk <caloutlabels.length; kk ++) {if (caloutlabels [kk] == reallabels [kk]) {redigncount ++; }}} double accuracy = redlectCount/(1.0*i+batch); System.out.println ("ความแม่นยำในการทดสอบคือ"+ความแม่นยำ+"CredentCount"+CORDITCOUNT); -ดังที่ได้กล่าวไว้ข้างต้นคุณสามารถฝึกอบรมโดยโทรไปที่รถไฟของเครือข่ายและคุณสามารถทดสอบได้โดยเรียกวิธีการทำนายของเครือข่าย
บันทึกและโหลดพารามิเตอร์
โมฆะสาธารณะ savemodel (ชื่อสตริง) {network.saveModel (ชื่อ); } โมฆะสาธารณะ loadModel (ชื่อสตริง) {network = net network (); Network.loadModel (ชื่อ); Network.Prepare (); -การเรียก SaveModel และ LoadModel ของเครือข่ายสามารถบันทึกและโหลดพารามิเตอร์ตามลำดับ คุณจะต้องผ่านชื่อไฟล์เท่านั้น เมื่อเราสร้างเครือข่ายประสาทผ่านพารามิเตอร์ที่บันทึกไว้เราจำเป็นต้องใช้เครือข่ายใหม่ก่อนจากนั้นเรียกโหลดโมเดลของเครือข่ายนี้เพื่อโหลดพารามิเตอร์ที่บันทึกไว้แล้วอย่าลืมเรียกใช้วิธีการเตรียมการเพื่อสร้างบล็อกข้อมูลเอาต์พุตและบล็อกข้อมูลข้อผิดพลาดสำหรับแต่ละเลเยอร์
สถานะความสำเร็จในปัจจุบันและแผนการในอนาคต
ปัจจุบันเลเยอร์ที่นำมาใช้รวมถึง: การเชื่อมต่อเต็มรูปแบบการ convolution, ชั้นรวมสูงสุด, เลเยอร์การรวมกลุ่มโดยเฉลี่ยและเลเยอร์ Softmax ฟังก์ชั่นการเปิดใช้งานที่ใช้คือ: Sigmod, Tanh, Relu
ฟังก์ชั่นการสูญเสียที่นำไปใช้คือ: Cross Entropy, Log-Likeliight การเพิ่มประสิทธิภาพที่ใช้คือ: SGD พารามิเตอร์สามารถบันทึกและโหลดได้แล้ว ถัดไปจะมีการเพิ่มเลเยอร์การออกกลางคันและจะเพิ่มตัวอย่างของ CIFAR-10
นอกจากนี้ฉันจะเขียนบทความบางอย่างเพื่อตรวจสอบความคิดและคำถามของฉันในระหว่างกระบวนการเขียน Cupcnn เพื่ออ้างอิงโดยผู้เริ่มต้น กรุณาใช้ทางอ้อม ผู้ที่สนใจสามารถให้ความสนใจต่อไป ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น