我是用 jupyter notebook寫的,各個(gè)功能模塊清楚分明,順便推薦給大家。 以圖片分類為例:
主要依賴于:
- scikit-learn
- scikit-image
- matplotlib
- jupyter notebook
- numpy
- cv2 (傾向于使用 skimage image 代替之, skimage 使用的是 圖像坐標(biāo) (通過(guò)行列檢索),cv2使用笛卡爾坐標(biāo)檢索(x,y))
直接開(kāi)始正文:
導(dǎo)入依賴庫(kù)
- 寫個(gè) lib.ipynb 將依賴庫(kù)都放進(jìn)去
%matplotlib inline
import platform
SYS = platform.system()
if 'Linux' in SYS:
%run /home/v/WORKSPACE/GIT/LIB/lib.ipynb
else:
%run d:/WORKSPACE/git/LIB/lib.ipynb
t1 = toc()
注意事項(xiàng):
- lib.ipynb 是依賴庫(kù)函數(shù)所在文件
- 為了方便linux 和 win 都能運(yùn)行,所以加入最后幾行。
- toc()函數(shù)是自己寫的函數(shù),為了方便整體計(jì)時(shí),存放在lib里面,局部計(jì)時(shí)有%%timeit命令。
數(shù)據(jù)庫(kù)(圖片)路徑
trainset = ps('image path for training ')
testset = ps('image path for testing')
print ("[INFO] There are %d classes in the trainset" % len(os.listdir(trainset)))
注意事項(xiàng):
- ps函數(shù)可有可無(wú),有興趣的朋友可以留言。
- 每個(gè)文件夾存放一個(gè)類別的圖片,文件夾的命名要體現(xiàn)圖片label和category name,這樣做會(huì)在分類上省事一些,通過(guò)下面的特征提取代碼,大家可以看到。我的數(shù)據(jù)庫(kù)是這樣命名的:

train and test folders

class folders in train set
這樣命名的好處很快可以在特征提取模塊看到。
特征提取 -- HOG 特征
%%time
x_train=[]
y_train=[]
for floder_nmae in tqdm(os.listdir(trainset)):
label= int( floder_nmae.split("__")[0] )
class_path=os.path.join(trainset,floder_nmae)
for img_name in os.listdir(class_path):
img_path=os.path.join(class_path,img_name)
## readin the original image
ROI = imread(img_path, as_grey=True, resize =True, width =200, height =100)
x_train.append(HOG(ROI,ori=9, ppc=(20, 20), cpb=(2, 2)))
y_train.append(label)
x_test=[]
y_test=[]
for class_folder in tqdm(os.listdir(testset)):
label= int( class_folder.split("__")[0] )
class_path=os.path.join(testset,class_folder)
for j in os.listdir(class_path):
img_path=os.path.join(class_path,j)
## readin the original image
ROI = imread(img_path, as_grey=True, resize =True, width =200, height =100)
x_test.append(HOG(ROI,ori=9,ppc=(20, 20), cpb=(2, 2)))
y_test.append(label)
print (" number of train samples : %d " % len(x_train) )
print (" number of test samples : %d " % len(x_test) )
print (" feature dim is : %d " % len(x_train[0]) )
注意事項(xiàng):
- 文件夾命名的好處現(xiàn)在知道了吧,直接 .split("__")就可以得到類別label
- imread 函數(shù)和HOG函數(shù)都被我簡(jiǎn)單封裝了下,存在lib里面,原因是不同語(yǔ)言各種各樣的 圖片讀取, resize, 灰度化函數(shù)搞得我好亂啊,所以索性同一放在imread函數(shù)里面,集 圖片讀取,灰度化, resize, rescale于一身。如有朋友需要的話,我可以公布下這個(gè)函數(shù)。HOG函數(shù)也是一樣,skimage不僅在HOG函數(shù)bins的方向上弄得不好,而且函數(shù)明明也過(guò)于冗長(zhǎng)和復(fù)雜. ori = orientation, ppc = pixel per cell, cpb = cell per block 沒(méi)人會(huì)質(zhì)疑我的簡(jiǎn)化吧。
- 這部分的輸出是這樣的:

module output
wall time 就是jupyter notebook magic函數(shù)的功能,給出當(dāng)前cell的運(yùn)行時(shí)間。有機(jī)會(huì)寫一系列 jupyter notebook (ipython) magic function的簡(jiǎn)文(如果有人提出的話)。
分類器的訓(xùn)練(linear SVM)
直接上代碼
%%time
clf = svm.LinearSVC()
parameters = {
'C': np.arange(1, 15, 1),
'multi_class': ['crammer_singer']
}
# run randomized search
n_iter_search = 10
clf = RandomizedSearchCV(clf,
param_distributions = parameters,
n_iter = n_iter_search,
n_jobs = 4,
pre_dispatch = '2*n_jobs')
clf.fit(x_train, y_train)
- crammer singer SVM 是為多類別分類設(shè)計(jì)的,這個(gè)我喜歡,因?yàn)樾Ч谩?/li>
- 現(xiàn)在知道 特征列表和label 列表明明的好處了吧。 x, y, train。體會(huì)一下。
- 我特意加入了參數(shù)選擇這一塊,調(diào)參是個(gè)大問(wèn)題,如果機(jī)器允許,就讓他自己去找吧,當(dāng)然是通過(guò) coss validation的方式, Randomized SearchCV 默認(rèn)是將訓(xùn)練數(shù)據(jù)5-fold還是6-fold, 這個(gè)參數(shù)也可以修改,需要的話可以百度 scikit learn documentation.
- 這部分的輸出: 有需要解釋的地方可以提問(wèn)。。。。。。

module output
測(cè)試 --測(cè)試集
這部分沒(méi)啥說(shuō)的, scikit learn 搞的函數(shù)接口還是簡(jiǎn)單易懂的。
y_pred = clf.predict(x_test)
分類結(jié)果 accuracy
- 這里只提供了我寫的 acc函數(shù),scikit learn 沒(méi)有提供acc的檢測(cè)接口。 當(dāng)然還有其他的準(zhǔn)則去檢驗(yàn),如:precision, recall, f1 score. 這些還是不如acc 表達(dá)的清楚:分對(duì)的個(gè)數(shù)除以要分類的樣本個(gè)數(shù)。
- 依舊,acc被我封裝起來(lái)了,存在lib.ipynb里面。
- 上結(jié)果:

Paste_Image.png
- 不用多解釋了吧。
- 函數(shù)總體運(yùn)行時(shí)間,通過(guò)elapsed_time 得到, 現(xiàn)在知道toc()的作用了吧。