30岁学网站开发,网站建设管理员,wordpress如何给头部加个搜索,网站服务器错误文章目录
背景 物体识别简介 自动驾驶 淘宝京东使用物体识别技术公司业务需求 深度学习简介 深度学习的位置 深度学习概念深度学习优势 深度学习基础知识 感知机 激活函数多层感知机卷积神经网络 卷积层 * 池化层 模型训练 前向传播 * 反向传播与参数优化 深度学习服务端框…文章目录
背景 物体识别简介 自动驾驶 淘宝京东使用物体识别技术公司业务需求 深度学习简介 深度学习的位置 深度学习概念深度学习优势 深度学习基础知识 感知机 激活函数多层感知机卷积神经网络 卷积层 * 池化层 模型训练 前向传播 * 反向传播与参数优化 深度学习服务端框架 tensorFlow keraspytorchCaffe/Caffe2.0 caffe框架 为何选择caffe caffe环境搭建caffe基础 数据集 模块概要图 solverprototxt 执行者配置 神经网络可视化 caffe中的基础概念 blobs layer 神经层 net 神经网络 * forward/backward 前向传播/反向传播
* caffemnist数据集lenet
* caffecifar10caffenet
* caffecifar10mobilenet
* caffevoc2012vggfinetunessd物体检测模型 轻量级客户端框架-ncnn ncnn简介 ncnncaffemobilenet实战 ncnn环境搭建 * 模型转化caffe格式- ncnn格式 源码解析 文件目录 执行流程 重点代码 效果展示 其他工程的效果图 相关学习资料 教学视频 开源项目参考博客
背景
产品以后的发展需要添加更多科技元素如下
人脸识别物体识别场景识别
以下以物体识别为重点使用到了深度学习技术以下我们将逐一展开。 本次分享的重点是深度学习caffencnn其余部分将简单的进行带过。 注本文主要以有监督的学习为主分类和回归问题无监督学习不作为分享范围。
物体识别简介
物体识别俗称Object detection是近年来兴起的技术这也是人工智能的首要目标之一。这是一种完全模拟人眼识别的技术即使在物体旋转、变色、部分展示等的情况下同样具备优秀的识别效果。 人工智能目标是
让机器看世界让机器听世界让机器独立思考
自动驾驶
在驾驶领域中引入物体识别技术将大大降低交通事故发生的概率。
淘宝京东使用物体识别技术 公司业务需求
近期产品提出物体识别的相应需求能识别出家长和老师发送图片中的物体来开展相应的业务。以下是一张海边游玩的照片。
深度学习简介
深度学习的位置 深度学习分别属于人工智能和机器学习的一部分。与深度学习相并行的另外一种机器学习方法被称之为传统的机器学习例如svm、逻辑回归。
深度学习概念 人工神经网络是一个分层的有向图第一层输入节点接受输入的信息也称为输入层。来自这些点的数值按照它们输出的弧的权重wn进行线性加权得到G然后再做一次函数变化fG赋给第二层的节点Y。 第二层的节点照此将数值向后传递直到第三层节点如此一层层传递直到最后一层最后一层又被称为输出层。在模式分类时一个模式图像、语音、文字等的特征值比如坐标从输入层开始按照上面的规则和公式一层层向后传递。最后在输出层哪个节点的数值最大输入的模式就被分在了哪一类。 ------------------引自《数学之美—Google大脑和人工神经网络》 深度学习优势
神经网络与传统的机器学习相比
能支持更复杂的分类边界非线性表征更加丰富准确率会随着数据集的增加而突破传统学习的瓶颈与svm相比在大数据集上收敛的更快轻量级神经网络具备高性能的前向传播方便部署到移动设备深度学习基础知识
参考https://www.cnblogs.com/wj-1314/p/9754072.html
感知机
可以简单的理解为是线性分类。假设训练数据集是线性可分的感知机学习的目标是求得一个能够将训练数据集正实例点和负实例点完全正确分开的分离超平面。 感知机重点包含以下两点
线性加权依靠损失函数进行权重优化
数学公式略将在其他博文中进行阐述。
感知机的缺陷只支持线性分类对于简单的异或问题也不能进行分类。以下是异或问题中最简单的情况可以看到无论哪一条直线都不能进行完美的分割。
激活函数
针对于感知机不能表达非线性的问题激活函数诞生了。 在人工神经网络中规定神经元函数只能对输入变量指向他的节点的值线性组合后的结果进行一次非线性变换。 这次非线性变化成为“激活函数” ----《数学之美》 为了神经网络的通用性每一层的非线性变化都选择同一类函数。 激活函数包括
relusigmoidtanh等等
激活函数参考博客https://blog.csdn.net/tyhj_sf/article/details/79932893
多层感知机
多层感知机MLPMultilayer Perceptron也叫人工神经网络ANNArtificial Neural Network除了输入输出层它中间可以有多个隐层最简单的MLP只含一个隐层即三层的结构
输入层输入特征数据等加工或者没有加工过的原始数据隐含层隐含层可以很多resnet有128层的就是说的隐含层输出层输出最后的计算结果很多神经网络里面都把输出层定义为概率值
多层感知机等同于全连接层信息每向下传递一个神经元都会产生n*n的计算量计算量会随着输入的维度增大而变得非常恐怖
卷积神经网络 卷积神经网络是近年发展起来的并引起广泛重视的一种高效识别方法20世纪60年代Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性继而提出了卷积神经网络Convolutional Neural Networks-简称CNN 参考资料https://www.cnblogs.com/wj-1314/p/9754072.html
卷积的原理与人眼观察事物极其相似过程都是边缘 - 局部 - 整体。卷积神经网络的核心就是使用多个局部特征来影响分类结果。 全连接的计算量非常大。而且是以整体来计算没有进行有效的特征提取即使权重最终达到了收敛效果也不能很好的进行预测。 卷积神经网络则不同每次卷积完毕后传入下一层的数据大大降低了维度而且经过卷积获得了众多局部特征后面的层对这些特征数据进行训练将变得既简单又高效。
卷积层
简单来说卷积层用于特征提取。 根据卷积核的滑动获取到一个新的特征数据Convolved Feature。这个特征数据不是那么直观来看一下实物的效果。 针对于不同的通道rgb进行卷积后会得到边缘轮廓的图。
池化层
池化层用于降低参数而降低参数的方法当然是删除参数保留最有效的参数。
一般我们有最大池化和平均池化。
最大池化是现在使用最多的可以突出局部特征平均池化则考虑了所有参数而计算出了平均值
需要注意的是池化层一般放在卷积层后面。所以池化层池化的是卷积层的输出。
模型训练
本博客重点关注有监督的训练。在训练之前需要有一批标注好的数据即训练数据。为了能在训练过程中动态的观测模型的准确率同样也需要一批标注数据推荐为训练数据/测试数据比例为4/1
前向传播 前向传播即训练数据在神经网络里从输入层到输出层的方向传播一次最终得到输出层的输出结果即在每个分类的概率值。
反向传播与参数优化
用数据语言来表达假设C为一个成本函数Cost Function它表示根据人工神经网络的输出值分类结果概率和实际训练数据中的输出值之间的差距。现在训练人工神经网络的问题就变成了一个最优化的问题说的通俗点就是数学中的“找最大最小值”的问题。解决最优化为题的常用方法是梯度下降法Gradient Descent 注这里存在一个局部最优解的问题不过已经被证明在深度神经网络中即使收敛过程进入了局部最优最终结果也与全局最优没有明显差异。
深度学习服务端框架 tensorFlow
2015年11月谷歌Google出品基于Python和C编写。GitHub上最热谷歌搜索最多使用人数最多笔者也是其中之一大多数网上招聘工作描述中也提到了它。由于Google在深度学习领域的巨大影响力和强大的推广能力TensorFlow一经推出就获得了极大的关注并迅速成为如今用户最多的深度学习框架。2019年3月已发布最新的TensorFlow2.0 版本。
官方网站https://www.tensorflow.org/ 优点
自带tensorboard可视化工具能够让用户实时监控观察训练过程拥有大量的开发者有详细的说明文档、可查询资料多支持多GPU、分布式训练跨平台运行能力强具备不局限于深度学习的多种用途还有支持强化学习和其他算法的工具
缺点
频繁变动的接口。TensorFlow的接口一直处于快速迭代之中并且没有很好地考虑向后兼容性这导致现在许多开源代码已经无法在新版的TensorFlow上运行同时也间接导致了许多基于TensorFlow的第三方框架出现BUG接口设计过于晦涩难懂在设计TensorFlow时创造了图、会话、命名空间、PlaceHolder等诸多抽象概念对初学者来说较难上手运行明显比其他框架速度慢
keras
Keras 于2015年3月首次发布拥有“为人类而不是机器设计的API”得到Google的支持。它是一个用于快速构建深度学习原型的高层神经网络库由纯Python编写而成以TensorFlowCNTKTheano和MXNet为底层引擎提供简单易用的API接口能够极大地减少一般应用下用户的工作量。 如果你是深度学习的初学者想要快速入门建议从Keras开始。 官方网站https://keras.io
优点
更简洁更简单的API丰富的教程和可重复使用的代码更多的部署选项直接并且通过TensorFlow后端更简单的模型导出
缺点
过度封装导致丧失灵活性导致用户在新增操作或是获取底层的数据信息时过于困难初学者容易依赖于 Keras 的易使用性而忽略底层原理
pytorch
PyTorch于2016年10月发布是一款专注于直接处理数组表达式的低级API。 前身是 Torch一个基于 Lua 语言的深度学习库。Facebook 人工智能研究院对PyTorch提供了强力支持。 PyTorch 支持动态计算图为更具数学倾向的用户提供了更低层次的方法和更多的灵活性目前许多新发表的论文都采用PyTorch作为论文实现的工具成为学术研究的首选解决方案。
如果你是一名科研工作者倾向于理解你的模型真正在做什么那么就考虑选择PyTorch。
官方网站https://pytorch.org/
Caffe/Caffe2.0
Caffe的全称是Convolutional Architecture for Fast Feature Embedding它是一个清晰、高效的深度学习框架于2013年底由加州大学伯克利分校开发核心语言是C。它支持命令行、Python和MATLAB接口。Caffe的一个重要特色是可以在不编写代码的情况下训练和部署模型。
具体介绍见下文。
caffe框架
为何选择caffe
我们暂时先选择caffe框架作为分享目标原因如下
与ncnn的兼容性好最重点不需要写代码就可以实现训练可以作为深度学习的突破口支持python接口可以丰富编程化实现丰富的demo实现等
caffe环境搭建
推荐ubuntu系统参考博客https://blog.csdn.net/wangjie5540/article/details/97786182 mac系统也可搭建参考博客https://blog.csdn.net/wangjie5540/article/details/99571832
caffe使用了众多的依赖库再加上caffe年久失修出现编译兼容问题也不奇怪。推荐大家在ubuntu上进行编译可以驱动gpumac的最新14.14不支持n卡据说需要降到14.13才可以。
caffe基础
针对于神经网络的模型caffe设计了对应的概念。并且使用caffe来训练模型的过程非常简单甚至都不用写一行代码仅仅改改配置文件也同样能直接开始训练当然用python去写训练过程的话会更加的灵活。
数据集
原始数据本文主要针对的是图片数据可能有不同的格式image格式、bytes格式、lmdb格式等标注数据监督学习必须进行标注
caffe倾向于先把数据集转化成lmdb或者hdf5格式然后输入神经网络进行训练。
模块概要图 概要
使用数据构建脚本构建训练数据和测试数据caffe train命令加载solver的prototxt配置solver配置加载神经网络配置神经网络对接训练数据和测试数据成千上万次迭代最终按照solver中的配置策略周期性生成权重模型文件
solverprototxt 执行者配置
超参数配置文件。 超参数的概念如下 在机器学习的上下文中超参数是在开始学习过程之前设置值的参数而不是通过训练得到的参数数据。通常情况下需要对超参数进行优化给学习机选择一组最优超参数以提高学习的性能和效果 神经网络可视化
http://ethereon.github.io/netscope/#/editor 下面是对lenet的可视化可以清楚的看到lenet的全貌。
mnist数据输入conv1第一次卷积层pool1第一池化层conv2第二次卷积层pool2第二次池化层ip1全连接层即多层感知机relu1激活层ip2全连接层loss损失层同时激发bn反向传播操作
caffe中的基础概念
blobs
对待处理数据带一层封装用于在Caffe中通信传递也为CPU和GPU间提供同步能力数学上是一个N维的C风格的存储数组总的来说Caffe使用Blob来交流数据其是Caffe中标准的数组与统一的内存接口它是多功能的在不同的应用场景具有不同的含义如可以是batches of images, model parameters, and derivatives for optimization等 作者沤江一流 链接https://www.jianshu.com/p/0ac09c3ffec0 layer 神经层
layer是caffe神经网络的基本组成单元。layer包括不同的种类
Data也就是blob的层Convolution卷积层Pooling池化层InnerProduct全连接SoftmaxWithLoss激活函数loss层
不同的层次对应了神经网络中的不通过概念。另外每种类型的层在caffe的源码中有特定的实现之后会在其他博客中展开讨论这里不再赘述。
net 神经网络
net是指神经网络定义可以认为是layer的总和。在python版本编程中会出现net的概念。
forward/backward 前向传播/反向传播
forward和backward在python编程版本中会出现手动执行会触发一次前向传播或反向传播python实现的caffe训练最终的本质是在循环中每次手动触发forward函数重点看一下本博客的caffemnist的python实现注释版。
caffemnist数据集lenet
参考博客https://blog.csdn.net/wangjie5540/article/details/98615226 python实现mnist注释版https://gitee.com/simple_projects/caffe_learning/blob/master/01-learning-lenet-mine.ipynb
caffecifar10caffenet
非常类似mnist数据集参考https://blog.csdn.net/wangjie5540/article/details/98615226
caffecifar10mobilenet
参考https://github.com/shicai/MobileNet-Caffe.git shicai的mobilenet提供了预训练模型可以直接进行数据预测。 大家肯定想预训练模型没什么意思要自己训练才来实际。 参考https://blog.csdn.net/lwplwf/article/details/82415525可以使用cifar10进行模型训练。 ps作者用cpu训练了几天最终迭代了19w次最终准确率在70%没有达到很好的收敛效果。之后准备好gpu的机器还会再次训练以观后效
注cifar10的数据集进行模型训练的时候出现mean的概念即均值rgb每个通道上的像素的平均值。这样做的目的是让个像素的值以0为对称点进行均匀分布训练过程更容易收敛。有两种获取均值的方法
以数据集为目标把每个通道上的像素值全部加和然后求平均caffe的cifar10就是使用的这种方法直接使用均值128128128简单暴力。mobilenetssd的训练过程中就是这么做的最终也能收敛
以上两种方法暂时没有证实哪个效果最好。
caffevoc2012vggfinetunessd物体检测模型
参考https://github.com/weiliu89/caffe.git voc的数据集需要在外网下载时间要好久好久。。我已经把这些数据都下载完毕上传到云盘。以下是下载地址https://download.csdn.net/download/wangjie5540/11598810 由于本次是迁移训练预训练模型是vggnet还需要下载vggnet地址是https://download.csdn.net/download/wangjie5540/11603902
注博主用cpu训练跑了两天还没有跑到第一次的快照地点。如果想自己训练的话就选gpu的机器吧。
轻量级客户端框架-ncnn
ncnn简介
git地址https://github.com/Tencent/ncnn ncnn 是一个为手机端极致优化的高性能神经网络前向计算框架。ncnn 从设计之初深刻考虑手机端的部署和使用。无第三方依赖跨平台手机端 cpu 的速度快于目前所有已知的开源框架。基于 ncnn开发者能够将深度学习算法轻松移植到手机端高效执行开发出人工智能 APP将 AI 带到你的指尖。ncnn 目前已在腾讯多款应用中使用如 QQQzone微信天天P图等。
支持大部分常用的 CNN 网络
Classical CNN: VGG AlexNet GoogleNet Inception …Practical CNN: ResNet DenseNet SENet FPN …Light-weight CNN: SqueezeNet MobileNetV1/V2/V3 ShuffleNetV1/V2 MNasNet …Detection: MTCNN facedetection …Detection: VGG-SSD MobileNet-SSD SqueezeNet-SSD MobileNetV2-SSDLite …Detection: Faster-RCNN R-FCN …Detection: YOLOV2 YOLOV3 MobileNet-YOLOV3 …Segmentation: FCN PSPNet UNet …
ncnncaffemobilenet实战
ncnn环境搭建
先下载release版本的ncnn我这里现在ncnn-20190611
$ cd ncnn-root-dir
$ mkdir -p build-android-armv7
$ cd build-android-armv7$ cmake -DCMAKE_TOOLCHAIN_FILE$ANDROID_NDK/build/cmake/android.toolchain.cmake \-DANDROID_ABIarmeabi-v7a -DANDROID_ARM_NEONON \-DANDROID_PLATFORMandroid-14 ..# if you want to enable vulkan, platform api version android-24 is needed
$ cmake -DCMAKE_TOOLCHAIN_FILE$ANDROID_NDK/build/cmake/android.toolchain.cmake \-DANDROID_ABIarmeabi-v7a -DANDROID_ARM_NEONON \-DANDROID_PLATFORMandroid-24 -DNCNN_VULKANON ..$ make -j4
$ make installpick build-android-armv7/install folder for further jni usage
编译完成后生成以下文件 支持库和头文件供android的arm-v7a使用
模型转化caffe格式- ncnn格式
首先需要编译caffe的环境。 参考https://blog.csdn.net/wangjie5540/article/details/97786182https://blog.csdn.net/wangjie5540/article/details/99571832
源码解析
文件目录
├── README.md
├── app
│ ├── build.gradle // android工程配置
│ ├── proguard-rules.pro // 混淆配置
│ └── src
│ ├── androidTest
│ │ └── java
│ │ └── com
│ │ └── ztjy
│ │ └── ncnndemo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── assets
│ │ │ ├── mobilenet_v2.bin // mobilenet权重文件
│ │ │ ├── mobilenet_v2.param.bin // 神经网络参数文件
│ │ │ └── synset.txt // 分类索引文件
│ │ ├── cpp
│ │ │ ├── CMakeLists.txt
│ │ │ ├── include // ncnn的头文件
│ │ │ │ ├── allocator.h
│ │ │ │ ├── benchmark.h
│ │ │ │ ├── blob.h
│ │ │ │ ├── caffe.pb.h
│ │ │ │ ├── command.h
│ │ │ │ ├── cpu.h
│ │ │ │ ├── gpu.h
│ │ │ │ ├── layer.h
│ │ │ │ ├── layer_type.h
│ │ │ │ ├── layer_type_enum.h
│ │ │ │ ├── mat.h
│ │ │ │ ├── mobilenet_v2.id.h
│ │ │ │ ├── mobilenet_v2.mem.h
│ │ │ │ ├── modelbin.h
│ │ │ │ ├── net.h
│ │ │ │ ├── opencv.h
│ │ │ │ ├── option.h
│ │ │ │ ├── paramdict.h
│ │ │ │ ├── pipeline.h
│ │ │ │ └── platform.h
│ │ │ ├── jniLibs
│ │ │ │ └── armeabi-v7a
│ │ │ │ └── libncnn.a // ncnn静态库
│ │ │ └── native-lib.cpp
│ │ ├── java
│ │ │ └── com
│ │ │ └── ztjy
│ │ │ └── ncnndemo
│ │ │ ├── MainActivity.java // 主窗体
│ │ │ ├── NcnnJni.java // jni交互文件
│ │ │ └── PhotoUtil.java // 图片工具文类从相册中取文件
│ │ └── res
│ │ ├── drawable
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout
│ │ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── ztjy
│ └── ncnndemo
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
执行流程
https://www.processon.com/view/link/5d5cfe08e4b08b95b82695bb
重点代码
java层代码
// predict imageprivate void predict_image(String image_path) {// picture to float arrayBitmap bmp PhotoUtil.getScaleBitmap(image_path);Bitmap rgba bmp.copy(Bitmap.Config.ARGB_8888, true);// resize to 227x227Bitmap input_bmp Bitmap.createScaledBitmap(rgba, ddims[2], ddims[3], false);try {// Data format conversion takes too long// Log.d(inputData, Arrays.toString(inputData));long start System.currentTimeMillis();// get predict result调用jni层代码进行预测float[] result squeezencnn.detect(input_bmp);long end System.currentTimeMillis();Log.d(TAG, origin predict result: Arrays.toString(result));long time end - start;Log.d(TAG, String.valueOf(result.length));// show predict result and timeint r get_max_result(result);Log.d(TAG, r );Log.d(TAG, resultLabel.toString());Log.d(TAG, resultLabel.get(r));Log.d(TAG, result[r] );Log.d(TAG, time );String show_text result r ,name resultLabel.get(r) \nprobability result[r] \ntime time ms;Log.d(TAG, show_text);result_text.setText(show_text);} catch (Exception e) {e.printStackTrace();}}
jni层代码
// public native String Detect(Bitmap bitmap);
JNIEXPORT jfloatArray JNICALL
Java_com_ztjy_ncnndemo_NcnnJni_detect(JNIEnv *env, jobject thiz, jobject bitmap) {// ncnn from bitmapncnn::Mat in;{AndroidBitmapInfo info;// 获取位图信息AndroidBitmap_getInfo(env, bitmap, info);// 获取位图宽高int width info.width;int height info.height;// demo只支持rgba格式的图片if (info.format ! ANDROID_BITMAP_FORMAT_RGBA_8888)return NULL;void *indata;AndroidBitmap_lockPixels(env, bitmap, indata);// 把像素转换成data并指定通道顺序in ncnn::Mat::from_pixels((const unsigned char *) indata, ncnn::Mat::PIXEL_RGBA2BGR,width, height);AndroidBitmap_unlockPixels(env, bitmap);}// ncnn_net// std::vectorfloat cls_scores;{// 减去均值和乘上比例来源与caffe神经网络的配置文件即prototxt文件const float mean_vals[3] {103.94f, 116.78f, 123.68f};const float scale[3] {0.017f, 0.017f, 0.017f};// 设置均值与标准化参数in.substract_mean_normalize(mean_vals, scale);// 创建ncnn前向传播的结果提取器ncnn::Extractor ex ncnn_net.create_extractor();// 如果不加密使用ex.input(data, in);ex.input(mobilenet_v2_param_id::BLOB_data, in);ncnn::Mat out;// 如果不加密是使用ex.extract(prob, out);ex.extract(mobilenet_v2_param_id::BLOB_prob, out);int output_size out.w;jfloat *output[output_size];for (int j 0; j out.w; j) {output[j] out[j];}// 获取结果预测结果并返回给android层jfloatArray jOutputData env-NewFloatArray(output_size);if (jOutputData nullptr) return nullptr;env-SetFloatArrayRegion(jOutputData, 0, output_size,reinterpret_castconst jfloat *(*output)); // copyreturn jOutputData;}
}
效果展示
caffemobilenet分类
其他工程的效果图
https://github.com/chehongshu/ncnnforandroid_objectiondetection_Mobilenetssd.git ncnnmobilenet-ssd
相关学习资料
教学视频
唐宇迪-深度学习Caffe框架入门视频课程https://edu.csdn.net/course/detail/3506 会写代码的好厨师-Caffe实战入门https://www.imooc.com/learn/1040
开源项目
caffe官网https://github.com/BVLC/caffe ncnnhttps://github.com/Tencent/ncnn.git ncnnmobilenet-ssdhttps://github.com/chehongshu/ncnnforandroid_objectiondetection_Mobilenetssd shicai_mobilenethttps://github.com/shicai/MobileNet-Caffe.git weiliu89https://github.com/weiliu89/caffe.git需要check_out到ssd分支
参考博客
在Android手机上使用腾讯的ncnn实现图像分类https://blog.csdn.net/qq_33200967/article/details/82421089