试试kaggle竞赛:辨别猫狗
在上一篇文章《深度学习中超大规模数据集的处理》中讲到采用HDF5文件处理大规模数据集。有朋友问到:HDF5文件是一次性读入内存中,然后通过键进行访问吗?答案当然不是,在前面的文章中也提到过,最后生成的train.hdf5文件高达30G,如果全部加载到内存,内存会撑爆。实际上,由于HDF5采用了特殊的文件格式,这样我们可以在一次读操作中加载一个批量(比如128)的图片,而不用一个个的读取。也就是说采用这种方式,只是减少了IO操作次数,另外加载的图片是RAW图像数据,减少了解码时间。
在这篇文章中,我们将说明如何读取HDF5文件,从头实现一个AlexNet网络模型。掌握了这些知识,你也可以去挑战一下Kaggle竞赛。需要指出的是,在ImageNet超大规模数据集上训练,特别是深度模型,非常耗时!!!周末在我的机器(配置为CPU: i7 6700, GPU: GTX960, MEM: 8G)上从头训练AlexNet模型,一个Epoch下来,都要花上一天的时间,结果搭上整个周末,也就跑了两个Epoch,更别提对比使用HDF5文件前后的效果。看样子该升级一下机器配置:(
图像预处理
在实现AlexNet网络模型之前,先介绍几个图像预处理方法,这些预处理在计算机视觉深度学习中应用十分广泛,可以有效的提高图像分类的准确率。
均值减法(mean subtraction)
在上一篇文章中,在处理图像文件的过程中,计算了所有图像的RGB通道的均值。而所谓的均值减法预处理就是将图像的每个像素点RGB通道值减去对应通道的均值,简单说,公式如下:
比如一张狗狗的图片,经过均值预处理,得到了右边的图像。
均值减法是一种数据归一化技巧,可以减少光线变化造成的影响。
借助于opencv的处理函数,实现均值减法非常简单:
(B, G, R) = cv2.split(image.astype("float32"))# subtract the means for each channelR -= self.r_meanG -= self.g_meanB -= self.b_mean# merge the channels back and return the imagereturn cv2.merge([B, G, R])
切片(patch)
切片预处理就是在训练过程中随机截取图像M x N区域内的像素值。我们知道,CNN模型要求图像输入尺寸是一个固定值,如果我们使用的图像大小和输入尺寸不一致,通常的处理方法是对图像进行缩放。但是,如果使用的图像比输入尺寸大,还有一种更好的方法就是进行随机截取部分图像,这可以有效的降低过拟合。
上图中,随机裁剪256x256的图像到227x227大小。因为是随机裁剪,所以网络每次训练的图像不同,相当于一种数据扩充技术,可以减少过拟合。
我们也不需要从头实现,借助与sklearn中的实用函数,一句话就可以搞定:
def preprocess(self, image):# extract a random crop from the image with the target width and heightreturn extract_patches_2d(image, (self.width, self.height), max_patches=1)[0]
裁切(cropp)
裁切预处理有点类似上面的切片预处理。不过有两点不同:
- 本预处理应用于验证数据集,而切片预处理应用在训练数据上。
- 本预处理固定截取4个角及正中间区域,在加上水平翻转,这样每张图片可以得到10张采样。
还记得《提高模型准确率:组合模型》这篇文章讲到,通过组合多个网络的输出可以提高分类准确率,这里就是计算10张采样的分类概率平均值,从而达到提高分类准确率的效果。
该预处理没有现成的函数可用,不过写起来也不难:
def preprocess(self, image):crops = []# grab the width and height of the image then use these dimensions to# define the corners of the image based(h, w) = image[:2]coords = [[0, 0, self,width, self.height],[w - self.width, 0, w, self.height],[w - self.width, h - self.height, w, h],[0, h - self.height, self.width, h]]# compute the center crop of the image as welldw = int(0.5 * (w - self.width))dh = int(0.5 * (h - self.height))coords.append([dw, dh, w - dw, h - dh])for (startx, starty, endx, endy) in coords:crop = image[startx:endx, starty:endy]crop = cv2.resize(crop, (self.width, self.height), interpolation=self.inter)crops.append(crop)if self.horiz:# compute the horizontal mirror flips for each cropmirrors = [cv2.flip(c, 1) for c in crops]crops.extend(mirrors)return np.array(crops)
HDF5数据集生成器
《深度学习中超大规模数据集的处理》中,我们将数据集存成HDF5文件格式,这里,我们需要从HDF5文件中按照批次读取图像数据及类别标签。
# loop over the HDF5 datasetfor i in np.arange(0, self.num_images, self.batch_size):# extract the images and labels from HDF5 datasetimages = self.db["images"][i : i + self.batch_size]labels = self.db["labels"][i : i + self.batch_size]if self.binarize:labels = np_utils.to_categorical(labels, self.classes)if self.preprocessors is not None:proc_images = []for image in images:for p in self.preprocessors:image = p.preprocess(image)proc_images.append(image)images = np.array(proc_images)
每次读取batch_size个图像数据和类别标签,并进行预处理,代码中对images和labels的访问有点类似数组,[i : i + self.batch_size]读取第i到第(i+batch_size)个元素。
AlexNet
相对于我们之前实现的深度学习模型,AlexNet相当复杂,图的层如下表所示:
当AlexNet首次提出来时,还没有出现批量归一化等技术。在实现中,我们将在激活后加入批量归一化,对于使用卷积神经网络的大多数图像分类任务而言,这是非常标准的处理。另外,我们还会在每次POOL操作后做一些dropout,以进一步减少过拟合。
在前面的文章中,我们已经见识过keras的简洁之处,即使是AlexNet这样复杂的网络,对keras而言只是多几行代码而已。
class AlexNet:@staticmethoddef build(width, height, depth, classes, reg=0.0002):model = Sequential()input_shape = (width, height, depth)channel_dim = -1if K.image_data_format() == "channels_first":input_shape = (depth, width, height)channel_dim = 1# block #1: CONV => RELU => POOLmodel.add(Conv2D(96, (11, 11), strides=(4, 4), input_shape=input_shape,padding="same", kernel_regularizer=l2(reg)))model.add(Activation("relu"))model.add(BatchNormalization(axis=channel_dim))model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2)))model.add(Dropout(0.25))# block #2: CONV => RELU => POOLmodel.add(Conv2D(256, (5, 5),padding="same", kernel_regularizer=l2(reg)))model.add(Activation("relu"))model.add(BatchNormalization(axis=channel_dim))model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2)))model.add(Dropout(0.25))# block #3: CONV => RELU => CONV => RELU => CONV => RELU => POOLmodel.add(Conv2D(384, (3, 3),padding="same", kernel_regularizer=l2(reg)))model.add(Activation("relu"))model.add(BatchNormalization(axis=channel_dim))model.add(Conv2D(384, (3, 3),padding="same", kernel_regularizer=l2(reg)))model.add(Activation("relu"))model.add(BatchNormalization(axis=channel_dim))model.add(Conv2D(256, (3, 3),padding="same", kernel_regularizer=l2(reg)))model.add(Activation("relu"))model.add(BatchNormalization(axis=channel_dim))model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2)))model.add(Dropout(0.25))# block #4: FC => RELUmodel.add(Flatten())model.add(Dense(4096, kernel_regularizer=l2(reg)))model.add(Activation("relu"))model.add(BatchNormalization())model.add(Dropout(0.5))# block #5: FC => RELUmodel.add(Dense(4096, kernel_regularizer=l2(reg)))model.add(Activation("relu"))model.add(BatchNormalization())model.add(Dropout(0.5))# softmax classifiermodel.add(Dense(classes, kernel_regularizer=l2(reg)))model.add(Activation("softmax"))return model
接下来就是训练和测试模型,对于深度学习而言,不管是复杂还是简单的模型,其训练和测试过程都是大同小异,所以在这里我也不再罗嗦,有兴趣的同学可以参考我在github上的完整代码。但是需要注意,这个训练非常耗时,如果没有极其牛的显卡,还是不要轻易尝试。其实对于图片分类任务来说,最好还是采用迁移学习,站在巨人的肩膀上,不仅省力,效果还更好一些。
以上实例均有完整的代码,点击阅读原文,跳转到我在github上建的示例代码。
另外,我在阅读《Deep Learning for Computer Vision with Python》这本书,在微信公众号后台回复“计算机视觉”关键字,可以免费下载这本书的电子版。
往期回顾
- 深度学习中超大规模数据集的处理
- 提高模型准确率:组合模型
- 再谈迁移学习:微调网络
- 站在巨人的肩膀上:迁移学习
- 聊一聊rank-1和rank-5准确度
- 使用数据增强技术提升模型泛化能力
试试kaggle竞赛:辨别猫狗相关推荐
- 基于kaggle数据集的猫狗识别(超详细版本)
目录 下载kaggle数据集 创建新的小数据集 构建猫狗分类的小型卷积神经网络 猫狗分类的网络架构 模型的配置 图像的预处理 利用批量生成器拟合模型 绘制精度和损失 结果显示 随机增强后的训练图像显示 ...
- tensorflow kaggle猫狗大战识别猫狗
一,Kaggle猫狗大战数据集: 下载地址:https://www.kaggle.com/c/dogs-vs-cats 下载解压后会有两个文件目录,一个测试数据,一个训练数据: 训练数据: 二,训练代 ...
- kaggle项目实战——猫狗分类检测
主要参考:<深度学习--caffe之经典模型详解与实战> kaggle数据集下载链接:https://www.kaggle.com/c/dogs-vs-cats-redux-kernels ...
- 华为云深度学习kaggle猫狗识别
使用华为云深度学习服务完成kaggle猫狗识别竞赛 参考: kaggle猫狗竞赛kernel第一名的代码 Tensorflow官网代码 华为云DLS服务github代码 1. 环境配置与数据集处理 首 ...
- 【深度学习】猫狗识别TensorFlow2实验报告
实验二:猫狗识别 一.实验目的 利用深度学习实现猫狗动物识别,采用Kaggle提供的公开数据集,训练深度学习模型,对测试集猫狗中的图片准确分类.通过该实验掌握深度学习中基本的CV处理过程. 二.实验原 ...
- AlexNet 实现猫狗分类(keras and pytorch)
AlexNet 实现猫狗分类 前言 在训练网络过程中遇到了很多问题,先在这里抱怨一下,没有硬件条件去使用庞大的ImageNet2012 数据集 .所以在选择合适的数据集上走了些弯路,最后选择有kagg ...
- 猫狗大战(kaggle竞赛-猫狗图像分类)
本实验使用kaggle中猫狗大战中的部分数据集(2000张训练数据+500张测试数据) 本次实验中使用了DNN.CNN.RNN分别进行了图像识别,具体代码如下: DNN模型: 全连接层 神经元个数 F ...
- 毕设:基于CNN卷积神经网络的猫狗识别、狗品种识别(Tensorflow、Keras、Kaggle竞赛)
基于卷积神经网络的图像识别算法及其应用研究 毕业快一年了,拿出来分享给大家,我和网上唯一的区别就是,我能够同时实现两个方案(猫狗识别和狗品种识别),我当时也是网上各种查,花了2,3个月的时间,一个萝卜 ...
- Kaggle深度学习与卷积神经网络项目实战-猫狗分类检测数据集
Kaggle深度学习与卷积神经网络项目实战-猫狗分类检测数据集 一.相关介绍 二.下载数据集 三.代码示例 1.导入keras库,并显示版本号 2.构建网络 3.数据预处理 4.使用数据增强 四.使用 ...
最新文章
- uniapp在低版本android,uni-app离线打包Android平台注意事项
- 11.4 专利法与反不正当竞争法解读
- SAP License:你熟悉SAP的统驭科目吗?
- Echarts数据可视化tooltip提示框,开发全解+完美注释
- wordpress字体_如何在WordPress中使用网络字体
- 计算机桌面变小了是怎么回事啊,电脑桌面整体变小了要怎么调回来的
- [转]二十四式太极拳攻防含义拆解
- IKBC DC-108改装锂电池
- 前端架构师的YY定义
- AD20 制作 Logo
- Android如何设置按钮图片(控件图片)大小自适应
- 树莓派 电脑 文件共享 搬移
- Didn't find class android.support.v7.widget.RecyclerView 解决办法 ———————————————— 版权声明:本文为CSDN博主「eag
- Qt修改可执行程序的图标 生成的exe使用自定义的Ico文件
- npm start 报错解决方案
- 在Word中撰写论文插入MathType公式,使得公式居中编号右对齐教程
- 将页面中的指定 div 下载为图片
- 如何来投放广告更赚钱
- FME学习资料……new
- 在Centos7上安装osp
热门文章
- 上学还是坐牢?百年老校“监控”学生惹争议
- Java根据奖品权重计算中奖概率实现抽奖(适用于砸金蛋、大转盘等抽奖活动)
- 杜克大学计算机专业本科入学条件,杜克大学计算机专业基本信息详解以及入学要求汇总介绍...
- 什么计算机玩游戏好,电脑玩游戏什么配置好
- 菌群分析Linux,Qiime1-13.菌群组成与指标相关性分析(自带命令及MaAslin)
- 爬取网易云音乐两万条评论储存在MySQL服务器上
- ognl表达式的简单用法
- 数据结构课程设计:1、单位员工通讯录管理系统(线性表的应用)
- 汇川AM401非标准协议通讯socket_client
- 查看linux centos ftp服务,Centos7开启FTP服务