python +keras实现图像分类(入门级例子讲解)
一.項目描述
數據集來源于kaggle貓狗大戰數據集。訓練集有25000張,貓狗各占一半。測試集12500張。希望計算機可以從這些訓練集圖片中學習到貓狗的特征,從而使得計算機可以正確的對未曾見過的貓狗圖片進行分類。這就是圖像分類問題,計算機視覺研究領域之一,計算機通過學習圖像本身的特征將不同類別的圖像區分開來。
二.評價指標
二分類評價指標
binary_crossentropy:交叉熵
y? i是樣本標簽,yi樣本輸出。只有yi和y? i是相等時,loss才為0,否則loss就是為一個正數。而且,概率相差越大,loss就越大。這個度量概率距離的方式稱為交叉熵。
二分類模型的最后一層的激活函數 是:sigmoid
二分類模型最后輸出的是0到1的數。
應該使用numpy的四舍五入求取類別,并轉換為整數
pred_y=int(np.round(predict_y))
多分類評價指標
categorical_crossentropy:分類交叉熵函數
y? i是樣本標簽,yi樣本輸出
多分類模型的最后一層的激活函數 是:softmax
softmax先把輸出指數化,再歸一化,得到各類概率。
假設一個問題是3分類,一個訓練樣本進來得到的softmax是[0.5,0.2,0.3]
假設這個正確樣本類別為第一個類別。
則該樣本分類交叉熵為:
多分類模型輸出的是各個類別的概率,如2個樣本的預測輸出為:ypred=[[0.5,0.2,0.3],[0.4,0.1,0.5]]
應該使用numpy求取最大值索引
pred=np.argmax(ypred,axis=1)
得到[0,2]
三.算例實現
數據集
電腦垃圾啦,無法將全部圖片都用上,跑不動。
于是貓和狗都選取原始數據集的一半左右。
貓的圖片如下:
狗的圖片如下:
各種各樣的貓和狗,不容易找到統一的圖片預處理方式,如處理成二值圖像(但貓狗顏色不一樣,二值處理有的把背景提取出來啦,畢竟二值處理需要把前景色處理成白色,為了達到此要求,有的圖片得做反二值化處理)
就對圖片不做任何處理吧,防止圖片失真。
1數據集讀取函數
注意:cv2.imread(name) 圖片路徑不能含有中文。
#個人喜好用OpenCV
需要對圖片統一大小: cv2.resize(img, (100, 100))
import os import numpy as np import cv2def ReFileName(dirPath):""":param dirPath: 文件夾路徑:return:"""# 對目錄下的文件進行遍歷x=[]for file in os.listdir(dirPath):# 判斷是否是文件if os.path.isfile(os.path.join(dirPath, file)) == True:c= os.path.basename(file)name = dirPath + '\\' + cimg = cv2.imread(name)img = cv2.resize(img, (100, 100)) # 使尺寸大小一樣x.append(img)return x2數據集讀取并處理
分別讀取貓狗數據集,之前我將貓和狗放在兩個文件夾啦。
對數據除以255,cnn模型對數值小的數處理得比較好。
轉換數據格式,圖像格式為np.uint8, 轉換成float型,計算機可以計算。
標簽處理,貓處理成1,狗處理成0
3.數據打亂
首先拼接數據集,然后打亂數據集特征和標簽。
如果是多分類問題得在打亂數據前對y進行one-hot化,如:
y=keras.utils.to_categorical(y,4)#四分類
4.定義模型
電腦不行,就用個普通模型跑吧。
如果是多分類問題
最后兩行為
本文模型
from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D import keras import timedef define_model():model = Sequential()model.add(Conv2D(filters=16,kernel_size=(5, 5),padding='same',input_shape=(100, 100, 3),activation='relu')) # 卷積層1model.add(MaxPooling2D(pool_size=(2, 2))) # 池化層2model.add(Dropout(0.25))model.add(Flatten()) # 平坦層model.add(Dense(10,activation='relu')) # 隱藏層model.add(Dense(1, activation='sigmoid')) # 輸出層model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])model.summary()return model5.模型訓練并保持
準確率0.7072,之前使用的是貓狗各3000多張,準確率為0.5。
現在使用的是各6000多張,準確率0.7。
原始數據集有各12000多張,原諒我,使用全部數據集電腦太卡,沒服務器,學生黨。
四.pyqt可視化結果
建立個簡單版的qt貓狗預測系統吧。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Author: yudengwu # @Date : 2020/7/18 import sys from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import *import cv2 import keras from keras .models import load_model import numpy as np import re class picture(QWidget):def __init__(self):super(picture, self).__init__()self.resize(600, 400)self.setWindowTitle("貓狗分類")self.btn = QPushButton()self.btn.setText("打開圖片")self.btn.clicked.connect(self.openimage)self.label = QLabel()self.label.setText('圖片路徑')self.labelimage = QLabel()self.labelimage.setText("顯示圖片")#self.labelimage.setFixedSize(500, 400)#設置尺寸self.labelimage.setStyleSheet("QLabel{background:white;}""QLabel{color:rgb(300,300,300,120);font-size:10px;font-weight:bold;font-family:宋體;}")#預測按鈕self.btnclass=QPushButton()self.btnclass.setText('點擊預測分類')self.btnclass.clicked.connect(self.fenlei)self.labelclass=QLabel()self.labelclass.setText('預測類別')self.labelclass.setStyleSheet("font:16pt '楷體';border-width:2px;border-style: inset;border-color:gray")layout1=QVBoxLayout()layout1.addWidget(self.btn)layout1.addWidget(self.label)layout1.addWidget(self.labelimage)layout2 = QVBoxLayout()layout2.addWidget(self.btnclass)layout2.addWidget(self.labelclass)layout=QVBoxLayout()layout.addLayout(layout1)layout.addLayout(layout2)self.setLayout(layout)def openimage(self):imgName, imgType = QFileDialog.getOpenFileName(self, "打開圖片", "", "*.jpg;;*.png;;All Files(*)")#jpg = QtGui.QPixmap(imgName).scaled(self.labelimage.width(), self.label.height())#適應labelimage尺寸,前提是label設置了尺寸jpg = QtGui.QPixmap(imgName)self.labelimage.setPixmap(jpg)self.label.setText(str(imgName))def fenlei(self):biaoqian = {'1': '貓', '0': '狗'}path=self.label.text()newName = re.sub('(D:/機器學習/學習草稿/)','', path)print(newName)img = cv2.imread(str(newName))img = cv2.resize(img, (100, 100)) # 使尺寸大小一樣img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)img = np.array(img) / 255img = img.astype(np.float64)img = img.reshape(-1, 100, 100, 1)model = load_model('貓狗分類.h5')predict_y = model.predict(img)pred_y = int(np.round(predict_y))print(pred_y)self.labelclass.setText(biaoqian[str(pred_y)])if __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)my = picture()my.show()sys.exit(app.exec_())說明:
newName = re.sub(’(D:/機器學習/學習草稿/)’,’’, path)
這是因為我圖片放在了當前項目文件夾里,導致圖片絕對路徑含有中文,cv.imread()會出錯,我去除掉中文部分,使模型讀取相對路徑
如果你要讀取任意文件夾里的圖片,要使圖片絕對路徑無中文。
可以固定圖片顯示尺寸;
#self.labelimage.setFixedSize(500, 400)#設置尺寸
#jpg = QtGui.QPixmap(imgName).scaled(self.labelimage.width(), self.label.height())#適應labelimage尺寸,前提是label設置了尺寸
結果
預測界面:
識別cat
識別dog
這個結果還不能讓我滿意,等我多學習下知識再來吧。
當然也可以調用攝像頭,實現對攝像頭下的貓狗進行實時識別。
可以參考博文然后自己修改程序。就是一個定時器作用,每隔多少時間識別下攝像頭下的物體。
opencv進階學習筆記1: 調用攝像頭用法大全(打開攝像頭,打開攝像頭并實時不斷截屏,讀取視頻并截圖)
送上其他資源:
計算機視覺:圖像特征與描述大全 (一篇博文帶你簡單了解完圖像特征提取技術)
電氣專業的計算機萌新,寫博文不容易。如果你覺得本文對你有用,請點個贊再走,謝謝。
總結
以上是生活随笔為你收集整理的python +keras实现图像分类(入门级例子讲解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pyqt5讲解2:QPushButton
- 下一篇: 银行卡丢失怎么补办 挂失银行卡是第一步