日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

机器学习分类器——案例(opencv sklearn svm ann)

發布時間:2023/12/8 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 机器学习分类器——案例(opencv sklearn svm ann) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

機器學習分類器——案例(opencv sklearn svm ann python)

ps:最近師姐給我們留了一個任務,記錄一下從一開始的什么都不懂到現在把任務做出來,并從中學習到的東西吧。。。。
語言環境python3.7,用到的庫

import os import cv2 import math import time import numpy as np import tqdm from skimage.feature import hog from sklearn import svm,datasets,metrics import matplotlib.pyplot as plt from skimage import feature as ft from sklearn.neural_network import MLPClassifier from sklearn.preprocessing import StandardScaler from sklearn.metrics import * from sklearn import tree,neighbors from xgboost import XGBClassifier from sklearn.base import TransformerMixin,BaseEstimator from sklearn.ensemble import HistGradientBoostingClassifier from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.pipeline import make_pipeline from sklearn.linear_model import LogisticRegression from sklearn.naive_bayes import CategoricalNB,GaussianNB from sklearn.model_selection import cross_val_score from yellowbrick.classifier.rocauc import roc_auc import joblib

任務要求:給定數據集train和test文件夾,其中文件夾中包含四個文件夾(后來才知道是對應于多分類的四個類別),數據格式是圖片(也是后來才知道已經灰度處理過了)

小插曲:本來想展示一下文件夾層及目錄,奈何圖片過多,效果并不好,記錄一下獲取文件結構圖的方法吧。

1.win+R cmd

2.進入想要展示的文件夾內

3.輸入tree/f>file.txt命令,在響應的文件夾下生成txt文件可以看到文件結構圖。

數據集目錄結構

ps:一開始什么都不懂,后來讀文獻知道了處理問題的整體思路,先來說一下整體思路吧。

整體思路:

數據預處理

方法:我的理解是把圖片的像素變成0和255,來分割目標區域(細胞核),后面特征提取可以用到。

知識點:(方法原理可進一步了解)

直方圖均衡化( Histogram Equalization):一種增強圖像對比度的方法。

濾波: 盡量保留圖像細節特征的條件下對目標圖像的噪聲進行抑制 , 消除圖像中的噪聲成分叫作圖像的平滑化或濾波操作 。種類:均值濾波、中值濾波

圖像的閾值分割:基于區域的圖像分割技術,原理是把圖像像素點分為若干類。本次采用ostu法或者迭代法計算閾值(很多種方法)

程序代碼

def ImgProcessing(img):imgHist = cv2.equalizeHist(img) # 直方圖均衡化,用于提高圖像的質量imgblur = cv2.blur(imgHist, (5, 5)) # 均值濾波imgthre, ostu = cv2.threshold(imgblur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # otsu法聚類計算閾值# print(imgthre)###最佳閾值imgthre=126(具體問題的值不一樣)return ostupath = "Resource\\train\\1_typical_epithelial_cell\\1_122.jpg" img = cv2.imread(path, 0)#把圖片讀進來 thres = ImgProcessing(imgcopy) cv2.namedWindow("result",0)cv2.resizeWindow("result",600,300)result = cv2.hconcat([thres,img])cv2.imshow('result',result)if cv2.waitKey(1) & 0xFF == ord('q'):break

效果演示:如果想得到目標是黑色背景是白色,修改cv2.threshold的參數即可,因為后面的輪廓檢測要求傳入的目標是白色,故這里目標選擇白色。(也是采坑遇見錯誤查閱官方文檔才知道。。。)

去燥效果演示:

將預處理后的圖片保存到trainpro和testpro文件夾中

方法:傳入文件路徑,獲取每張圖片然后對每張圖片處理后保存到文件夾中

程序代碼:

def get_label_dir(path):for file_name in os.listdir(path):img_dir = os.path.join(path, file_name)# print(file_name)img = cv2.imread(img_dir,0)imgHist = cv2.equalizeHist(img) # 直方圖均衡化,用于提高圖像的質量imgblur = cv2.blur(imgHist, (5, 5)) # 均值濾波bestyuzhi1 = diedai(imgblur)#迭代法求閾值ret1, th1 = cv2.threshold(imgblur, bestyuzhi1, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)#file_name = '4'+file_name[1:]cv2.imwrite("Resource\\testpro\\6_garbage\\"+file_name,th1) get_label_dir("Resource\\test\\6_garbage")#每次只需要修改路徑即可

獲取特征

本次計算11個基本特征值和Hog特征(還有很多特征可以自行查閱,具體問題具體分析)最后把特征保存到Features列表中,一個圖片對應一個11長度的列表。

基本特征:(輪廓特征)周長、面積、長度、寬度、圓度、橢圓度、矩形度、規劃形狀因子;(紋理特征)均值、方差、平滑度、熵值、三階矩;

Hog特征:一種在計算機視覺和圖像處理中用來進行物體檢測的特征描述子。它通過計算和統計圖像局部區域的梯度方向直方圖來構成特征。 通過提取有用信息并扔掉多余的信息來簡化圖像 。 特征描述子將一張大小為width×height×3 (通道數)的圖片化成一個長度為n的特征向量數組。以HOG特征為例,輸入圖像的大小是64×128×3,輸出是一個長度為3780(假設)的特征向量 。本次提取756個特征。

程序代碼:

def getContours(thres,Features):contours, hierarchy = cv2.findContours(thres, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)cnt = contours[0]# print(cv2. arcLength(contours,True)) #輪廓長度# print(cv2.contourArea(contours))#輪廓面積area = cv2.contourArea(contours[0])# print("輪廓的面積是:%f" % area)length = cv2.arcLength(contours[0],True)# print("輪廓的周長是:%f" % length)#圓度計算公式4*PI*Area/length^2a = area*4*math.pib = math.pow(length,2)if b!=0:roundness = a/belse:roundness = 0# print("輪廓圓度是:%f" % roundness)#最小外接矩形框rect = cv2.minAreaRect(contours[0])wideth = rect[1][0]highth = rect[1][1]box = cv2.cv2.Boxpoint() if imutils.is_cv2() else cv2.boxPoints(rect)box = np.int0(box)minrectarea = np.int0(rect[1][0]*rect[1][1])#計算矩形度rect_degree = area/minrectarea# print("輪廓矩形度是:%f" % rect_degree)# cv2.drawContours(imgcopy, [box], 0, (255, 0, 0), 1)# cv2.drawContours(imgcopy, contours, -1, (0, 0, 255), 1) # 畫出輪廓#計算橢圓度for i in range(len(contours)):if len(contours[i]) >= 5:cv2.drawContours(thres, contours, -1, (150, 10, 255), 3)ellipse = cv2.fitEllipse(contours[i])ellipse_area = np.int0(ellipse[1][0] * ellipse[1][1])ellipse_degree = 4 * area / ellipse_area# Features.append(round(ellipse_degree, 3))# print("輪廓橢圓度%d是:%f" % (i,ellipse_degree))d1 = ellipse[1][0]d2 = ellipse[1][1]if d1 * d2 * length !=0:REF = area * (3 * (d1 + d2) - 2 * math.sqrt(d1 * d2)) / (d1 * d2 * length)else :REF =0# cv2.imshow("Perfectlyfittedellipses", thres)# cv2.waitKey(0)# ellipse = cv2.fitEllipse(contours[0])# ellipse_area = np.int0(ellipse[1][0]*ellipse[1][1])# ellipse_degree = 4*area/ellipse_area# # cv2.ellipse(imgcopy,ellipse,(0,255,255),1)#可視化橢圓輪廓# #規劃形狀因子# print("規劃形狀因子是:%f" % REF)wenli_gt = cv2.moments(contours[0])# print("三階矩是:%f" % wenli_gt['mu02']) # 三階矩Features.append(round(wideth,3))Features.append(round(highth,3))Features.append(round(area,3))Features.append(round(length,3))Features.append(round(roundness,3))Features.append(round(rect_degree,3))Features.append(round(ellipse_degree,3))Features.append(round(REF,3))Features.append(round(wenli_gt['mu02'],3)) def grain_feature(img,Features):mean , stddv = cv2.meanStdDev(img)#圖像均值和標準差(方差)# print("均值為%f 方差為%f " % (mean[0][0],stddv[0][0]))wenli_r = 1-1/(1+stddv*stddv)# print("平滑度為%f" % wenli_r)imagea = np.histogram(img.ravel(), bins=256)[0]wenli_s = skimage.measure.shannon_entropy(imagea,base=2)# print("熵值是:%f" % wenli_s)Features.append(round(wenli_r[0][0],6))Features.append(round(wenli_s,3)) def get_features(path):Features_set = []for file_name in os.listdir(path):Features = []img_dir = os.path.join(path, file_name)# print(file_name)img = cv2.imread(img_dir,0)imgcopy = img.copy()thres = ImgProcessing(imgcopy)getContours(thres,Features) ###基本特征grain_feature(imgcopy,Features) #####紋理特征# Features = np.array(Features)# print(type(Features),type(Features_sets))Features_set.append(Features)return Features_set

獲取Hog特征代碼:

def get_hog_feat(path):Features = []try:for file_name in os.listdir(path):img_dir = os.path.join(path, file_name)img = cv2.imread(img_dir,0)imgcopy = cv2.resize(img,(32,64))features, hog_img = ft.hog(imgcopy, orientations=9, pixels_per_cell=(8, 8), cells_per_block=(2, 2), visualize=True)Features.append(features)except cv2.error:print(file_name)return Features

制作數據集準備傳入模型中,將四類訓練集的特征都放入X_train中,Y_train存放標簽1,2,3,4(有的模型要求是0,1,2,3,代碼中有體現)

path_train = "Resource\\train" path_test = "Resource\\test" ###########制作訓練集 def get_data(path):X = []Y = []cnt =0for file_name in os.listdir(path):Features = []img_dir = os.path.join(path, file_name)Features = get_hog_feat(img_dir)cnt = cnt + 1for i in Features:X.append(i)Y.append(cnt)# cnt = cnt + 1 #XGB要求0123return X,Y X_train ,Y_train = get_data(path_train) X_test,Y_test = get_data(path_test)

如果遇到傳入數據有空值的錯誤可以使用以下代碼

關于np.nan_to_num可查看官方文檔https://numpy.org/doc/stable/reference/generated/numpy.nan_to_num.html

X_train = np.nan_to_num(X_train) Y_train = np.nan_to_num(Y_train) X_test = np.nan_to_num(X_test) Y_test = np.nan_to_num(Y_test)

數據降維

特征向量的維數過高會增加計算的復雜度,數據降維消除特征之間的數量級。

使用sklearn中的from sklearn.preprocessing import StandardScaler,使用方法可查看官方文檔,sklearn的文檔做的很好,有很多example,嘻嘻嘻。

sc_X = StandardScaler() X_trainscaled = sc_X.fit_transform(X_train) X_testscaled = sc_X.fit_transform(X_test) X_testscaled = np.nan_to_num(X_testscaled)

ps:數據準備好開始訓練

分類器訓練和模型衡量標準

本次訓練包含svm支持向量機,ann人工神經網絡(MLP多層感知機),Decision Tree決策樹、XGBboost(種梯度提升決策樹的實現)k-nn(K近鄰),Naive Bayes(樸素貝葉斯),有很多方法可以使用,但是很多原理還需要進一步學習。。。

分類器的訓練模型參數均保存到.dat文件中,可以節約每次訓練的時間。

程序代碼

###############SVM linear = svm.SVC(kernel='linear',C=1,decision_function_shape='ovo').fit(X_train ,Y_train) linear = svm.SVC(decision_function_shape='ovo').fit(X_train ,Y_train) linear_pred = linear.predict(X_test) linear = joblib.load("Hog_linear.dat") accuracy_lin = linear.score(X_test,Y_test) print("SVM-linear準確度為%.2f%%" % (accuracy_lin*100)) # joblib.dump(linear,"Hog_linear.dat")#保存模型 ##############ANN #MLP = MLPClassifier(solver='adam', alpha=1e-5,#256,128,64,32,hidden_layer_sizes=(30,30,30)random_state=100,activation='logistic').fit(X_trainscaled,Y_train) MLP = MLPClassifier().fit(X_trainscaled,Y_train) #joblib.dump(MLP,"Hog_MLP.dat")#保存模型 #MLP = joblib.load("Hog_MLP.dat")#加載模型 # MLP_pre = MLP.predict(X_testscaled) accuracy_ANN = MLP.score(X_testscaled,Y_test) print("Hog特征之ANN準確度%.2f%%" % (accuracy_ANN*100.0))

About SVM:kernel(核函數linear、rbf、poly、sigmoid),gamma值、懲罰系數c的選取都會影響最終的準確度的,由于是多分類, 邏輯回歸和 SVM 等二元分類模型本身不支持多類分類,需要元策略 ,分類策略采用的是ovo,還有ovr。

關于分類策略ovo和ovr:

由于SVM本質上是二分類模型,多分類可以是二分類的延伸。例如給定多分類class 1,class 2,class 3,class4。

ovo(One-vs-One):

class1 vs class 2

class 1 vs class3 等總共有n(n-1)/2種(4*3/2=6)

ovr(One-vs-Rest)n種:

class 1 vs [class2,class3,class4]

class 2 vs [class1,class 3,class 4]

class 3 vs [class1,class 2 ,class4]

class4 vs [class1,class2,class3]

About ANN

ANN就是借鑒了神經突觸機制,在結點中設置了函數,比如sigmoid或者tanh函數,來完成抑制或激活的目標。

衡量標準

計算準確率(Accuracy)、精確率(Precision)、召回率(Recall)、F1-Measure的數值、畫AUC曲線和混淆矩陣。

準確率(Accuracy):1-錯誤率

精確率(Precision):有多少比例是好的

召回率(Recall):好的信息中有多少被檢索出來

F1-Measure的數值:對查準率/查全率的重視程度

混淆矩陣:看出有多少個分類正確,有多少個被分類到其他的類中

ROC-AUC曲線:ROC曲線下的面積

###########衡量標準 target_names = ['class 1', 'class 2', 'class 3','class 4'] print(classification_report(Y_test, MLP_pre, target_names=target_names)) ######混淆矩陣 disp = metrics.ConfusionMatrixDisplay.from_predictions(Y_test, MLP_pre) disp.figure_.suptitle("confusion matrix") print(f"confusion matrix:\n{disp.confusion_matrix}") plt.show() ######ROC曲線和AUC #model = RidgeClassifier() #model = SVC() model = MLPClassifier() roc_auc(MLP, X_train, Y_train, X_test=X_test, y_test=Y_test, encoder={1:'typical', 2:'Lymphocyte', 3:'Single',4:'garbage'})

效果演示

其他的分類器

#####################Decision Trees 決策樹DTC = tree.DecisionTreeClassifier() DTC.fit(X_trainscaled,Y_train) # joblib.dump(DTC,"Hog_DTC.dat") DTC = joblib.load("Hog_DTC.dat") accuracy_DTC = DTC.score(X_testscaled,Y_test) print("Hog特征之DTC準確度%.2f%%" % (accuracy_DTC*100.0)) # print(cross_val_score(DTC,X_train,Y_train,cv=10)) # tree.plot_tree(DT)#繪制樹 #可以pip graphviz導出樹到pdf ####################集成學習 ######XGBoost是一種梯度提升決策樹的實現 XGB = XGBClassifier().fit(X_trainscaled,Y_train) # XGB = joblib.load("Hog_XGB.dat") accuracy_XGB = XGB.score(X_testscaled,Y_test) print("Hog特征之XGB準確度%.2f%%" % (accuracy_XGB*100.0)) # joblib.dump(XGB,"Hog_XGB.dat")####################K-Nearest Neighbors K近鄰 n_neighbors = 20 h = 0.02 K_N = neighbors.KNeighborsClassifier(n_neighbors,weights="distance") K_N.fit(X_trainscaled,Y_train) # # K_N = joblib.load("Hog_KNN.dat") accuracy_KNN = K_N.score(X_testscaled, Y_test) print("Hog特征之KNN準確度%.2f%%" % (accuracy_KNN * 100.0)) # # joblib.dump(K_N,"Hog_KNN.dat") ##繪制accuracy和k取值的關系圖 acc = [] for i in range(1,40):neigh = neighbors.KNeighborsClassifier(n_neighbors = i).fit(X_trainscaled,Y_train)yhat = neigh.predict(X_testscaled)acc.append(metrics.accuracy_score(Y_test, yhat)) plt.figure(figsize=(10,6)) plt.plot(range(1,40),acc,color = 'blue',linestyle='dashed',marker='o',markerfacecolor='red', markersize=10) plt.title('accuracy vs. K Value') plt.xlabel('K') plt.ylabel('Accuracy') print("Maximum accuracy:-",max(acc),"at K =",acc.index(max(acc))) plt.show()############ Naive Bayes 樸素貝葉斯(種類多):多項式樸素貝葉斯(離散)高斯樸素貝葉斯(連續) NB_G = GaussianNB().fit(X_trainscaled,Y_train) NB_G = joblib.load("Hog_NB_G.dat") accuracy_NBG = NB_G.score(X_testscaled,Y_test) print("Hog特征之NB_G準確度%.2f%%" % (accuracy_NBG*100.0)) # joblib.dump(NB_G,"Hog_NB_G.dat")

About DT

決策樹通過遞歸地進行特征選擇,將訓練集數據 D 進行分類最終生成一顆由節點和有向邊組成的樹結構。其中結點分為兩種類型:內部節點和葉節點,內部結點表示一個特征,葉結點表示一個類別。

About k-nn

即是給定一個訓練數據集,對新的輸入實例,在訓練數據集中找到與該實例最鄰近的K個實例,這K個實例的多數屬于某個類,就把該輸入實例分類到這個類中。(這就類似于現實生活中少數服從多數的思想

ps:關于分類器的算法的原理和理解很淺,希望后期可以多看原理,多看背后的數學邏輯,對適合數據的參數選擇能力還不夠,加油吧。

總結

以上是生活随笔為你收集整理的机器学习分类器——案例(opencv sklearn svm ann)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。