深度学习 图像识别 三

传送门



本文目录

三、逐行学习代码,熟悉开发环境

1. Pycharm环境熟悉

首先我拿到了逐飞AI的资料包,找到了 number_train_model 的文件夹如下

想当初刚拿到看到这里的时候是一脸懵逼,只能头铁一个个看里面的代码。

在文件夹下右击鼠标,如果已经成果安装了 PyCharm,可以看到 Open folder as Pycharm Project(很喜欢 Pycharm 的风格)

下面跟大家简单聊一些 pycharm 的使用。左边是 Project 栏,里面有三个部分。

第一个就是刚刚我们所在的 number_train_model 文件夹,现在变成了工程文件夹。

第二个是 External Library,也就是所谓的外部Python环境库,我们可以在右边最上面看到一个警告,No Python interpreter configured for the project,没有为项目配置Python解释器

第三个是 Scratch and Consoles,我一般是用作草稿文件。

这时候我们需要打开 Setting,位置如下:

setting下选择当前 Project,比如我的是 Project : number_train_model,下面就可以发现 Project Interpreter


从上到下依次点击齿轮,点击 add 加入环境,进入 Add Python Interpreter 界面,我的 python 是直接官网下载的,没有使用 Anaconda 配置,就直接在电脑本地文件夹找到我的 python安装路径,选中 python.exe ,一路OK即可。

Pycharm 有一个代码习惯的问题,可以看到下图中到处都是黄色下划线警告,因为此处与预设的代码习惯不符合。

之前在一个TensorFlow的讨论组里有人问过,Pycharm的这个黄色下划线怎么消除。结果群里一大堆同志都回答各种 “重装python啊、Pycharm破解问题啊、重装系统、建议换Linux” 都出来了,笑…

比如说我们把鼠标放在一个黄色下划线附近查看一下,上面写的是 E225 missing whitespace around operator,表示error 类型编号为225,等号周围缺少空格。

我们点击 More actions,可以直接点击 Ignore errors like this 忽略这个错误。

也可以点击 Edit inspection profile setting 查看所有的警告类型进入以下这个界面。不过要是看不惯全英文的操作界面,还是写代码的时候看见哪里不爽才把哪里屏蔽掉吧。


pycharm 的基本配置先到此为止。

下面开始与大家尽可能详尽地讲解代码,带有注释的代码打包在这里

百度网盘链接



2. 数据集准备

find_image.py 文件用于制备训练数据集。采用了 下载cifar-100 / cifar-10 网络爬虫 两种途径获取数据集。

2.1 通过 keras.dataset 下载 cifar数据集

cifar 是一份经典的数据集,包括 常见的动物、水果 、汽车、飞机、轮船 等等的图片,但是很不幸,本次任务中需要对一些特殊类别进行识别,比如 猪、榴莲 等,cifar数据集里找不到,只能通过网络爬虫来寻找。

或是等逐飞发布竞赛专用数据集哈哈哈哈,这里把逐飞整理好的数据集发给大家:
链接https://pan.baidu.com/s/1-cFTV0KRig5QYO0ApG8pGg
提取码:data

百度图片网站上爬取图片用于训练。爬虫的原理我们就不多说,只关注如何使用、根据要求修改这份代码。

首先可以看到这里定义了几个字典、变量,可以看到明显的 https://image.baidu.com ,从百度图片网站上爬取的图片

然后下面的代码可以看到有 cattle apple cat dog horse 五个分块,这里就是利用 keras 的库函数 读取 cifar 数据集的操作

首先我们回到这份代码的最顶端,可以看到这份代码导入的所有外部文件, from keras.datasets import cifar10, cifar100 从keras导入了cifar数据集。

keras.dataset 是我们接触到的第一个keras函数,这里我们下载一下 Keras中文文档

链接https://pan.baidu.com/s/1TjHb4V9Gy_Z7LfeQvb11mg
提取码:kras

百度也能搜到页面版,但版式不是很舒服:

在文档里搜索一下 dataset 可以看到:

得知 cifar10 是一个 keras 支持的数据库,可以调用 .load_data() 方法读取数据,返回值为 训练集 (X_train, y_train) 测试集 (X_test, y_test) 两个Tuple 。

cattle 的提取为例:


由顶部的 import numpy as np 可知, np numpy库 的别称。本文件用到了 np.where 以及 np.ravel 两种numpy函数。这里教给大家如何快速掌握 python函数 的功能信息。

在pycharm中,单击选中 变量 或者 函数名 ,然后按快捷键 Crtl + B , 实现 go to definition 的功能。

例如下图,可以看到 where 函数的头部有 函数简介 入口参数 返回参数 ,从而得知 where 可以用于 输出满足条件 (即非0) 元素的坐标 ravel 用于把多维数组展平,简单理解就是 获取标签的序号 (比如牛的序号为19,苹果的序号为0)。


如果 标签y 的序号 == 19,就获取对应位置的 图像x ,并保存为 npy 文件,保存路径即为 np.save 中的参数 “./picture/4/cattle.npy”

这篇文章里介绍了如何查看 cifar100每个标签的序号,代码可借鉴
Cifar100的标签序号与名称对应

2.2 npy到底长啥样?

初学的时候我也非常好奇,numpy是数组矩阵运算的函数库,npy是numpy专用的二进制格式,npy格式的图片是啥样的? 于是写了一个小代码,查看npy文件的所有信息:

import numpy as np

pic = np.load(r'.\x.npy')

# np.set_printoptions(threshold = 1e6) # 其中threshold表示输出数组的元素数目

print(pic)
print("数据类型",type(pic))            # 打印数组数据类型
print("数组元素数据类型:",pic.dtype)   # 打印数组元素数据类型
print("数组元素总数:",pic.size)       # 打印数组尺寸,即数组元素总数
print("数组形状:",pic.shape)         # 打印数组形状
print("数组的维度数目",pic.ndim)      # 打印数组的维度数目

由于npy文件太大,会导致显示不全的问题。代码中被注释掉的的 np.set_printoptions(threshold = 1e6) 一句可以解决这个问题, threshold 用来设置显示多少个数据。

可以看到,数据集被保存为一个4维度的数组 (1394, 32, 32, 3) 1394 指代图片数量, (32, 32, 3) 表示图片是 32 _ 32 像素的 rgb 3 通道格式。



2.3 自制数据集

很多时候,我们找不到像 cifar 这样优质的数据集,只能自己制备,可以爬虫、拍照。比如我们有这样一堆拍好的图片:


我们要做的就是把这堆 jpg 格式的图片(png之类的其他格式也是可以的) 也压缩到 npy 文件里面去

打开 make_dataset.py

代码里写有足够多的思路、注释,这里只大致讲解 代码结构以及用法、改法

在文件头部定义了两个bool型变量 make check ,作为标志位使用。如果只需要 制作数据集 ,把 make 赋值 True 即可;如果只需要 检查已有的数据集 ,而不用重新制作,把 check 赋值 True 即可。

制作数据集的部分也分成了 jpg文件 npy文件 两部分。如果你拍摄的照片是 png 或其他格式,自行修改即可。

如果你的文件夹下不包含直接从 cifar 这样的数据集下载过来的 npy文件 , 可以直接 删掉下面这两块代码

最后就是 数据集检查

代码中所有被 3颗 _ 符号 包围的部分都需要根据自己的文件夹路径命名需要合理修改。


如果你的标签不是 0 1 2 3 4 5 6 7 8 9 ,可以改为类似于 label = [“apple”, “orange”, “cat”, “dog”, “orange”] + [“flower”, “plane”, “car”, “cattle”, “purple”] 的数组,只要与期望输出的标签对应即可。

数据集制作、检查完毕。

3. 模型训练

接下来便是最最重要 train.py 文件了,顾名思义,搭建网络,开始训练

3.1 数据集分割

周志华教授的西瓜书 §2 模型评估与选择中,我们学到了 留出法、交叉验证法、自助法 三种数据集分割方法。因为我们的数据集不仅需要用来训练,也需要用来验证网络的性能。

就好似你想检验小孩儿的学习情况,不仅需要给他一堆习题册去训练,还得时不时拿点卷子给他测验。测验题有可能会出自训练集,也有可能在训练集之外。如果小孩儿能够完成在训练集之外的题目测试,说明他知识已经学习的不错了。


是最容易实现的分割方法,只需要将一部分给训练集,剩余的给测试集即可,一般我们 二八分 或者 三七分

这里采用的是 留出法 二八分

下面通过 两种搭建方法 搭建了一个 卷积-池化-激活-卷积-池化-激活-卷积-池化-激活-拉伸-全连接 这样一个简单线性结构的网络。


小声吐槽:也不知道逐飞最后到底是不是用的这个架构完成的任务,这个架构我是怎么训都没训好…





传送门

〇、前言

一、机器学习基础

二、开发环境搭建

三、逐行学习代码,熟悉开发环境

四、学习Keras构建网络,尝试各种模型

五、TensorBoard 可视化,更可靠

六、克服过拟合的第一步 实现过拟合

七、与导师闲言小叙,忽有灵光

八、发现神器,但功力不够,反造成内伤

九、老老实实调参师,挨个尝试架构

十、发现妙解!量化装载!超内存!

十一、最后的灵丹

十二、在线预测百分百,量化之后二百五?

十三、量化之后表现差?在线运行试试

十四、甲方又来催了…租个服务器加急

十五、寻了千百遍,原因竟不在于神经网络太傻

十六、尾声