欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-14 12:24:52
...

准备工作

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

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

准备数据

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

点击这里进入Kaggle官网然后点Competitions:
利用Caffe+Python实现Kaggle上Digit Recognition练手项目

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

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

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

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

继续点击进入该比赛:

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

然后下载数据:

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

数据处理

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

# -*- coding:utf-8 -*-
# 训练数据提取部分代码

from PIL import Image
import os
import numpy as np
import pandas as pd

train=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 Image
import os
import numpy as np
import pandas as pd

test=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:
利用Caffe+Python实现Kaggle上Digit Recognition练手项目

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

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

Caffe训练图片数据

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

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

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

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

2、原来的配置文件:

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

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

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

利用Caffe+Python实现Kaggle上Digit Recognition练手项目
其他的参数我使用的是原来默认的参数大小。

然后就是进行训练了。

3、训练模型:

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

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

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

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

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

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

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

注意路径的问题,使用时需要修改路径。
利用Caffe+Python实现Kaggle上Digit Recognition练手项目

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

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

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

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

进行预测

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

识别代码:

# -*- coding:utf-8 -*-
import caffe
import numpy as np
root='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结果如下:

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

最后将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)  

总结(aaa@qq.com)

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