用Python圖像識別技術打造一個小狗分類器,實現讓機器自己去“學習”~


前言

今日給大家帶來的是圖像識別技術——小狗分類器
在這里插入圖片描述

工具使用

開發環境:win10、python3.6
開發工具:pycharm
工具包 :keras,numpy, PIL

效果展示

訓練集的准確率為0.925,但測試集只有0.7
說明過擬合了,可以再增加一些圖片,或者使用數據增強,來減少過擬合。

圖片

測試了兩張圖片,全都識別對了!

圖片

思路分析

  • 1 准備數據集
  • 2 數據集的預處理
  • 3 搭建卷積神經網絡
  • 4 訓練
  • 5 預測

1、准備數據集

我們可以通過爬蟲技術,把4類圖像(京巴、拉布拉多、柯基、泰迪)保存到本地。總共有840張圖片做訓練集,188張圖片做測試集。

2 數據集的預處理

1 統一尺寸為1001003(RGB彩色圖像)

# 統一尺寸的核心代碼
img = Image.open(img_path)
new_img = img.resize((100, 100), Image.BILINEAR)
new_img.save(os.path.join('./dog_kinds_after/' + dog_name, jpgfile))

2 由於數據是自己下載的,需要制作標簽(label),可提取圖像名稱的第一個數字作為類別。(重命名圖片)

kind = 0

# 遍歷京巴的文件夾
images = os.listdir(images_path)
for name in images:
    image_path = images_path + '/'
    os.rename(image_path + name, image_path + str(kind) +'_' + name.split('.')[0]+'.jpg')

3 划分數據集

840張圖片做訓練集,188張圖片做測試集。

4 把圖片轉換為網絡需要的類型

# 只放了訓練集的代碼,測試集一樣操作。
ima_train = os.listdir('./train')

# 圖片其實就是一個矩陣(每一個像素都是0-255之間的數)(100*100*3)
# 1.把圖片轉換為矩陣
def read_train_image(filename):
    img = Image.open('./train/' + filename).convert('RGB')
    return np.array(img)

x_train = []
# 2.把所有的圖片矩陣放在一個列表里 (840, 100, 100, 3)
for i in ima_train:
    x_train.append(read_train_image(i))
x_train = np.array(x_train)
# 3.提取kind類別作為標簽
y_train = []
for filename in ima_train:
    y_train.append(int(filename.split('_')[0]))

# 標簽(0/1/2/3)(840,)
y_train = np.array(y_train)

# 我是因為重命名圖片為(1/2/3/4),所以都減了1
# 為了能夠轉化為獨熱矩陣
y_train = y_train - 1  

# 4.把標簽轉換為獨熱矩陣
# 將類別信息轉換為獨熱碼的形式(獨熱碼有利於神經網絡的訓練)
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
print(y_test)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')

x_train /= 255
x_test /= 255
print(x_train.shape)  # (840, 100, 100, 3)
print(y_train.shape)  # (840,)

3 搭建卷積神經網絡

Keras是基於TensorFlow的深度學習庫,是由純Python編寫而成的高層神經網絡API,也僅支持Python開發。

它是為了支持快速實踐而對Tensorflow的再次封裝,讓我們可以不用關注過多的底層細節,能夠把想法快速轉換為結果。

# 1.搭建模型(類似於VGG,直接拿來用就行)
model = Sequential()
# 這里搭建的卷積層共有32個卷積核,卷積核大小為3*3,采用relu的激活方式。
# input_shape,字面意思就是輸入數據的維度。

#這里使用序貫模型,比較容易理解
#序貫模型就像搭積木一樣,將神經網絡一層一層往上搭上去

model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
#dropout層可以防止過擬合,每次有25%的數據將被拋棄

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4, activation='softmax'))

4 訓練

訓練的過程,就是最優解的過程。

圖片

對上圖來說,就是根據數據集,不斷的迭代,找到一條最近似的直線(y = kx + b),把參數k,b保存下來,預測的時候直接加載。

# 編譯模型
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

# 一共進行32輪
# 也就是說840張圖片,每次訓練10張,相當於一共訓練84次
model.fit(x_train, y_train, batch_size=10, epochs=32)


# 保存權重文件(也就是相當於“房價問題的k和b兩個參數”)
model.save_weights('./dog_weights.h5', overwrite=True)
# 評估模型
score = model.evaluate(x_test, y_test, batch_size=10)
print(score)

5 預測

此時k、b(參數)和x(小狗的圖像)都是已知的了,求k(類別)就完了。

# 1.上傳圖片
name = input('上傳圖片的名稱(例如:XX.jpg)為:')

# 2.預處理圖片(代碼省略)

# 3.加載權重文件
model.load_weights('dog_weights.h5')

# 4.預測類別
classes = model.predict_classes(x_test)[0]

target = ['京巴', '拉布拉多', '柯基', '泰迪']
# 3-泰迪 2-柯基 1-拉布拉多 0-京巴

# 5.打印結果
print("識別結果為:" + target[classes])

文章到這里就結束了,感謝你的觀看,Python數據分析系列,下個系列分享Python小技巧

為了感謝讀者們,我想把我最近收藏的一些編程干貨分享給大家,回饋每一個讀者,希望能幫到你們。

干貨主要有:

① 2000多本Python電子書(主流和經典的書籍應該都有了)

② Python標准庫資料(最全中文版)

③ 項目源碼(四五十個有趣且經典的練手項目及源碼)

④ Python基礎入門、爬蟲、web開發、大數據分析方面的視頻(適合小白學習)

⑤ Python學習路線圖(告別不入流的學習)

⑥ 兩天的Python爬蟲訓練營直播權限

All done~詳見個人簡介或者私信獲取完整源代碼。。

往期回顧

Python實現“假”數據

Python爬蟲魯迅先生《經典語錄》

Python爬蟲豆瓣熱門話題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM