我是如何快速拿下datacastle图像识别竞赛“猫狗大战”冠军的 | 含全代码和详细说明

接触数据挖掘快有一年了,早期在学生团队做过一些D3数据可视化方面的工作,今年上半年开始数据挖掘实践。想把这个爱好发展成事业。有在kaggle混迹,算个数据新手,但一直不承认:你是新人,所以成绩不好看没啥关系。

小试牛刀

之前偶然的机会看到了datacastle大数据竞赛平台的“猫狗大战”竞赛,本着好奇和体验一下的心态就参加了。但是我本身对图像识别这一块并不是特别熟悉,所以在前期的上手过程中遇到了很多麻烦,甚至一度有放弃的想法。在很长一段时间内,我都没有去思考有关这个竞赛的问题。

过程艰难

一开始,我就把一屏的代码放进了我的jupyter notebook中,一步一步试水。很明显,我的很多依赖包都没安装,所以也是错误不断。

早先是在Windows系统下,使用python2.7,需要什么包,就安装什么包。在安装keras过程中,我发现了Anaconda——很好用的一个科学计算环境,集成了各种数据挖掘包。即使是这样,仍然是满屏的错误,亟待排查。

初见曙光

后来上论坛逛过几次。一次偶然的机会,让我看到了yinjh团队分享的vgg16模型。乍一看,代码简单、效果不错。更为重要的是,这个模型自己以前从未见过。于是抱着验证学习的态度,我把代码扣了下来,打算自己照着做一遍。

一开始,我就把一屏的代码放进了我的jupyter notebook中,一步一步试水。很明显,我的很多依赖包都没安装,所以也是错误不断。

早先是在Windows系统下,使用python2.7,需要什么包,就安装什么包。在安装keras过程中,我发现了Anaconda——很好用的一个科学计算环境,集成了各种数据挖掘包。即使是这样,仍然是满屏的错误,亟待排查。

欣喜万分

离比赛截止就还只有几天,一边准备期末考试,一边焦急地排查bug。Windows系统下仍有个别难以解决的错误,我索性切换到了做NAO机器人时装的Ubuntu系统下。

结合keras给的官方文档,我对原代码进行了函数拆分解耦,又在循环体部分增加了异常检测。综合考虑性能,稍微修改了循环结构。下载好训练的vgg16_weights,在没有错误之后,焦急地等待25分钟后,屏幕开始打印结果。

第一次提交,随便截取了前面一段,没成绩。折腾了几次,才发现是提交的格式出了问题。后面取p=0.99+部分,提交结果在0.58左右,数据集大概有90个。

估计了下,狗狗总数应该在180左右。第二次提交,取了180左右,结果0.97多一点。第三次,也是最后一次提交,取了result前189个,结果0.98639,一举升到第一。

代码分享及思路详解

以下操作均在Ubuntu14.04+Anaconda中进行   

导入python标准包

In [ ]:

import os   # 处理字符串路径

import glob  # 用于查找文件

导入相关库

  • keras

    • keras是基于Theano的深度学习(Deep Learning)框架
    • 详细信息请见keras官方文档
安装过程

conda update conda

conda update --all

conda install mingw libpython

pip install git+git://github.com/Theano/Theano.git

pip install git+git://github.com/fchollet/keras.git

  • cv2

    • OpenCV库

      conda isntall opnecv

  • numpy
    • Anaconda自带

In [ ]:


from keras.models import Sequential
from keras.layers.core import Flatten, Dense, Dropout
from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D
from keras.optimizers import SGD
import cv2, numpy as np

使用keras建立vgg16模型

  • 参考官方示例

In [ ]:

def VGG_16(weights_path=None):

    model = Sequential()

    model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))

    model.add(Convolution2D(64, 3, 3, activation=‘relu‘))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(64, 3, 3, activation=‘relu‘))

    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(128, 3, 3, activation=‘relu‘))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(128, 3, 3, activation=‘relu‘))

    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(256, 3, 3, activation=‘relu‘))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(256, 3, 3, activation=‘relu‘))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(256, 3, 3, activation=‘relu‘))

    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(512, 3, 3, activation=‘relu‘))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(512, 3, 3, activation=‘relu‘))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(512, 3, 3, activation=‘relu‘))

    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(512, 3, 3, activation=‘relu‘))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(512, 3, 3, activation=‘relu‘))

    model.add(ZeroPadding2D((1,1)))

    model.add(Convolution2D(512, 3, 3, activation=‘relu‘))

    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(Flatten())

    model.add(Dense(4096, activation=‘relu‘))

    model.add(Dropout(0.5))

    model.add(Dense(4096, activation=‘relu‘))

    model.add(Dropout(0.5))

    model.add(Dense(1000, activation=‘softmax‘))

    if weights_path:

        model.load_weights(weights_path)

    return model

引入训练好的vgg16_weights模型

Note:

  • vgg16_weights.h5需单独下载,并与代码文件处于同一文件夹下,否则会报错。

    • 网上有资源 附百度云盘链接 vgg16_weights.h5下载

In [ ]:

model = VGG_16(‘vgg16_weights.h5‘)

In [ ]:

sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)model.compile(optimizer=sgd, loss=‘categorical_crossentropy‘)

猫和狗的特征

In [ ]:

dogs=[251, 268, 256, 253, 255, 254, 257, 159, 211, 210, 212, 214, 213, 216, 215, 219, 220, 221, 217, 218, 207, 209, 206, 205, 208, 193, 202, 194, 191, 204, 187, 203, 185, 192, 183, 199, 195, 181, 184, 201, 186, 200, 182, 188, 189, 190, 197, 196, 198, 179, 180, 177, 178, 175, 163, 174, 176, 160, 162, 161, 164, 168, 173, 170, 169, 165, 166, 167, 172, 171, 264, 263, 266, 265, 267, 262, 246, 242, 243, 248, 247, 229, 233, 234, 228, 231, 232, 230, 227, 226, 235, 225, 224, 223, 222, 236, 252, 237, 250, 249, 241, 239, 238, 240, 244, 245, 259, 261, 260, 258, 154, 153, 158, 152, 155, 151, 157, 156]cats=[281,282,283,284,285,286,287]

待处理文件导入

Note:

  • 将测试集改名为test,放入imgs文件夹下,imgs文件夹又与此代码处于同一文件夹下。
  • 当然,你也可以修改下面的路径。

In [ ]:

path = os.path.join(‘imgs‘, ‘test‘, ‘*.jpg‘)  #拼接路径
 files = glob.glob(path) #返回路径

定义几个变量

In [ ]:

result=[]

In [ ]:

flbase=0p=0temp=0

定义图像加载函数

In [ ]:

def load_image(imageurl):
    im = cv2.resize(temp ,(224,224)).astype(np.float32)
    im[:,:,0] -= 103.939
    im[:,:,1] -= 116.779
    im[:,:,2] -= 123.68
    im = im.transpose((2,0,1))
    im = np.expand_dims(im,axis=0)
    return im

定义预测函数

In [ ]:

def predict(url):
    im = load_image(url)        
    out = model.predict(im)
    flbase = os.path.basename(url)
    p = np.sum(out[0,dogs]) / (np.sum(out[0,dogs]) + np.sum(out[0,cats]))
    result.append((flbase,p))

开始预测

Note:

  • 此处的if,else异常检测很重要,因为cv2.imread(fl)在遇到某几张图时会为空,抛出错误,程序中途停止,图片集得不到完全检测。
  • 一般配置电脑跑这部分时,大约需要20~30分钟,不是程序没有工作,请耐心等待。

In [ ]:

for fl in files:
    temp=cv2.imread(fl) 
    if  temp ==None:  
        pass
    else:
        predict(fl)

对结果进行排序

In [ ]:

result=sorted(result, key=lambda x:x[1], reverse=True)

打印预测结果与相应概率

In [ ]:

for x in result:
    print x[0],x[1]

预测结果

  • 根据上面的概率,选择相应的前多少张图片
  • 复制进csv文件,使用一般编辑器将".jpg"以空格替代

In [ ]:

for x in result:
    print x[0]

ps:完整的代码可以在github下载

https://github.com/KuHung/DateCastle/blob/master/catdog.ipynb

关注datacastle查看更多竞赛信息和技术分享

时间: 2024-11-08 08:17:41

我是如何快速拿下datacastle图像识别竞赛“猫狗大战”冠军的 | 含全代码和详细说明的相关文章

学习Keras:《Keras快速上手基于Python的深度学习实战》PDF代码+mobi

有一定Python和TensorFlow基础的人看应该很容易,各领域的应用,但比较广泛,不深刻,讲硬件的部分可以作为入门人的参考. <Keras快速上手基于Python的深度学习实战>系统地讲解了深度学习的基本知识.建模过程和应用,并以深度学习在推荐系统.图像识别.自然语言处理.文字生成和时间序列中的具体应用为案例,详细介绍了从工具准备.数据获取和处理到针对问题进行建模的整个过程和实践经验. <Keras快速上手>PDF,531页,带书签目录,彩色配图,文字可以复制. 配套源代码和

Angular2快速入门-3.多个组件(分离新闻列表页和详细页)

上篇(Angular2快速入门-2.创建一个新闻列表)已经完成新闻列表的展示,并且点击新闻列表的时候,下面可以展示出新闻的详细信息,这节我们把新闻详细和新闻列表页面分离出来 新闻详细单独一个component 第一.创建news-detail.component 1)创建news-detail.component.ts import {Component,Input} from '@angular/core'; import {News} from './news'; @Component({

江苏省2017年高等数学竞赛本二试题(含解答)

模糊, 所以我也不看了.

我是这样一步步理解--主题模型(Topic Model)、LDA(案例代码)

1. LDA模型是什么 LDA可以分为以下5个步骤: 一个函数:gamma函数. 四个分布:二项分布.多项分布.beta分布.Dirichlet分布. 一个概念和一个理念:共轭先验和贝叶斯框架. 两个模型:pLSA.LDA. 一个采样:Gibbs采样 关于LDA有两种含义,一种是线性判别分析(Linear Discriminant Analysis),一种是概率主题模型:隐含狄利克雷分布(Latent Dirichlet Allocation,简称LDA),本文讲后者. 按照wiki上的介绍,L

vuex 快速上手,具体使用方法总结(含使用例子)

网上有关vuex的文章很多,我这里只讲实用的: vuex 用处:管理全局状态(类似全局变量,每个组件都能访问到) vuex 用法: //下面是一个js文件,用最简单最全的例子展示了全局数据 city 和 cityID 的声明以及改变的方法: import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { city: '深圳', cityID: "1&quo

Linux--如何通过图形界面选项快速更改ubuntu的窗口、图标、分辨率大小,超详细超实用~(适合所有人群)

这是默认ubuntu给出的分辨率大小:800*600,说实话有点小不适合操作. (分辨率800*600) 这是调整后的分辨率大小. (分辨率1400*900) 操作方法: 首先点击选项框中的设置图标-显示(Displays),进入到页面窗口操作区: 接着在分辨率(Resolution)中选择合适的分辨率,个人建议1440*900最适合, 在Launcher placement 中选择All displays 在Scale for menu and title bars:滑为 1 最适合 记住很重

Java 常用快捷键

大多数快捷键在苹果下对应Cmd,在Windows下对应Ctrl键 Ctrl+1快捷修复 Ctrl+d快捷删除行 Ctrl+F11快速运行项目 shift+enter 切换下一行 Alt+上下箭头 快速移动行 Ctrl+Alt+上下箭头快速复制行 Ctrl+M 放大工作区 Alt+/ 补全代码 Ctrl+/ 快速注释多行

OI 助手 | 简洁快速的 OI 工具箱 (原 竞赛目录生成)

原竞赛目录生成 (4.0 版本前) 开发者:abc2237512422 OI 助手是一个轻量简洁的 OI 工具箱.你可以使用它来快速进行 OI 竞赛中一些繁琐的操作,例如生成竞赛目录.对拍.它为你省去了手动做这些操作的时间. 官网:oitoolbox.github.io 点击跳转到官网 主要功能 竞赛目录生成 快速地生成 OI 竞赛目录 只需输入选手姓名,题目名称,即可快速生成 OI 竞赛目录. · 自定义生成的文件类型 - 您可以自由的选择要生成的文件类型,如 cpp.pas.in.out 文

5A拿下PMP

首先能以5A的成绩拿下PMP,是我意想不到的.在这里非常感谢王安老师,感谢班主任木木,感谢各位班委们和同学们.是他们的帮助让我能够更好.更努力.更有方向性的去学习这门PMP.我是在8月份中旬的时候报名,参加的是12月份的考试.报考时间不是越早越好,正常是2-3个月的学习时间就足够了.因为我们每个人都会有自己的一个临界点,有些人过早参与,后期学习可能会越来越累.想要报考的话,可以跟老师咨询好.以下我说一下关于我的一些学习方法跟答题方法:重点:将王安老师.班主任设为特别关注,一定要留意老师说的话,按