我是参加DataCastle猫狗大战的选手,kuhung。在测评中,我提交的数据集最后评分0.98639。以下是我的备战过程及心得体会。(最后有完整代码及较全面的注释)

在猫狗大战中参赛者需要从训练集里建立一个模型去识别测试集里的小狗来。谁能识别出最多的数量,谁的成绩就更好。

参赛者需要提交你识别出认为是小狗图片的图片名,不包括文件类型,例如:xabcd.jpg,则提交的uid为xabcd。


个人介绍

华中科技大学机械学院的大二(准大三)学生,接触数据挖掘快有一年了。早期在学生团队做过一些D3数据可视化方面的工作,今年上半年开始数据挖掘实践。想把这个爱好发展成事业。做过阿里的天池竞赛,也有在kaggle混迹。算个数据新手,但一直不承认:你是新人,所以成绩不好看没啥关系。


初识比赛

第一次接触数据集,就感觉有些难度。因为以前没做过图片分类的比赛,更没想过要用深度学习的神经网络进行识别。思索一番,还是觉得特征提取后,使用决策树靠谱。自己也下去找过资料,发现并不容易实现。期间,还曾一度想过肉眼识别。但打开文件,看到那1400+图片,就觉得这时间花在肉眼识别上不值。中间一度消停。


初见曙光——yinjh战队分享

后来上论坛逛过几次。一次偶然的机会,让我看到了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,一举升到第一。


比赛总结

这次比赛,首先还得感谢yinjh团队的yin前辈。如果没有您分享的代码,就不会有我今天的成绩。感谢您分享的代码,感想您在我写这篇分享时提供的代码指导。 再者,感谢我的女票晶晶,谢谢你一直陪在我身边,谢谢你包容我写代码时不那么快的回复手速。我是新手,但我一直不觉得成绩低是理所当。立志从事这一行,就需要快速地学习、快速地成长。新人,也需要做到最好。当然,自己目前还存在很多问题。一些基本的概念只是模糊掌握,需要更多的实践,需要更多的理论积淀,而不是简单地做一个调包侠。


给新手的建议

善用搜索引擎,多读官方文档,不要一开始就依赖Google。

Google Groups、Stack Overflow、GitHub是好东西。

干!就是干!


全部代码

以下操作均在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 Sequentialfrom keras.layers.core import Flatten, Dense, Dropoutfrom keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2Dfrom keras.optimizers import SGDimport 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=0
p=0
temp=0
定义图像加载函数
In [ ]:
def load_image(imageurl):im = cv2.resize(temp ,(224,224)).astype(np.float32)im[:,:,0] -= 103.939im[:,:,1] -= 116.779im[:,:,2] -= 123.68im = 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:  passelse: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]

查看DataCastle文章原文

在github上获取代码


DataCastle[猫狗大战]冠军——Kuhung 思路及代码相关推荐

  1. DataCastle[猫狗大战] ——Yinjh比赛全部代码

    DataCastle猫狗大战参赛者需要从训练集里建立一个模型去识别测试集里的小狗来.谁能识别出最多的数量,谁的成绩就更好. 参赛者需要提交你识别出认为是小狗图片的图片名,不包括文件类型,例如:xabc ...

  2. DataCastle[猜你喜欢]推荐系统竞赛——Kuhung思路及代码

    概况介绍 我是参加DataCastle[猜你喜欢]推荐系统的kuhung.在截止竞赛日期的测评榜中,我的团队--猜你不喜欢,以7.86565的最终成绩,位居第二.接下来我将分享我的比赛心得及才赛代码. ...

  3. [IOS]iphone开发之常用代码:不断更新

    1,获取翻转事件,并开启翻转: 只要在viewcontroller的类中加入 -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOri ...

  4. [转]AES加密算法及java代码实现

    转自:http://www.cnblogs.com/block2016/p/5596676.html AES加密 AES是一个对称密码,旨在取代DES成为广泛使用的标准. 一.AES的加密过程 二.A ...

  5. [猜你喜欢]冠军 yes,boy! 分享 | 推荐系统也可以很简单 做个记录 以后方便学习

    DC 关于分享 无论是充满"魔性"的"yes,boy!"这个昵称,还是诸神无法超越的7.89645分,都让这次[猜你喜欢]冠军充满了神秘色彩,最关键的是,&qu ...

  6. Linux RCU机制详解[转]

    一:前言 RCU机制出现的比较早,只是在linux kernel中一直到2.5版本的时候才被采用.关于RCU机制,这里就不做过多的介绍了,网上有很多有关RCU介绍和使用的文档.请自行查阅.本文主要是从 ...

  7. 收藏一篇访谈并做笔记:《[独家]与周鸿祎谈乔布斯》

    五点第一觉醒来,看到Apple4us上的一篇访谈<[独家]与周鸿祎谈乔布斯>,通读下来,甚是喜欢.周鸿祎的每一个回答我都非常认同,也想到了一些自己正在做的事,错误与正确.同时,这让我对周鸿 ...

  8. 使用json web token[转]

    使用json web token[转] 由来 做了这么长时间的web开发,从JAVA EE中的jsf,spring,hibernate框架,到spring web MVC,到用php框架thinkPH ...

  9. [Linux]从控制台一次读取一个字符,无需等待回车键

    [Linux]从控制台一次读取一个字符,无需等待回车键 周银辉 读取字符嘛,可以使用getchar(),getch()等等函数,但它们都需要等待回车键以结束输入,而不是按下键盘时立即响应,看上去不那么 ...

最新文章

  1. Element 'dependency' cannot have character [children], because the type's content type is element-on
  2. Stas and the Queue at the Buffet
  3. 断言、触发器、存储过程
  4. 全网都在看的Jmeter精选原创文章
  5. 概率图模型(PGM)/马尔可夫随机场(MRF)/条件随机场基本概念(CRF)
  6. 任何人都可以胜任全栈开发?
  7. iFrame只要竖滚动条,不要横滚动条
  8. MacOS自定义设置定时开关机?
  9. 分布式存储 HDFS原理
  10. Keil 5模块化编程详细步骤
  11. Unity快速安装教程
  12. React项目实战(一)
  13. 如何在Mac上清理磁盘空间?
  14. Selenium WebDriver 常用API
  15. 疫情过后,制造业中小企业应用工业互联网数字化转型之路的探讨
  16. 苹果x为什么总黑屏_苹果X突然黑屏重启怎么回事?教你强制重启方法
  17. 解决:linux启动Redis报Failed to search for file:Cannot prepare internal mirrorlist: No URLs in mirrorlist
  18. MySQL数据库实操教程(15)——表的关联关系
  19. 超像素论文(三)——AINet: Association Implantation for Superpixel Segmentation
  20. 蔚来汽车自动驾驶部门招聘自动驾驶算法研发框架实习生

热门文章

  1. kylin版本_如何在 Kylin 中优雅地使用 Spark
  2. 天辰的救赎(JS)第一章(救赎之地)
  3. Python自动化连接谷歌浏览器
  4. iOS上传视频到服务器
  5. 修改element ui中form表单的 label 颜色样式
  6. Mac下Charles踩坑记录
  7. 如何选择一个合适高效率的光纤熔接机--TFN FM-82
  8. wineHQ安装VC6
  9. python crop
  10. 人脸识别---闭集测试评价指标CMC曲线(rank)