github地址:https://github.com/HandsomeHans/Image-Pre-Classification
想法是在卷积神经网络分类图片之前先进行一次预分类,二分类就好,判断当前图片是否包含我要分类的物品。
因为只要你丢一张图片进卷积神经网络,它总归会输出一个结果,可能这个结果置信度不高,但是在某些情况这个置信度也会超过所设阈值。
特征提取有很多算法,直方图太寒酸了,并不适用。
对于少量数据集,直方图还能训练出一个还不错的模型。但是一上完整数据集就歇菜。
我提供的是一种思路,不是解决方案,我也在摸索当中。
---------【2018.01.24】更新--------------------
同样的训练集(7W+)和测试集(1W)
未微调参数,256维灰度直方图,adaboost,忘记记录在测试集上准确率了。
未微调参数,768维颜色直方图,adaboost,准确率0.8516;
参数同上,根据0.99方差百分比PCA降到221维,adaboost,准确率0.6483,说明直方图特征独立性很强啊。后来尝试mle算法自动降维,发现只降了一维,好吧。以后尝试用LDA。
经过微调参数,768维颜色直方图,adaboost,准确率暂时0.90,还没调完。参数好多,真的好慢啊!
参数待定,256维lbp直方图,adaboost,下回更新。
参数待定,1024维颜色直方图&lbp直方图,adaboost,下会更新。
暂时没做0均值,归一化,正则化等预处理。
没做上面预处理,每一维度方差还蛮大的,不管了。
通过相关系数法,查看了下排名前221维度的特征,通过这种方式降维效果如何待验证。
---------------------------------------------------------
train 和 test的list文档格式和caffe转lmdb用的文档格式一样:
路径+空格+类别索引
#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Wed Jan 17 13:09:08 2018 @author: hans """ import cv2 import os import numpy as np from sklearn.externals import joblib from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score from sklearn.ensemble import AdaBoostClassifier from sklearn.ensemble import GradientBoostingClassifier from skimage import transform from sklearn import tree import datetime def gray(img_path): img = cv2.imread(img_path, 0) img=transform.resize(img, (227, 227)) img = img*255 img = img.astype(np.uint8) feature = cv2.calcHist([img],[0],None,[256],[0,256]).reshape(1,-1) return feature def rgb(img_path): img = cv2.imread(img_path) img=transform.resize(img, (227, 227,3)) b = img[:,:,0]*255 g = img[:,:,1]*255 r = img[:,:,2]*255 b = b.astype(np.uint8) g = g.astype(np.uint8) r = r.astype(np.uint8) feature_b = cv2.calcHist([b],[0],None,[256],[0,256]).reshape(1,-1) feature_g = cv2.calcHist([g],[0],None,[256],[0,256]).reshape(1,-1) feature_r = cv2.calcHist([r],[0],None,[256],[0,256]).reshape(1,-1) feature = np.hstack((feature_b,feature_g,feature_r)) return feature def hist_feature(list_txt): root_path = 'image/' with open(list_txt, 'r') as f: line = f.readline() img_path = os.path.join(root_path,line.split(' ')[0]) if mode == 0: feature = gray(img_path) elif mode == 1: feature = rgb(img_path) label = np.array([int(line.split(' ')[1].split('\n')[0])]) line = f.readline() num = 2 while line: img_path = os.path.join(root_path,line.split(' ')[0]) if not os.path.isfile(img_path): line = f.readline() continue print("%d dealing with %s ..." %(num, line.split(' ')[0])) if mode == 0: hist_cv = gray(img_path) elif mode == 1: hist_cv = rgb(img_path) feature = np.vstack((feature,hist_cv)) label = np.hstack((label,np.array([int(line.split(' ')[1].split('\n')[0])]))) num+=1 line = f.readline() joblib.dump(feature, list_txt.split('.')[0]+filename,compress=5) joblib.dump(label, list_txt.split('.')[0]+'_label.pkl', compress=5) return feature, label def save_feature(): t1 = datetime.datetime.now() X_train, y_train = hist_feature(train_list) t2 = datetime.datetime.now() X_test, y_test = hist_feature(test_list) t3 = datetime.datetime.now() print("\ntime of extracting train features: %0.2f"%(t2-t1).total_seconds()) print("time of extracting test features: %0.2f"%(t3-t2).total_seconds()) def decision_tree(): dt = tree.DecisionTreeClassifier(criterion='gini',max_depth=None, min_samples_split=2, min_samples_leaf=1,random_state=80) return fit(dt, 'dt') def random_forest(): # criterion: 分支的标准(gini/entropy), n_estimators: 树的数量, bootstrap: 是否随机有放回, n_jobs: 可并行运行的数量 rf = RandomForestClassifier(n_estimators=25,criterion='entropy',bootstrap=True,n_jobs=4,random_state=80) # 随机森林 return fit(rf, 'rf') def adaboost(): ada = AdaBoostClassifier(tree.DecisionTreeClassifier(criterion='gini',max_depth=11, min_samples_split=400, \ min_samples_leaf=30,max_features=30,random_state=10), \ algorithm="SAMME", n_estimators=100, learning_rate=0.001,random_state=10) return fit(ada, 'ada') def fit(clf, s): t3 = datetime.datetime.now() X_train = joblib.load(train_list.split('.')[0]+filename) y_train = joblib.load(train_list.split('.')[0]+'_label.pkl') clf = clf.fit(X_train, y_train) joblib.dump(clf, s+'_model.pkl') t4 = datetime.datetime.now() print("--------------------------------\ntime of training model: %0.2f"%(t4-t3).total_seconds()) scores = cross_val_score(clf, X_train, y_train,scoring='accuracy' ,cv=3) print("Train Cross Avg. Score: %0.4f (+/- %0.4f)" % (scores.mean(), scores.std() * 2)) return clf def testScore(clf): t4 = datetime.datetime.now() X_test = joblib.load(test_list.split('.')[0]+filename) y_test = joblib.load(test_list.split('.')[0]+'_label.pkl') clf_score = clf.score(X_test, y_test) print ("--------------------------------\nTest score: %.4f" %clf_score) clf_pred = clf.predict(X_test) print clf_pred[:10] t5 = datetime.datetime.now() print("time of testing model: %0.2f"%(t5-t4).total_seconds()) scores = cross_val_score(clf, X_test, y_test,scoring='accuracy' ,cv=10) print("Test Cross Avg. Score: %0.4f (+/- %0.4f)" % (scores.mean(), scores.std() * 2)) mode=1 if mode==0: filename = '_feature_gray.pkl' elif mode==1: filename = '_feature_rgb.pkl' train_list = "train_all.txt" test_list = "test_all.txt" #train_list = "train.txt" #test_list = "test.txt" if __name__ == '__main__': # save_feature() # dt = decision_tree() # rf = random_forest() ada = adaboost() # gbdt = gradientboost() # dt = joblib.load('dt_model.pkl') # rf = joblib.load('rf_model.pkl') ada = joblib.load('ada_model.pkl') testScore(ada)