利用Caffe+Python实现Kaggle上Digit Recognition练手项目

来源:互联网 发布:农村淘宝怎么加盟 编辑:程序博客网 时间:2024/06/05 11:40

准备工作

1、安装Caffe,我这里安装的是无GPU版本的Caffe,Caffe的安装教程自行百度,注意:编译Caffe时需要留出Python的接口,因为有许多功能是用Python实现的。

2、Python的安装一定要在Caffe编译之前安装,推荐一个博客:Windows+CPU only+VS2013安装caffe以及配置Python接口。

准备数据

1、从Kaggle上面下载所需要的数据:

点击这里进入Kaggle官网然后点Competitions:
如图

点击之后进入到这样的界面:

如图

然后就可以看到练手赛:Digit Recognition:

这里写图片描述

继续点击进入该比赛:

这里写图片描述

然后下载数据:

这里写图片描述

数据处理

从Kaggle上面下载下来的数据是csv格式的数据,需要我们转换成图片格式的数据,我这里用Python代码实现转换,原理就是先生成一个空的图片,然后将下载下来的csv格式数据中的每一张图片像素点一次填入一张图像中,就得到了我们需要的数字图片,注意,官网数据是28*28大小的图片,所以我们转换时最好转换成28*28大小的图片。
具体代码:(我对于Python还处于陌生阶段,见谅不能更详细的解说):

# -*- coding:utf-8 -*-# 训练数据提取部分代码from PIL import Imageimport osimport numpy as npimport pandas as pdtrain=pd.read_csv('E:\\Kaggle\\DigitRecognition\\train.csv')trainData=train.values[:, 1:]trainLabels=train.values[:, 0]# 写入标签数据,并利用像素点填充的方法讲矩阵中的像素点采用RGB模式填入一张图片中,# R=G=B代表灰度图片file = open('E:\\Kaggle\\DigitRecognition\\label.txt', 'w')img=Image.new('RGB', (28, 28), 0x000000)img_array=img.load()for line in range(0, 42000):    num=0    for x in range(28):        for y in range(28):            #将RGB三个分量取相等就表示灰度图            img_array[y, x] = (255-trainData[line, num], 255-trainData[line, num], 255-trainData[line, num])            num = num + 1    img.save('E:\Kaggle\DigitRecognition\\trainImages\\'+str(line)+'.jpg')    file.write('E:\Kaggle\DigitRecognition\\trainImages\\'+str(line)+'.jpg' + ' ' +str(trainLabels[line])+'\n')file.close()

测试数据的提取代码:(注意路径,时绝对路径,也可以使用相对路径)

# -*- coding:utf-8 -*-from PIL import Imageimport osimport numpy as npimport pandas as pdtest=pd.read_csv('E:\\Kaggle\\DigitRecognition\\test.csv')testData=test.values[:, :]img=Image.new('RGB',(28, 28), 0x000000)img_array=img.load()for line in range(0, 28000):    num = 0    for x in range(28):        for y in range(28):            img_array[y, x] = (255-testData[line, num], 255-testData[line, num], 255-testData[line, num])            num = num+1    img.save('E:\\Kaggle\\DigitRecognition\\testImage\\'+str(line)+'.jpg')

转换之前的数据和转换之后的数据对比:
train.csv:
train.csv

trainImage:
trainImage

转换成功之后,就可以用Caffe进行训练了。

Caffe训练图片数据

这里直接使用Caffe中mnist手写体数字识别时使用的配置文件,但有些地方改动了一下,改动的地方如下:

lenet_train_test.prototxt:
修改了原来的输入数据层,原来的配置文件需要输入lmdb/leveldb的文件,本次直接使用原始的图片进行训练,因为在转换成图片时已经进行了图片归一化(28*28),修改之后的对比如下:

1、修改之后的配置文件:

这里写图片描述

2、原来的配置文件:

这里写图片描述

怎么修改网络层我也不是你很清楚,大神教我的,还没学会。。。。。

然后,lenet_solver.prototxt配置文件只需要注意图中两个地方就OK

这里写图片描述
其他的参数我使用的是原来默认的参数大小。

然后就是进行训练了。

3、训练模型:

我没有编写bat文件,直接在命令行中进行训练的,命令一毛一样啊!!
另外,我的整个项目所包含的文件内容如下图:

这里写图片描述

其中有些文件是我训练好的模型文件。
(r.csv是我对28000张图片的预测结果)

然后在上图中的文件夹内,先按下shift键不松手,然后右键,如下图:

这里写图片描述

直接打开命令行就行,然后输入命令:

Build\x64\Release\caffe.exe train -solver examples/mnist/lenet_solver.prototxt

注意路径的问题,使用时需要修改路径。
这里写图片描述

开始训练之后的窗口如图:

这里写图片描述

等训练结束之后,我们在文件夹中就可以得到训练好的模型:

这里写图片描述

进行预测

我用python实现的预测,如果各位有更好的代码,谢谢分享到我的邮箱号码?真的需要,因为我是小白啊~~~

识别代码:

# -*- coding:utf-8 -*-import caffeimport numpy as nproot='E:/Kaggle/DigitRecognition/'      #根目录deploy=root+'lenet.prototxt'   #描述文件caffe_model=root+'lenet_iter_10000.caffemodel'    #训练好的caffe模型img_root='E:/Kaggle/DigitRecognition/testImage/'#加载caffe模型net=caffe.Net(deploy,caffe_model,caffe.TEST)file=open('E:/Kaggle/DigitRecognition/result.txt','w')for num in range(28001):    # 图片预处理设置    img = img_root + str(num)+'.jpg'    transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})  # 设定图片的shape格式(1,3,28,28)    transformer.set_transpose('data', (2, 0, 1))  # 改变维度的顺序,由原始图片(28,28,3)变为(3,28,28)    # transformer.set_mean('data', np.load(mean_file).mean(1).mean(1))    #减去均值,前面训练模型时没有减均值,这儿就不用    transformer.set_raw_scale('data', 255)  # 缩放到【0,255】之间    transformer.set_channel_swap('data', (2, 1, 0))  # 交换通道,将图片由RGB变为BGR    im = caffe.io.load_image(img)  # 加载图片    net.blobs['data'].data[...] = transformer.preprocess('data', im)  # 执行上面设置的图片预处理操作,并将图片载入到blob中    # 执行测试    out = net.forward()    # labels = np.loadtxt(labels_filename, str, delimiter='\t')   #读取类别名称文件    prob = net.blobs['prob'].data[0].flatten()  # 取出最后一层(Softmax)属于某个类别的概率值,并打印    # print prob    order = prob.argsort()[-1]  # 将概率值排序,取出最大值所在的序号    #print order  # 将该序号转换成对应的类别名称,并打印    file.write(str(num+1)+ '\t' + str(order)+'\n')file.close()

识别之后我是将识别结果保存到一个txt文件中的,然后再将txt文件转换成csv文件,最后上传到Kaggle的。

识别之后的txt结果如下:

这里写图片描述

最后将txt转换为csv的python代码如下:

import numpy as np  import pandas as pd  txt = np.loadtxt('file.txt')  txtDF = pd.DataFrame(txt)  txtDF.to_csv('file.csv',index=False)  

总结(moulei007@gmail.com)

以上就是我对机器学习的初步认识,真的还只是皮毛,甚至连皮毛都没碰到,往后续努力,虽然目前不知道该如何进行下一步的学习,只能想到一点就往下学一点,唉,继续努力吧!希望有大神指导,谢谢!!!