竞赛练习—形状识别2:方圆之外

前言

此次竞赛为《形状识别2:方圆之外》,是一起图像的多分类问题。因为是初次接触CNN模型,主要分析标杆模型并进行调参
提交的结果为每行的预测标签,也就是0、1、2。评价方法为准确率。本文最终处理结果为0.98767,排名2

1 CNN模型概述

其实卷积神经网络(CNN)依旧是层级网络,只是层的功能和形式做了变化,主要是面对图像输入

1.1 卷积神经网络的层级结构

1.1.1 数据输入层/ Input layer

该层要做的处理主要是对原始图像数据进行预处理

1.1.2 卷积计算层/ CONV layer

这一层就是卷积神经网络最重要的一个层次,也是“卷积神经网络”的名字来源。在这个卷积层,有两个关键操作:
局部关联——每个神经元看做一个滤波器(filter)——相当于一个filter提取图像的一个特征图
窗口(receptive field)滑动——filter对局部数据计算——矩阵内积

一般要设置的超参数包括filters的数量、大小、步长,以及填充值(padding)

image

这里filters的数量为两个filter(w0,w1)大小为(3×3)步长为2

这里的蓝色矩阵就是输入的图像,灰色边框是填充值
粉色矩阵就是卷积层的filter
移动的蓝色矩阵就是窗口滑动,将窗口内的局部数据与粉色矩阵filter计算内积
绿色矩阵就是经过卷积运算后的输出矩阵

1.1.3 ReLU激励层 / ReLU layer

把卷积层输出结果做非线性映射,不过一般使用ReLU函数,它的特点是收敛快,求梯度简单,但较脆弱,图像如下:

ReLU

1.1.4 池化层 / Pooling layer

池化层夹在连续的卷积层中间, 用于在特征不变的基础上压缩数据和参数的量减小过拟合

这里里面没有参数需要我们学习,因为这里里面的参数都是我们设置好了,要么是Maxpooling,要么是Averagepooling
需要指定的超参数,包括是Max还是average,窗口大小以及步长
通常,我们使用的比较多的是Maxpooling,而且一般取大小为(2,2)步长为2的filter,这样,经过pooling之后,输入的长宽都会缩小2倍,特征不变

1.1.5 全连接层 / FC layer

和传统的神经网络一样,这一层是每一个单元都和前一层的每一个单元相连接,所以称之为“全连接”
这里要指定的超参数,无非就是神经元的数量,以及激活函数,一般最后一个全连接层才使用softmax函数(前面用relu是为了收敛快,最后softmax是为了输出结果)

1.2 CNN的特点

CNN相较于传统的神经网络,无非就是把FC改成了CONV和POOL,就是把传统的由一个个神经元组成的layer,变成了由filters组成的layer
优点

• 共享卷积核(一个filter对应一个参数),对高维数据处理无压力
• 无需手动选取特征,训练好权重,即得特征分类效果好

缺点

• 需要调参,需要大样本量,训练最好要GPU
• 物理含义不明确(也就说,我们并不知道没个卷积层到底提取到的是什么特征,而且神经网络本身就是一种难以解释的“黑箱模型”)

1.3 CNN结构演化历史

image

以上结构可查看《深度学习----CNN几种常见网络结构及区别》

2 标杆模型分析

标杆模型是基于Keras所构造的一个CNN卷积网络。
Keras是一个高级的Python神经网络框架,已被添加到TensorFlow中,成为其默认的框架,为TensorFlow提供更高级的API。
keras系列︱Sequential与Model模型、keras基本结构功能(一)

2.1 加载数据

将数据特征转换为矩阵,以便卷积计算

2.2 数据处理

①图像预处理:

利用中值滤波(median filter)进行降噪
——中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。
利用阈值分割法(threshold segmentation)生成掩膜(binary mask)
——图像阈值化的目的是要按照灰度级,对像素集合进行一个划分,得到的每个子集形成一个与现实景物相对应的区域,各个区域内部具有一致的属性,而相邻区域不具有这种一致属性。
利用形态闭合(morphology closing)来填充图中的小洞
——先膨胀(一般对二值图像进行操作。找到像素值为1的点,将它的邻近像素点都设置成这个值。1值表示白,0值表示黑,因此膨胀操作可以扩大白色值范围,压缩黑色值范围)再腐蚀(和膨胀相反的操作,将0值扩充到邻近像素),可用来填充孔洞。

②挑选异形样本并过采样:

因为训练集中没有异形样本,人工挑选5个异形样本加入训练

2.3 构造卷积神经网络

def built_model(): 
    n_filter=32; 
    model = Sequential() 
    model.add(Convolution2D(filters=n_filter, kernel_size=(5, 5), input_shape=(40, 40, 1), activation='relu'))
    model.add(Convolution2D(filters=n_filter, kernel_size=(5,5), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Convolution2D(filters=n_filter, kernel_size=(5,5), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Convolution2D(filters=n_filter, kernel_size=(3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.5))
    model.add(Flatten())
    model.add(Dense(units=128, activation='relu'))
    model.add(Dense(3, activation='softmax')) # Final Layer using Softmax
    model.compile(loss='categorical_crossentropy', 
                  optimizer=Adam(lr=0.0003),
                  metrics=['accuracy']) 
    model.summary()
    return model

流程:创建Sequential()对象(简单线性堆叠网络),逐层堆叠网络
[Convolution2D-> RELU]卷积层—— 【[Convolution2D-> RELU]卷积层——MaxPooling2D池化层】×3
——Dropout防止过拟合——Flatten压平,多维转为一维——[FC -> RELU]全连接层——[FC -> Softmax]全连接层

n_filter就是滤波器(filter)的个数,一般个数从少到多,本文统一为32个
model.compile()定义损失函数
model.summary()输出模型各层的参数状况,具体参数计算可参考《详细解释CNN卷积神经网络各层的参数和链接个数的计算》

2.4 训练卷积神经网络

①训练模型的同时进行数据增广:

datagen = ImageDataGenerator( rotation_range=180, width_shift_range=0.1, height_shift_range=0.1, horizontal_flip=True ) 
# 训练模型的同时进行数据增广
history=model.fit_generator(datagen.flow(x_train, y_train, batch_size=batch_size),
                            steps_per_epoch=len(x_train) / batch_size, epochs=epochs,
                            class_weight=class_weight, 
                            validation_data=datagen.flow(x_train, y_train, batch_size=batch_size), validation_steps=1)

ImageDataGenerator()是keras.preprocessing.image模块中的图片生成器,同时也可以在batch中对数据进行增强扩充数据集大小增强模型的泛化能力。比如进行旋转,变形,归一化等等。
因为异形样本较少,还设置class_weight损失权重,使得损失函数对异形样本更加关注。

②画epoch损失图:

2.5 提交结果

试着按照原代码,每一个epoch时间为150s(使用的是CPU所以计算较慢),经过100个epoch,最终提交成绩为0.95242

3 模型处理

3.1 模型调参和选择结构

3.1.1 调整卷积层和池化层数量

【[Convolution2D-> RELU]卷积层——MaxPooling2D池化层
——Dropout防止过拟合——Flatten压平,多维转为一维——[FC -> RELU]全连接层——[FC -> Softmax]全连接层

图1

【[Convolution2D-> RELU]卷积层——MaxPooling2D池化层】×2
——Dropout防止过拟合——Flatten压平,多维转为一维——[FC -> RELU]全连接层——[FC -> Softmax]全连接层

图2

【[Convolution2D-> RELU]卷积层——MaxPooling2D池化层】×3
——Dropout防止过拟合——Flatten压平,多维转为一维——[FC -> RELU]全连接层——[FC -> Softmax]全连接层

图3

由上往下,随着卷积层和池化层得增多,时耗增多,这是因为每一层卷积层都会增加参数数量。但发现图2表现最好,即下降得快且又平滑,

3.1.2 调整n_filter个数

在上面图1的基础上更改n_filter个数(速度较快)

n_filter=6
n_filter=36
n_filter=60

n_filter 越多,时耗越多,也是因为参数增多。但n_filter=36 时模型表现最好。

3.2 再增异形样本

以上损失图中最后epoch显示训练集和测试集的损失都接近0了,可提交上去仍未能前几。从竞赛前身《形状识别:是方还是圆》中仅对正方形和圆形识别,排行榜多为1.0,猜测是因为此竞赛因为多了异形判断,所以难达成100%的准确率。

尝试再增加不同的异形样本加入训练集中,刚好另一位博主的竞赛文章也加入了异形样本且成绩有所提高,引用该博主寻找的异形。

最终模型决定是:

def built_model(): 
    n_filter=36; 
    model = Sequential() 
    model.add(Convolution2D(filters=n_filter, kernel_size=(5, 5), input_shape=(40, 40, 1), activation='relu')) 
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Convolution2D(filters=n_filter, kernel_size=(3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.5))
    model.add(Flatten())
    model.add(Dense(units=128, activation='relu'))
    model.add(Dense(3, activation='softmax')) # Final Layer using Softmax
    model.compile(loss='categorical_crossentropy', 
              optimizer=Adam(lr=0.0003),
    metrics=['accuracy']) 
    model.summary()
    return model
num_anno=10
anno_idx=np.array([0,1, 4, 10, 13,4949, 4956, 4973, 4974, 4988])

3.3 提交结果

每一个epoch时间为60s,经过100个epoch,最终提交成绩为0.98767

小结

①了解了CNN模型,但未尝试更为复杂的结构(VGG、ResNet等)

②神经网络这种大量参数需要大量运算的,最好还是使用GPU版本(我安装失败就没用)

③本次并未对模型多大处理,因为标杆模型做的足够好,主要仅是消化CNN模型原理和简单运用

主要参考:
卷积神经网络CNN总结
【DL笔记6】从此明白了卷积神经网络(CNN)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351