利用Caffe+Python实现Kaggle上Digit Recognition练手项目
准备工作
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 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:
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 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结果如下:
最后将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)
以上就是我对机器学习的初步认识,真的还只是皮毛,甚至连皮毛都没碰到,往后续努力,虽然目前不知道该如何进行下一步的学习,只能想到一点就往下学一点,唉,继续努力吧!希望有大神指导,谢谢!!!