머리말
머신 러닝에서 Convolutional Neural Network는 이미지 인식에 성공적으로 적용된 깊은 피드 포워드 인공 신경망입니다. 현재, 많은 번호판 번호 인식, 얼굴 인식 등은 Convolutional Neural Networks를 사용합니다. Convolutional Neural Networks는 이미지 인식에서 큰 성공을 거두었다고 말할 수 있습니다. Caffe, Tensorflow, Torch 등과 같은 많은 오픈 소스 딥 러닝 프레임 워크가 있습니다. 이러한 딥 러닝 프레임 워크에는 완전한 컨볼 루션 신경망의 구현이 포함됩니다. 그렇다면 왜 우리는 여전히 컨볼 루션 신경 네트워크를 스스로 작성해야합니까? 이 오픈 소스 딥 러닝 프레임 워크를 직접 사용하는 것이 좋습니다.이 프레임 워크는 빠르고 다루기 쉽고 성능이 좋고 버그가 거의 없습니다. 그렇습니다. 컨볼 루션 신경망을 사용하여 일부 응용 프로그램을 수행하고 작업 원칙에 신경 쓰지 않으면 Convolutional Neural Networks를 작성하기 위해 열심히 노력할 필요가 없습니다. 그러나 컨볼 루션 신경 네트워크의 작동 원리를 완전히 익히고 싶다면 고대인들은 다음과 같이 말했습니다. 따라서 컨볼 루션 신경망을 직접 구현하여 이해를 심화시켜야합니다.
cupcnn은 무엇입니까?
Cupcnn은 Java로 작성된 Convolutional Neural Network입니다. 작업 외에도 컨볼 루션 신경 네트워크에 대한 이해를 심화시키기 위해 그것을 깨달았습니다. 충분히 간단하고 잘 수행하여 초보자가 참조하는 데 매우 적합합니다. 소스 코드는 github : cupcnn에서 다운로드 할 수 있습니다
프로토콜의 한계에 대해 걱정할 필요가 없습니다. 당신은 그것을 사용하여 무엇이든하고 임의로 수정할 수 있습니다. 그것이 당신을 도울 수 있다면, 나는 그것이 당신에게 별을 줄 수 있기를 바랍니다! ! !
^-^^-^^-^^-^
디자인 아이디어
초보자가 학습을 돕기에 충분히 간단한 신경망이기를 바랍니다. 그래서 나는 동시 가속화를 구현하지 않았으므로 코드의 입문 특성을 보장합니다. 설계 할 때 Convolutional Neural Network를 네트워크 (Layer Blob Loss Active)의 4 가지 모듈로 나누었습니다.이 모듈은 패키지 이름에서 볼 수 있습니다. 레이어, 손실 및 활성 모두에는 모두 기본 클래스가 있으며 전체 신경망의 프로그래밍은 기본 클래스를 향합니다. 네트워크는이 네 가지 모듈을 통합, 좌표 및 발송 리소스를 통합하는 센터입니다. 각 계층은 네트워크의 인스턴스가 있으므로 각 계층의 출력, Diff 등과 같은 네트워크를 통해 다양한 데이터를 쉽게 얻을 수 있습니다.
설계 블록 다이어그램은 다음과 같습니다.
Java의 경우 매개 변수를 저장하는 것은 매우 간단합니다. 직렬화 가능한 인터페이스를 구현하면 매개 변수의 직렬화 및 사막화가 빠르게 구현 될 수 있습니다. CUPCNN은 데이터 디렉토리의 블로브 및 블로브 파람에 대한 직렬화 가능한 인터페이스 만 구현되며 모든 매개 변수는이 두 가지에 의해 구현됩니다.
현재 성능
완전히 연결된 신경망
현재 MNIST 데이터 세트에서 완전히 연결된 신경망 (전체 연결 (100) + 전체 연결 (30) + 전체 연결 (10) + SoftMax)는 30 개의 EPOE로 훈련을받으며 정확도는 96.76입니다.
컨볼 루션 신경 네트워크
Convolutional Neural Network (6 특징) + 최대 풀링 + 컨볼 루션 (6 특징) + 전체 연결 (512) + 전체 연결 (30) + 전체 연결 (10) + SoftMax) 학습 속도가 0.2, 30 에피소가 훈련되면 정확도 속도는 97.79입니다. 추가 매개 변수 튜닝 후에는 충분한 훈련에서 정확도가 더 높을 수 있다고 생각합니다.
Convolutional Neural Network의 교육 스냅 샷은 다음과 같습니다.
열차를 시작하십시오
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.2563771032599674 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.2754066024803088 LR : 0.160000000000000000003 정확도는 0.96입니다
EPOE : 1 LossValue : 0.30256420975577103 LR : 0.160000000000000000003 정확도는 0.96입니다
EPOE : 1 LossValue : 0.1814964862985948 LR : 0.16000000000000000003 정확도는 0.99입니다
EPOE : 1 LossValue : 0.177239938748327 LR : 0.160000000000000000003 정확도는 0.96입니다
EPOE : 1 LOSSVALUE : 0.15041993009777443 LR : 0.160000000000000000003 정확도는 0.98입니다
EPOE : 1 LOSSVALUE : 0.10759545752665524 LR : 0.1600000000000000000003 정확도는 1.0입니다
cupcnn의 사용
현재 Cupcnn은 MNIST 데이터 세트에서 테스트를 구현합니다. SRC/Test에서 MnistTest는 기본 기능의 입구이며 특정 신경망은 Mnistnetwork 클래스에 구축됩니다. Mnistnetwork 클래스에서 BuildConvNetwork 및 BuildFCnetwork는 각각 컨볼 루션 신경망의 구성과 완전히 연결된 신경망의 구성을 구현합니다. Java의 좋은 크로스 플랫폼 속성 덕분에 Cupcnn의 소스 코드를 다운로드 한 후 Eclipse를 사용하여 프로젝트를 열고 직접 실행 한 다음 MNIST 데이터 세트에서 교육 및 테스트를 시작할 수 있어야합니다.
신경망 구축
public void buildNetwork () {// 먼저 신경망 객체를 빌드하고 매개 변수를 설정하여 네트워크 = 새로운 네트워크 (); Network.setbatch (100); Network.setLoss (new loglikeLoss ()); //network.setloss(New CrossentRopyloss ()); Optimizer = New SGDoptimizer (0.2); Network.setOptimizer (Optimizer); // buildfcnetwork (); BuildConvNetwork (); Network.prepare (); } setBatch () 함수는 배치에있는 사진 수를 설정합니다.
setLoss ()는 사용할 손실 함수를 설정합니다. Cupcnn은 크로스 엔트로피 손실 함수 및 로그-원성 손실 함수를 구현합니다.
setoptimizer ()를 사용하여 Optimizer를 설정해야합니다. Cupcnn은 SGD Optimizer 만 구현합니다. 더 나은 옵티마이저를 구현하고 Cupcnn에 기꺼이 제출하려는 경우 깊이 환영합니다.
완전히 연결된 신경망을 구축하십시오
private void buildfcnetwork () {// 네트워크에 네트워크 계층 추가 inputlayer layer1 = new inputlayer (네트워크, 새로운 blobparams (네트워크.getBatch (), 1,28,28)); Network.addlayer (Layer1); FullConnectionLayer Layer2 = New FullConnectionLayer (Network, New Blobparams (Network.getBatch (), 784,1,1); layer2.setActivationFunc (New ReluActivationFunc ()); Network.addlayer (Layer2); FullConnectionLayer Layer3 = New FullConnectionLayer (Network, New Blobparams (Network.getBatch (), 100,1,1); layer3.setActivationFunc (new ReluActivationFunc ()); Network.addlayer (Layer3); FullConnectionLayer Layer4 = New FullConnectionLayer (Network, New Blobparams (Network.getBatch (), 30,1,1); layer4.setActivationFunc (new sigModActivationFunc ()); Network.addlayer (Layer4); FullConnectionLayer Layer5 = New FullConnectionLayer (Network, New Blobparams (Network.getBatch (), 10,1,1); layer5.setActivationFunc (New ReluActivationFunc ()); Network.addlayer (Layer5); SoftMaxlayer Sflayer = New SoftMaxlayer (Network, New Blobparams (Network.getBatch (), 10,1,1); Network.addlayer (sflayer); }위 코드에 표시된 것처럼 각 계층에는 네트워크가 필요합니다. 이는 네트워크의 인스턴스입니다. 네트워크는 글로벌 관리자이자 리소스 파견자입니다. 네트워크를 참조하면 각 레이어의 출력 데이터, 출력 오류 등을 쉽게 얻을 수 있습니다. 또한 각 계층에는 현재 레이어의 출력 데이터 블록의 크기를 지정하는 매개 변수가 필요하며, 이는 출력해야 할 데이터의 양을 알려줍니다. 예를 들어, 신경망의 마지막 계층은 SoftMaxlayer이며 숫자는 출력해야합니다. 이 숫자는 숫자 7과 같은 길이 10의 벡터로 표시되므로 SoftMaxlayer는 8 번째 요소의 값을 1으로 출력하고 다른 요소의 값은 0이어야합니다. Convolution 레이어와 풀링 레이어는 모두 커널을 갖기 때문에 더 많은 매개 변수가 필요합니다. 컨볼 루션 레이어의 경우 컨볼 루션 커널이라고합니다. 컨볼 루션 층의 각 방향의 보폭은 1이며, 이는 여전히 개선의 여지입니다. 풀링 층의 경우 풀링 코어의 매개 변수를 전달하는 것 외에도 수평 및 수직 단계를 통과해야합니다.
훈련 및 테스트
신경망을 구축 한 후에는 네트워크를 호출해야하며 각 계층의 데이터 매개 변수를 기반으로 출력 데이터 블록 및 오류 데이터 블록을 생성합니다. 따라서이 방법에 대한 호출이 필요합니다.
공개 무효 열차 (목록 <Digitimage> imglist, int epoes) {System.out.println ( "시작 열차"); int batch = network.getBatch (); Double loclalr = Optimizer.getLr (); for (int e = 0; e <epoes; e ++) {collections.shuffle (imglist); for (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 :"+intimizer.getlr ()+""); testinner (inputandlabel.get (0), inputandlabel.get (1)); }} if (loclalr> 0.001) {loclalr*= 0.8; Optimizer.setlr (loclalr); }}} public void test (list <DigitImage> imglist) {System.out.println ( "시작 테스트"); int batch = network.getBatch (); int corencount = 0; int i = 0; for (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 [] leallabels = getBatchOutputLabel (inputandLabel.get (1) .getData ()); for (int kk = 0; kk <caloutlabels.length; kk ++) {if (caloutlabels [kk] == leallabels [kk]) {맞춤형 ++; }}} double 정확도 = 맞춤/(1.0*i+batch); System.out.println ( "테스트 정확도는"+accuracy+"count"+ArmentCount입니다); }위에서 언급했듯이 네트워크의 열차에 전화하여 훈련 할 수 있으며 네트워크의 예측 방법을 호출하여 테스트 할 수 있습니다.
매개 변수를 저장하고로드합니다
public void Savemodel (문자열 이름) {Network.saveModel (이름); } public void loadModel (문자열 이름) {Network = new Network (); Network.loadModel (이름); Network.prepare (); }네트워크의 Savemodel 및 LoadModel을 호출하면 각각 매개 변수를 저장하고로드 할 수 있습니다. 파일 이름 만 전달하면됩니다. 저장된 매개 변수를 통해 신경 네트워크를 만들 때 먼저 새 네트워크를 새로운 네트워크로 만든 다음이 네트워크의로드 모델을 호출하여 저장된 매개 변수를로드 한 다음 각 레이어에 대한 출력 데이터 블록 및 오류 데이터 블록을 작성하는 준비 방법을 호출하는 것을 잊지 마십시오.
현재 완료 상태 및 향후 계획
현재 구현 된 계층에는 전체 연결, 컨 커브, 최대 풀링 레이어, 평균 풀링 레이어 및 SoftMax 레이어가 포함됩니다. 구현 된 활성화 함수는 Sigmod, Tanh, Relu입니다.
구현 된 손실 함수는 다음과 같습니다. 교차 엔트로피, 로그-일성. 구현 된 최적화는 SGD입니다. 매개 변수는 이미 저장하고로드 할 수 있습니다. 다음으로, 드롭 아웃 계층이 추가되고 Cifar-10의 예가 추가됩니다.
또한 초보자가 참조하기 위해 CUPCNN을 작성하는 과정에서 내 생각과 질문을 검토하기 위해 몇 가지 기사를 작성할 것입니다. 우회석을 가져 가십시오. 관심있는 사람들은 계속주의를 기울일 수 있습니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.