keras冻结_【连载】深度学习第22讲:搭建一个基于keras的迁移学习花朵识别系统(附数据)...
在上一講中,和大家探討了遷移學習的基本原理,并利用 keras 基于 VGG16 預訓練模型簡單了在 mnist 數據集上做了演示。鑒于大家對于遷移學習的興趣,本節將繼續基于遷移學習利用一些花朵數據搭建一個花朵識別系統。因為是帶有教學系統的演示,本節將盡量將試驗過程完整詳細的展示給大家,也會附上試驗數據和代碼,以供大家學習和復現試驗內容。
使用的試驗數據來自于羅大鈞在 cos 統計之都上的分享,數據可于此處下載:
鏈接:https://pan.baidu.com/s/1whkhJMeV9od2oKRgCozFxg 密碼:7amd
下載數據后解壓可見共有五個文件夾,每個文件夾是一種花類,具體信息如下:
五種花種加起來不過是 3669 張圖片,數據量不算小樣本但也絕對算不上多。所以我們采取遷移學習的策略來搭建花朵識別系統。
實際數據中玫瑰花存在著一張圖片的重復,筆者直接對其進行了刪除。花型圖片大致如下:
需要導入的 package:
import os import pandas as pd import numpy as np import cv2 import matplotlib.pyplot as plt from PIL import Image import time from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import train_test_split import kerasfrom keras.models import Model from keras.layers import Dense, Activation, Flatten, Dropout from keras.utils import np_utils from keras.applications.resnet50 import ResNet50提取數據標簽
數據沒有單獨給出標簽文件,需要我們自行通過文件夾提取每張圖片的標簽,建立標簽文件:
def tranverse_images(path):labels = pd.DataFrame()first_dir_file = [file for file in os.listdir(path)] for item in first_dir_file:flower = [image for image in os.listdir(path+item)]labels_data = pd.DataFrame({'flower': flower, 'labels': item})labels = pd.concat((labels, labels_data)) return labelslabels = tranverse_images('./flower_photos/') labels.head()這樣標簽文件就順利拿到了。
圖片預處理(縮放)
通過試驗可知每張圖片像素大小并不一致,所以在搭建模型之前,我們需要對圖片進行整體縮放為統一尺寸。我們借助 opencv 的 python 庫 cv2 可以輕松實現圖片縮放,因為后面我們的遷移學習策略采用的是 ResNet50 作為預訓練模型,所以我們這里將圖片縮放大小為 224x224x3。單張圖片的 resize 效果如下:
原圖:
縮放后的效果和尺寸:
img_1 = cv2.resize(img, (224, 224)) print(img_1.shape) img3_1 = cv2.cvtColor(img3_1, cv2.COLOR_BGR2RGB) plt.imshow(img_1)批量縮放代碼為:
# resize def resize_image(path1, path2):images = [img for img in os.listdir(path1)]total = 0start_time = time.time() for img in images:img1 = cv2.imread(path1 + img)img1 = cv2.resize(img1, (224, 224))total += 1print('now is resizing {} image.'.format(total))cv2.imwrite(path2+img, img1)print('all images are resized, all resized image is {}.'.format(total))end_time = time.time()print('the resize time is {}.'.format(end_time - start_time))resize_image(path1='./flower_photos/', path2='./resize_flower_photos/')原始圖片并不復雜,所以除了對其進行縮放處理之外基本無需多做處理。下一步我們需要將圖片轉化為可以拿來進行訓練的 numpy 數組。
準備訓練數據
處理好的圖片無法直接拿來訓練,我們需要將其轉化為 numpy 數組的形式,另外標簽也需要進一步的處理。
將圖片轉化為數組:
可見轉化后的數組大小為 3669x224x224x3,跟我們的實際數據一致。然后我們再來處理標簽數據,標簽變量都是分類值,我們先需要將其進行硬編碼 LabelEncoder,然后借助 keras 將其 one-hot 處理。具體處理如下:
lbl = LabelEncoder().fit(list(labels['labels'].values)) labels['code_labels'] = pd.DataFrame(lbl.transform(list(labels['labels'].values))) labels.head()訓練數據的預處理準備停當,下面我們用 sklearn 劃分一下數據集:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)(2568, 224, 224, 3) (2568,) (1101, 224, 224, 3) (1101,)訓練集和測試集數據劃分完畢,終于可以進入建模環節啦。
基于resnet50 的遷移學習模型
試驗模型的基本策略就是使用預訓練模型的權重作為特征提取器,將預訓練的權重進行凍結,只訓練全連接層。在正式構建模型前,先將數據進行標準化以及標簽數據進行 onehot 處理。
X_train /= 255 X_test /= 255 y_train = np_utils.to_categorical(y_train, 5) y_test = np_utils.to_categorical(y_test, 5)構建模型如下: def flower_model(X_train, y_train):base_model = ResNet50(include_top=False, weights='imagenet', input_shape=(224, 224, 3)) for layers in base_model.layers:layers.trainable = Falsemodel = Flatten()(base_model.output)model = Dense(128, activation='relu')(model)model = Dropout(0.5)(model)model = Dense(5, activation='softmax')(model)model = Model(inputs=base_model.input, outputs=model)model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])model.fit(X_train, y_train, batch_size=128, epochs=50) return model模型訓練和測試集評估: model = flower_model(X_train, y_train) model.evaluate(X_test, y_test, verbose=0)訓練過程:限于計算資源,筆者的筆記本訓練了一輪后就已熱的發燙,果斷停止了訓練。大家若是有 gpu 計算資源的話可嘗試將模型訓練完。一兩輪后模型的識別準確率就達到 70%,相信繼續訓練下去會有一個較高的識別率。
總結
以上是生活随笔為你收集整理的keras冻结_【连载】深度学习第22讲:搭建一个基于keras的迁移学习花朵识别系统(附数据)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++ 获取当前时间_【Python】日
- 下一篇: idea persistence生成_真