一、前言
  
  计算机视觉长久以来没有大的突破,卷积神经网络的出现,给这一领域带来了突破,本篇博客,将通过具体的实例来看看卷积神经网络在图像识别上的应用。
  
  导读
  
  1、问题描述
  
  2、解决问题的思路
  
  3、用DL4J进行实现
  
  二、问题
  
  有如下一组验证码的图片,图片大小为60*160,验证码由5个数字组成,数字的范围为0到9,并且每个验证码图片上都加上了干扰背景,图片的文件名,表示验证码上的数字,样本图片如下:
  
  穷举每张图片的可能性几乎不可能,所以传统的程序思路不可能解这个问题,那么必须让计算机通过自我学习,获取识别验证码的能力。先让计算机看大量的验证码的图片,并告诉计算机这些图片的结果,让计算机自我学习,慢慢地计算机就学会了识别验证码。
  
  三、解决思路
  
  1、特征
  
  每个数字的形状各异,各自特征明显,这里的特征实际上指的是线条的走向、弯曲程度等等形状上的不同表征,那么对于侦测图形上的形状,卷积神经网络加上Relu和Max采样,可以很精确的做到这一点,本质原因在于,把卷积核拉直了看,本质上所做的事情就算向量的点积运算,求一个向量在另一个向量上的投影。对于卷积神经网络的原理可以看看《有趣的卷积神经网络》
  
  2、网络结构设计
  
  对于每张图片而言,有5个数字作为输出结果,那么得设计一个有5个output的深度神经网络,首先用多个卷积核+Max采样层的结构来抽取明显特征,最后获得的特征经过两个全连接层逼近,这里加全连接层有两个目的,第一:经过sigmoid函数把值压缩到0到1之间,便于softmax计算,第二,加上全连接层可以更加抽象特征,让函数的逼近更加容易。最终的网络结构如下:
  
  3、张量表示
  
  对于Label的表示用one-hot来表示,这样可以很好的配合softmax,下图展示了从0到9的数字表示,沿着行的方向,由上而下,分别表示0到9
  
  对于图片上的像素点,值域在0到255之间,图片如果是彩色,那么实际上会有三个通道,这里都是黑白色,所以,只有一个通道,取图片上真实像素点的值,除以255进行归一化即可。
  
  四、代码实现
  
  1、网络结构
  
  public static ComputationGraph createModel() {
  
  ComputationGraphConfiguration config = new NeuralNetConfiguration.Builder()
  
  .seed(seed)
  
  .gradientNormalization(GradientNormalization.RenormalizeL2PerLayer)
  
  .l2(1e-3)
  
  .updater(new Adam(1e-3))
  
  .weightInit( WeightInit.XAVIER_UNIFORM)
  
  .graphBuilder()
  
  .addInputs("trainFeatures")
  
  .setInputTypes(InputType.convolutional(60, 160, 1))
  
  .setOutputs("out1", "out2", "out3", "out4", "out5", "out6")
  
  .addLayer("cnn1", new ConvolutionLayer.Builder(new int[]{5, 5}, new int[]{1, 1}, new int[]{0, 0})
  
  .nIn(1).nOut(48).activation( Activation.RELU).build(), "trainFeatures")
  
  .addLayer("maxpool1", new SubsamplingLayer.Builder(PoolingType.MAX, new int[]{2,2}, new int[]{2, 2}, new int[]{0, 0})
  
  .build(), "cnn1")
  
  .addLayer("cnn2", new ConvolutionLayer.Builder(new int[]{5, 5}, new int[]{1, 1}, new int[]{0, 0})
  
  .nOut(64).activation( Activation.RELU).build(), "maxpool1")
  
  .addLayer("maxpool2", new SubsamplingLayer.Builder(PoolingType.MAX, new int[]{2,1}, new int[]{2, 1}, new int[]{0, 0})
  
  .build(), "cnn2")
  
  .addLayer("cnn3", new ConvolutionLayer.Builder(new int[]{3, 3}, new int[]{1, 1}, new int[]{0, 0})
  
  .nOut(128).activation( Activation.RELU).build(), "maxpool2")
  
  .addLayer("maxpool3", new SubsamplingLayer.Builder(PoolingType.MAX, new int[]{2,2}, new int[]{2, 2}, new int[]{0, 0})
  
  .build(), "cnn3")
  
  .addLayer("cnn4", new ConvolutionLayer.Builder(new int[]{4, 4}, new int[]{1, 1}, new int[]{0, 0})
  
  .nOut(256).activation( Activation.RELU).build(), "maxpool3")
  
  .addLayer("maxpool4", new SubsamplingLayer.Builder(PoolingType.MAX, new int[]{2,2}, new int[]{2, 2}, new int[]{0, 0})
  
  .build(), "cnn4")
  
  .addLayer("ffn0", new DenseLayer.Builder().nOut(3072)
  
  .build(), "maxpool4")
  
  .addLayer("ffn1", new DenseLayer.Builder().nOut(3072)
  
  .build(), "ffn0")
  
  .addLayer("out1", new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
  
  .nOut(10).activation(Activation.SOFTMAX).build(), "ffn1")
  
  .addLayer("out2", new www.gcyl158.com OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
  
  .nOut(10).activation(Activation.SOFTMAX).build(), "ffn1")
  
  .addLayer("out3", www.gcyl152.com new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
  
  .nOut(10).activation(Activation.SOFTMAX).build(), "ffn1")
  
  .addLayer("out4",www.mhylpt.com new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
  
  .nOut(10).activation(Activation.SOFTMAX).build(www.feifanyule.cn), "ffn1")
  
  .addLayer("out5", new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
  
  .nOut(10).activation(Activation.SOFTMAX).build(), "ffn1")
  
  .addLayer("out6", new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
  
  .nOut(10).activation(Activation.SOFTMAX).build(), "ffn1")
  
  .pretrain(false).backprop(true)
  
  .build();
  
  ComputationGraph model = new ComputationGraph(config);
  
  model.init();
  
  return model;
  
  }
  
  2、训练集构建
  
  public MultiDataSet convertDataSet(int num) throws Exception {
  
  int batchNumCount = 0;
  
  INDArray[] featuresMask = null;
  
  INDArray[] labelMask = null;
  
  List<MultiDataSet> multiDataSets = new ArrayList<>();
  
  while (batchNumCount != num && fileIterator.hasNext()) {
  
  File image = fileIterator.next();
  
  String imageName = image.getName().substring(0,image.getName().lastIndexOf('.'));
  
  String[] imageNames = imageName.split("");
  
  INDArray feature = asMatrix(image);
  
  INDArray[] features = new INDArray[]{feature};
  
  INDArray[] labels = new INDArray[6];
  
  Nd4j.getAffinityManager().ensureLocation(feature, AffinityManager.Location.DEVICE);
  
  if (imageName.length() < 6) {
  
  imageName = imageName + "0";
  
  imageNames = imageName.split("");
  
  }
  
  for (int i = 0; i < imageNames.length; i ++) {
  
  int digit = Integer.parseInt(imageNames[i]);
  
  labels[i] = Nd4j.zeros(1, 10).putScalar(new int[]{0, digit}, 1);
  
  }
  
  feature = feature.muli(1.0/255.0);
  
  multiDataSets.add(new MultiDataSet(features, labels, featuresMask, labelMask));
  
  batchNumCount ++;
  
  }
  
  MultiDataSet result = MultiDataSet.merge(multiDataSets);
  
  return result;
  
  }
  
  五、后记
  
  用deeplearning4j构建一个深度神经网络,几乎没有多余的代码,非常优雅就可以解一个复杂的图像识别问题,对于上述代码有几点说明:
  
  1、对于DenseLayer层,这里没有设置网络输入的size,实际上在dl4j内部已经做了这个set操作
  
  2、对于梯度更新优化,这里选用Adam,Adam融合了动量和自适应learningRate两方面的因素,通常会有更好的效果
  
  3、损失函数用的类Log函数,和交叉熵有相同的效果
  
  4、模型训练好可以使用 ModelSerializer.writeModel(model, modelPath, true)来保存网络结构,就可以用于图像识别了
  
  完整的代码,可以查看deeplearning4j的example

deeplearning4j——卷积神经网络对验证码进行识别的更多相关文章

  1. 基于MTCNN多任务级联卷积神经网络进行的人脸识别 世纪晟人脸检测

    神经网络和深度学习目前为处理图像识别的许多问题提供了最佳解决方案,而基于MTCNN(多任务级联卷积神经网络)的人脸检测算法也解决了传统算法对环境要求高.人脸要求高.检测耗时高的弊端. 基于MTCNN多 ...

  2. 验证码进阶(TensorFlow--基于卷积神经网络的验证码识别)

    本人的第一个深度学习实战项目,参考了网络上诸多牛人的代码,在此谢过,因时间久已,不记出处,就不一一列出,罪过罪过. 我的数据集是我用脚本在网页上扒的,标签是用之前写的验证码识别方法打的.大概用了400 ...

  3. TensorFlow 卷积神经网络手写数字识别数据集介绍

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 手写数字识别 接下来将会以 MNIST 数据集为例,使用卷积层和池 ...

  4. tensorflow卷积神经网络与手写字识别

    1.知识点 """ 基础知识: 1.神经网络(neural networks)的基本组成包括输入层.隐藏层.输出层.而卷积神经网络的特点在于隐藏层分为卷积层和池化层(po ...

  5. 图片训练:使用卷积神经网络(CNN)识别手写数字

    这篇文章中,我们将使用CNN构建一个Tensorflow.js模型来分辨手写的数字.首先,我们通过使之“查看”数以千计的数字图片以及他们对应的标识来训练分辨器.然后我们再通过此模型从未“见到”过的测试 ...

  6. 跟我学算法- tensorflow 卷积神经网络训练验证码

    使用captcha.image.Image 生成随机验证码,随机生成的验证码为0到9的数字,验证码有4位数字组成,这是一个自己生成验证码,自己不断训练的模型 使用三层卷积层,三层池化层,二层全连接层来 ...

  7. 吴裕雄--天生自然 Tensorflow卷积神经网络:花朵图片识别

    import os import numpy as np import matplotlib.pyplot as plt from PIL import Image, ImageChops from ...

  8. 深度学习-使用cuda加速卷积神经网络-手写数字识别准确率99.7%

    源码和运行结果 cuda:https://github.com/zhxfl/CUDA-CNN C语言版本参考自:http://eric-yuan.me/ 针对著名手写数字识别的库mnist,准确率是9 ...

  9. 深度学习项目——基于卷积神经网络(CNN)的人脸在线识别系统

    基于卷积神经网络(CNN)的人脸在线识别系统 本设计研究人脸识别技术,基于卷积神经网络构建了一套人脸在线检测识别系统,系统将由以下几个部分构成: 制作人脸数据集.CNN神经网络模型训练.人脸检测.人脸 ...

随机推荐

  1. ReactiveCocoa实战: 模仿 "花瓣",重写 LeanCloud Rest Api的iOS REST Client.

    这一次我们将要讨论的是移动开发中比较重要的一环--网络请求的封装.鉴于个人经验有限,本文将在一定程度上参考 基于AFNetworking2.0和ReactiveCocoa2.1的iOS REST Cl ...

  2. 第34-3题:LeetCode437. Path Sum III

    题目 二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数. 示例: root = [10,5,-3,3,2,null,11,3,-2,null,1], sum ...

  3. Eclipse编写JavaFX环境配置

    配置eclipse用于写JavaFX:1.确定JRE中有jfxrt.jar---jdk82.选中项目-->属性-->Java Build Path3.Libraries-->jre包 ...

  4. WIN10使用安装包安装Mysql5.6+JDBC

    很多教程教的是安装绿色版mysql或者是安装zip版的mysql,没什么不好,各有千秋,今天要教大家的是使用mysql-installer-community-5.6.43.0.msi安装mysql5 ...

  5. 访问远程mysql数据库,出现报错,显示“1130 - Host'xxx.xxx.xxx.xxx' is not allowed to connect to this MySQL server“

    在使用Navicat for MySQl访问远程mysql数据库,出现报错,显示“1130 - Host'xxx.xxx.xxx.xxx' is not allowed to connect to t ...

  6. html5中的progress兼容ie,制作进度条样式

    html5新增的progress标签用处很大,它可以制作进度条,不用像以前那样用css来制作进度条! 一.progress使用方法 progress标签很好使用,他有两个属性,value和max,va ...

  7. PyCharm 的安装与入门操作

    PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试.语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本控制. ...

  8. kivy学习二:做一个查询所在地区身份证前6位的小软件

    经过半个月的尝试,终于成功,记录下来备查! 做完之后发现有很多的问题没有解决,请大佬多批评指教! 强烈建议:学习KIVY的查看官方文档 需要用的知识: 1.字典的相关知识 2.kivy的下拉列表(Dr ...

  9. mysql8.0 忘记root密码

    先打开一个cmd:net stop mysql //关闭mysql服务mysqld --shared-memory --skip-grant-tables//跳过登录密码在不关闭第一个CMD的情况下打 ...

  10. Numpy基础数据结构 python

    Numpy基础数据结构 NumPy数组是一个多维数组对象,称为ndarray.其由两部分组成: 实际的数据 描述这些数据的元数据 1.一维数组 import numpy as np ar = np.a ...