Skip to content

Commit ad44a94

Browse files
committed
dive into keras, some useful code
1 parent 7e4b0a0 commit ad44a94

File tree

8 files changed

+314
-3
lines changed

8 files changed

+314
-3
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
2+
[上一篇文章](http://blog.csdn.net/u012162613/article/details/45397033)总结了Keras的基本使用方法,相信用过的同学都会觉得不可思议,太简洁了。十多天前,我在github上发现这个框架的时候,关注Keras的人还比较少,这两天无论是github还是微薄,都看到越来越多的人关注和使用Keras。所以这篇文章就简单地再介绍一下Keras的使用,方便各位入门。
3+
4+
主要包括以下三个内容:
5+
6+
- 训练CNN并保存训练好的模型。
7+
- 将CNN用于特征提取,用提取出来的特征训练SVM。
8+
- 可视化CNN卷积层后的特征图。
9+
10+
仍然以Mnist为例,代码中用的Mnist数据到这里下载
11+
[http://pan.baidu.com/s/1qCdS6](http://pan.baidu.com/s/1qCdS6),本文的代码在我的github上:[dive_into _keras](https://github.com/wepe/MachineLearning/tree/master/DeepLearning%20Tutorials)
12+
13+
14+
----------
15+
16+
17+
###1. 加载数据
18+
19+
数据是图片格式,利用pyhton的PIL模块读取,并转为numpy.array类型。这部分的代码在`data.py`里:
20+
21+
22+
----------
23+
24+
25+
###2. 训练CNN并保存训练好的CNN模型
26+
27+
将上一步加载进来的数据分为训练数据(X_train,30000个样本)和验证数据(X_val,12000个样本),构建CNN模型并训练。训练过程中,每一个epoch得到的val-accuracy都不一样,我们保存达到最好的val-accuracy时的模型,利用Python的cPickle模块保持。(Keras的开发者最近在添加用hdf5保持模型的功能,我试了一下,没用成功,去github发了issue也没人回,估计还没完善,hdf5压缩率会更高,保存下来的文件会更小。)
28+
29+
这部分的代码在`cnn.py`里,运行:
30+
31+
```
32+
python cnn.py
33+
```
34+
35+
在第Epoch 4得到96.45%的validation accuracy,运行完后会得到model.pkl这份文件,保存的就是96.45%对应的模型:
36+
37+
![这里写图片描述](http://img.blog.csdn.net/20150508155724085)
38+
39+
40+
----------
41+
42+
43+
###3.将CNN用于特征提取,用提取出来的特征训练SVM
44+
45+
上一步得到了一个val-accuracy为96.45%的CNN模型,在一些论文中经常会看到用CNN的全连接层的输出作为特征,然后去训练其他分类器。这里我也试了一下,用全连接层的输出作为样本的特征向量,训练SVM。SVM用的是scikit learn里的算法。
46+
47+
这部分代码在`cnn-svm.py`,运行:
48+
49+
```
50+
python cnn-svm.py
51+
```
52+
53+
得到下图的输出,可以看到,cnn-svm的准确率提高到97.89%:
54+
55+
![这里写图片描述](http://img.blog.csdn.net/20150508155806689)
56+
57+
58+
----------
59+
60+
61+
###4.可视化CNN卷积层后的特征图
62+
63+
将卷积层和全连接层后的特征图、特征向量以图片形式展示出来,用到matplotlib这个库。这部分代码在`get_feature_map.py`里。运行:
64+
65+
```
66+
python get_feature_map.py
67+
```
68+
69+
得到全连接层的输出,以及第一个卷积层输出的4个特征图:
70+
71+
![全连接层后的输出](http://img.blog.csdn.net/20150508155842678)
72+
73+
![这里写图片描述](http://img.blog.csdn.net/20150508155724909)
74+
75+
![这里写图片描述](http://img.blog.csdn.net/20150508155810914)
76+
77+
![这里写图片描述](http://img.blog.csdn.net/20150508155833190)
78+
79+
![这里写图片描述](http://img.blog.csdn.net/20150508160043578)
80+
81+
82+
----------
83+
转载请注明出处:http://blog.csdn.net/u012162613/article/details/45581421
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'''
2+
Author:wepon
3+
Code:https://github.com/wepe
4+
5+
File: cnn-svm.py
6+
'''
7+
from __future__ import print_function
8+
import cPickle
9+
import theano
10+
from sklearn.ensemble import RandomForestClassifier
11+
from sklearn.svm import SVC
12+
from data import load_data
13+
14+
15+
def svc(traindata,trainlabel,testdata,testlabel):
16+
print("Start training SVM...")
17+
svcClf = SVC(C=1.0,kernel="rbf",cache_size=3000)
18+
svcClf.fit(traindata,trainlabel)
19+
20+
pred_testlabel = svcClf.predict(testdata)
21+
num = len(pred_testlabel)
22+
accuracy = len([1 for i in range(num) if testlabel[i]==pred_testlabel[i]])/float(num)
23+
print("cnn-svm Accuracy:",accuracy)
24+
25+
def rf(traindata,trainlabel,testdata,testlabel):
26+
print("Start training Random Forest...")
27+
rfClf = RandomForestClassifier(n_estimators=400,criterion='gini')
28+
rfClf.fit(traindata,trainlabel)
29+
30+
pred_testlabel = rfClf.predict(testdata)
31+
num = len(pred_testlabel)
32+
accuracy = len([1 for i in range(num) if testlabel[i]==pred_testlabel[i]])/float(num)
33+
print("cnn-rf Accuracy:",accuracy)
34+
35+
if __name__ == "__main__":
36+
#load data,split into traindata and testdata
37+
data, label = load_data()
38+
(traindata,testdata) = (data[0:30000],data[30000:])
39+
(trainlabel,testlabel) = (label[0:30000],label[30000:])
40+
#use origin_model to predict testdata
41+
origin_model = cPickle.load(open("model.pkl","rb"))
42+
pred_testlabel = origin_model.predict_classes(testdata,batch_size=1, verbose=1)
43+
num = len(testlabel)
44+
accuracy = len([1 for i in range(num) if testlabel[i]==pred_testlabel[i]])/float(num)
45+
print(" Origin_model Accuracy:",accuracy)
46+
#define theano funtion to get output of FC layer
47+
get_feature = theano.function([origin_model.layers[0].input],origin_model.layers[11].output(train=False),allow_input_downcast=False)
48+
feature = get_feature(data)
49+
#train svm using FC-layer feature
50+
svc(feature[0:30000],label[0:30000],feature[30000:],label[30000:])
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#coding:utf-8
2+
3+
'''
4+
Author:wepon
5+
Code:https://github.com/wepe
6+
7+
File:cnn.py
8+
GPU run command:
9+
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python cnn.py
10+
CPU run command:
11+
python cnn.py
12+
'''
13+
#导入各种用到的模块组件
14+
from __future__ import absolute_import
15+
from __future__ import print_function
16+
from keras.models import Sequential
17+
from keras.layers.core import Dense, Dropout, Activation, Flatten
18+
from keras.layers.convolutional import Convolution2D, MaxPooling2D
19+
from keras.optimizers import SGD
20+
from keras.utils import np_utils, generic_utils
21+
from six.moves import range
22+
from data import load_data
23+
import random,cPickle
24+
25+
26+
nb_epoch = 5
27+
batch_size = 100
28+
nb_class = 10
29+
#加载数据
30+
data, label = load_data()
31+
32+
#label为0~9共10个类别,keras要求格式为binary class matrices,转化一下,直接调用keras提供的这个函数
33+
label = np_utils.to_categorical(label, nb_class)
34+
35+
#14layer, one "add" represent one layer
36+
def create_model():
37+
model = Sequential()
38+
model.add(Convolution2D(4, 1, 5, 5, border_mode='valid'))
39+
model.add(Activation('relu'))
40+
41+
model.add(Convolution2D(8,4, 3, 3, border_mode='valid'))
42+
model.add(Activation('relu'))
43+
model.add(MaxPooling2D(poolsize=(2, 2)))
44+
45+
model.add(Convolution2D(16, 8, 3, 3, border_mode='valid'))
46+
model.add(Activation('relu'))
47+
model.add(MaxPooling2D(poolsize=(2, 2)))
48+
49+
model.add(Flatten())
50+
model.add(Dense(16*4*4, 128, init='normal'))
51+
model.add(Activation('relu'))
52+
model.add(Dropout(0.2))
53+
54+
model.add(Dense(128, nb_class, init='normal'))
55+
model.add(Activation('softmax'))
56+
return model
57+
58+
59+
#############
60+
#开始训练模型
61+
##############
62+
model = create_model()
63+
sgd = SGD(l2=0.0,lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
64+
model.compile(loss='categorical_crossentropy', optimizer=sgd)
65+
66+
(X_train,X_val) = (data[0:30000],data[30000:])
67+
(Y_train,Y_val) = (label[0:30000],label[30000:])
68+
best_accuracy = 0.0
69+
for e in range(nb_epoch):
70+
#shuffle the data each epoch
71+
num = len(Y_train)
72+
index = [i for i in range(num)]
73+
random.shuffle(index)
74+
X_train = X_train[index]
75+
Y_train = Y_train[index]
76+
77+
print('Epoch', e)
78+
print("Training...")
79+
batch_num = len(Y_train)/batch_size
80+
progbar = generic_utils.Progbar(X_train.shape[0])
81+
for i in range(batch_num):
82+
loss,accuracy = model.train(X_train[i*batch_size:(i+1)*batch_size], Y_train[i*batch_size:(i+1)*batch_size],accuracy=True)
83+
progbar.add(batch_size, values=[("train loss", loss),("train accuracy:", accuracy)] )
84+
85+
#save the model of best val-accuracy
86+
print("Validation...")
87+
val_loss,val_accuracy = model.evaluate(X_val, Y_val, batch_size=1,show_accuracy=True)
88+
if best_accuracy<val_accuracy:
89+
best_accuracy = val_accuracy
90+
cPickle.dump(model,open("./model.pkl","wb"))
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#coding:utf-8
2+
"""
3+
Author:wepon
4+
Code:https://github.com/wepe
5+
6+
File: data.py
7+
8+
download data here: http://pan.baidu.com/s/1qCdS6
9+
10+
"""
11+
12+
13+
import os
14+
from PIL import Image
15+
import numpy as np
16+
17+
#读取文件夹mnist下的42000张图片,图片为灰度图,所以为1通道,如果是将彩色图作为输入,则将1替换为3,图像大小28*28
18+
def load_data():
19+
data = np.empty((42000,1,28,28),dtype="float32")
20+
label = np.empty((42000,),dtype="uint8")
21+
imgs = os.listdir("./mnist")
22+
num = len(imgs)
23+
for i in range(num):
24+
img = Image.open("./mnist/"+imgs[i])
25+
arr = np.asarray(img,dtype="float32")
26+
data[i,:,:,:] = arr
27+
label[i] = int(imgs[i].split('.')[0])
28+
#归一化和零均值化
29+
scale = np.max(data)
30+
data /= scale
31+
mean = np.std(data)
32+
data -= mean
33+
return data,label
34+
35+
36+
37+
38+
39+
40+
41+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
Author:wepon
3+
Code:https://github.com/wepe
4+
5+
File: get_feature_map.py
6+
1. visualize feature map of Convolution Layer, Fully Connected layer
7+
2. rewrite the code so you can treat CNN as feature extractor, see file: cnn-svm.py
8+
"""
9+
from __future__ import print_function
10+
import cPickle,theano
11+
from data import load_data
12+
import matplotlib.pyplot as plt
13+
import matplotlib.cm as cm
14+
15+
#load the saved model
16+
model = cPickle.load(open("model.pkl","rb"))
17+
18+
#define theano funtion to get output of FC layer
19+
get_feature = theano.function([model.layers[0].input],model.layers[11].output(train=False),allow_input_downcast=False)
20+
21+
#define theano funtion to get output of first Conv layer
22+
get_featuremap = theano.function([model.layers[0].input],model.layers[2].output(train=False),allow_input_downcast=False)
23+
24+
25+
data, label = load_data()
26+
27+
# visualize feature of Fully Connected layer
28+
#data[0:10] contains 10 images
29+
feature = get_feature(data[0:10]) #visualize these images's FC-layer feature
30+
plt.imshow(feature,cmap = cm.Greys_r)
31+
plt.show()
32+
33+
#visualize feature map of Convolution Layer
34+
num_fmap = 4 #number of feature map
35+
for i in range(num_fmap):
36+
featuremap = get_featuremap(data[0:10])
37+
plt.imshow(featuremap[0][i],cmap = cm.Greys_r) #visualize the first image's 4 feature map
38+
plt.show()

DeepLearning Tutorials/keras_usage/cnn.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
'''
44
GPU run command:
5-
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python cifar10_cnn.py
5+
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python cnn.py
66
CPU run command:
7-
python cifar10_cnn.py
7+
python cnn.py
88
'''
99
#导入各种用到的模块组件
1010
from __future__ import absolute_import

DeepLearning Tutorials/readme.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,12 @@ DeepLearning Tutorials
77
- Softmax_sgd(or logistic_sgd)
88

99

10-
每个文件夹下有两份代码,一份是Deeplearning网页上的教程的代码,另外一份带有 _commentate 后缀的是我所注释的,因为加入中文注释,显得比较杂乱,仅作帮助理解。真正使用代码时,请直接用原始的代码。
10+
以上每个文件夹下有两份代码,一份是Deeplearning网页上的教程的代码,另外一份带有 _commentate 后缀的是我所注释的,因为加入中文注释,显得比较杂乱,仅作帮助理解。真正使用代码时,请直接用原始的代码。
11+
12+
建议Theano用户转用Keras,不会让你失望,下面两份介绍Keras的基本使用。
13+
14+
- keras_usage
15+
- dive _into _keras
16+
17+
1118

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ CSDN:[wepon的专栏](http://blog.csdn.net/u012162613)
1717
- **DeepLearning Tutorials**
1818

1919
这个文件夹下包含一些深度学习算法的实现代码,以及具体的应用实例,包含:
20+
21+
[dive_into _keras]() Keras使用进阶。介绍了怎么保存训练好的CNN模型,怎么将CNN用作特征提取,怎么可视化卷积图。[文章链接](http://blog.csdn.net/u012162613/article/details/45581421)
2022
2123
[keras_usage](https://github.com/wepe/MachineLearning/tree/master/DeepLearning%20Tutorials/keras_usage) 介绍了一个简单易用的深度学习框架keras,用经典的Mnist分类问题对该框架的使用进行说明,训练一个CNN,总共不超过30行代码。[文章链接](http://blog.csdn.net/u012162613/article/details/45397033)
2224

0 commit comments

Comments
 (0)