卷积神经网络
我们知道图片是由大量像素点构成的,每个像素点又由 RGB 颜色值构成,用计算机识别图片,如果直接分析各个像素点和它们的颜色值,计算量就非常大,分析会很复杂和低效,卷积神经网络 (CNN,Convolutional Neural Network) 通过卷积运算快速从大量数据中提取出各种特征,然后用神经网络对浓缩后的特征数据进行快速分析,就能高效地处理图片。
Keras 是 TensorFlow 中一个高层神经网络 API,用 Keras 可以很方便地构建和训练神经网络模型,官方也提供了在 ImageNet 数据集上训练的 ResNet-50 模型,ResNet 叫残差网络,ResNet-50 是一种深度卷积神经网络,该神经网络模型既轻量又有很高的识别准确率。
图片识别 API
这里基于 Keras 的预训练模型 ResNet-50 做一个图片识别应用,为了易于使用,我们把图片识别部分封装成 RESTful API,客户端通过 Http 请求把图片传给后端,服务端完成识别后把结果返回给客户端,客户端再用某种可视化的方式展示出来。
用 Python 实现后端 API 的封装,主要包括以下几步:
加载模型
1 | from tensorflow.keras.applications import ResNet50 |
图片预处理
ResNet50 模型的默认输入尺寸是 224x224 像素,输入格式为 RGB,故需要对输入图片做一些预处理:
1 | from tensorflow.keras.preprocessing.image import img_to_array |
创建 RESTful API
Flask 是一个轻量级的 Python Web 应用框架,用 Flask 创建一个 POST 接口,用于接收客户端传过来的图片文件,送入模型进行识别,然后把识别结果返回给客户端。
1 | from flask import Flask, request, jsonify |
Vue 客户端
用 Vue.js 开发一个 Web 客户端,实现图片上传和识别结果展示。
为了贯彻 Vue 组件化开发思想,我把单一页面分成三个子组件,分别是图片选择、图片预览和结果显示三个组件,然后放置在一个父组件中,组件间通过 Vuex 共享状态。
核心代码
首先从电脑硬盘中选取一张图片,组件获取图片后,提交 mutation 更新 store 中的状态,把图片 URL 传递给预览组件:
1 | getFile(event) { |
同时请求 Flask 服务端接口,并把返回结果传递给图表子组件:
1 | let fdata = new FormData(); |
快速体验
这里我已将前后端整体打包为一个 Docker 镜像,你可以直接运行一个 Docker 容器来体验:
1 | docker run -p 80:80 yunterry/keras-vue |
前端页面:

Android 客户端
通过 Android 客户端你可以直接用手机摄像头拍摄一张照片,或是从手机相册中选取一张照片进行识别,这里用 Retrofit、Picasso 开发一个 Android APP。
核心代码
先从手机相册中选取一张图片,显示在图片预览控件中:
1 | String imgpath = data.getStringArrayListExtra( |
同时向服务端发起 Post 请求,把图片传过去,请求返回即为识别结果,根据标签和概率显示在列表控件中:
1 | Rest.getRestApi().uploadFile(requestImgPart) |
运行结果如下:

项目源码
Vue 客户端
https://github.com/yunTerry/Keras-Vue
Android 客户端
https://github.com/yunTerry/Keras-Android


