已經在深度學習方面潛水了很久,理論知識了解個大概,代碼能力相差很遠,至於為什么寫這行代碼,每個句子的功能是什么,了解的一塌糊塗,為熟悉深度學習的應用和提高Code水平,現使用Keras搭建CNN對貓狗進行分類。
本文結構:1、數據集;2、網絡設計;3、訓練網絡;4、測試網絡。
1、數據集
對於剛入門的新手,數據集處理是一個很困難的操作,一般數據集可以從tensorflow的kreas導入或使用自己的數據集。
(1)直接從tensorflow.keras導入數據集
直接從keras導入數據集,非常方便,省去了很多制作自己數據集的麻煩。不過這種方法只是我們學習深度學習快速搭建測試模型使用的。
# 導入keras的一個數據集的庫,這個庫包含常見的數據集 from tensorflow.keras import datasets import numpy as np # 導入cifar10數據集, 如果導入mnist數據集,只需把下面datasets后的cifar換位mnist即可 # (x_train, y_train)表示訓練集的樣本與標簽 # (x_test, y_test)表示測試集的樣本與標簽 (x_train, y_train), (x_test, y_test) = datasets.cifar10.load_data()
# 查看數據類型與shape print('the type of x_train:', type(x_train)) print('the shape of x_train:', x_train.shape) print('the type of y_train:', type(y_train)) print('the shape of y_train:', y_train.shape) #數據預處理 ## 原始圖片每個像素范圍為0-255,轉換為0-1之間,因為過大的數據范圍使神經網絡讀取起來非常麻煩 x_train = x_train / 255. y_train = y_train / 255. ## 隨機打散數據 data_train = np.random.shuffle(x_train)
(2)使用自己的數據集
自己的圖片數據集,可以使用Keras數據提取方式提取或自己制作標簽至csv,txt文件進行提取,也可以使用 tf.Data API 導入數據,但此處坑太多,目前還沒掌握,后續更新。貓狗分類數據集可以從kaggle下載,然后創建三個文件夾命名分別為train、validation、test,每個文件夾中再分別創建cats,dogs,選出相應的部分數據放在創建的文件夾就可以了。(train文件夾下cats,dogs各放1000張相應的圖片,validation和test文件夾下的dogs和cats各放500張相應的圖片)
from keras.preprocessing.image import ImageDataGenerator # 將照片[0-255]數據縮放為[0-1]
## ImageDataGenerator也可以增強數據集,產生更多的數據 train_datagen = ImageDataGenerator(rescale=1.255) validation_datagen = ImageDataGenerator(rescale=1./255) # 訓練集與驗證集路徑 train_dir = "train" test_dir = "validation" # 生成了150x150的RGB圖像,形狀為[20,150,150,3]與二進制標簽[20,]的批量,每個批量包含20個樣本 train_generator = train_datagen.flow_from_directory( train_dir, # 訓練集路徑 target_size=(150, 150), # 訓練集樣本尺寸大小為(150, 150) batch_size=20, # 訓練集每批包含20個樣本 class_mode='binary') # 由於是二分類,此處需要為 'binary' validation_generator = test_datagen.flow_from_directory( validation_dir, target_size=(150, 150), batch_size=18, class_mode='binary')
2、網絡設計
使用到的網絡為基本的CNN網絡結構。不斷地壓縮圖像尺寸大小,增多特征個數,最后通過全連接層輸出CNN結果。
from keras import models, layers, Sequential # (1)構建網絡模型 model = models.Sequential() # 卷積->池化->卷積->池化->卷積->池化->Flatten(打平)->Dropout(參數正則化方法)->全連接->全連接 model.add(layers.Conv2D(32, 3, activation='relu', input_shape=(150, 150, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, 3, activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, 3, activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Flatten()) model.add(layers.Dropout(0.5)) model.add(layers.Dense(512, activation='relu')) # 由於是個二分類問題,最后一層激活函數選擇sigmoid model.add(layers.Dense(1, activation='sigmoid'))
3、訓練網絡
訓練網絡需要配置網絡模型,包括損失函數,優化方法,訓練指標。需要注意的是,此處的樣本批量與訓練評估,輪數的關系。
# (2)配置網絡模型
# 配置損失函數,優化方法,訓練指標
## 損失函數:多分類時categorical_crossentropy
## 優化方法:SGD,RMSprop,Adam等
## 訓練指標:網絡調節自身參數的指標
model.compile(loss='binary_crossentrapy',
optimizer = optimizers.RMSprop(lr=1e-4),
metric=['accuracy'])
# 只需要用fit_generator就可配置訓練參數 history = model.fit_generator( train_generator, # 訓練集的生成器 steps_per_epoch=100, # 訓練100個批量,即100次梯度下降后進行下一輪,訓練集有2000個樣本,每批包含20個樣本 epochs=30, # 訓練30輪 validation_data=validation_generator,# 驗證集的生成器 validation_steps=50) # 從驗證集中抽取50批樣本用於評估,每批20個樣本,驗證集共1000樣本 # 保存網絡 model.save('cat_dog_model.h5')
4、測試網絡
測試網絡時,首先畫出了訓練好的模型的訓練集驗證集准確率和損失的圖形曲線,然后加載模型對測試集進行測試。
import matplotlib.pyplot as plt # 繪制損失與准確率曲線 acc = history.history['acc'] val_acc = history.history['val_acc'] loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(1, len(acc) + 1) plt.plot(epochs, acc, 'bo', label='Training acc') plt.plot(epochs, val_acc, 'b', label='Validation acc') plt.title('Training and validation accuracy') plt.legend() plt.figure() plt.plot(epochs, loss, 'bo', label='Training loss') plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and validation loss') plt.legend() plt.show()
此處為測試集測試方法,共有兩種,一種是對單張圖片進行測試,另一種方法是對整個測試集進行測試。
from keras.preprocessing import image from keras.models import load_model from keras.preprocessing.image import ImageDataGenerator # 加載訓練好的模型 model = load_model('cat_dog_net.h5') # 方法一:查看單張圖片結果(load_img中路徑名稱需修改) img = image.load_img('test/xxx.jpeg', target_size=(150, 150)) x = image.img_to_array(img) / 255. x = x.reshape((1,) + x.shape) print(model.predict_classes(x)) # 方法二:對整個測試集進行評估 test_dir = "test" test_datagen = ImageDataGenerator(rescale=1./255) test_generator = test_datagen.flow_from_directory( test_dir, target_size=(150, 150), batch_size=20, class_mode='binary') test_loss, test_acc = model.evaluate_generator(test_generator, steps=50) print('test acc:', test_acc)
一般搭建測試深度學習就是這個流程,但這個流程每一步都有太多坑。這僅僅是認識深度學習的第一步,后續會更新遇到的坑[]~( ̄▽ ̄)~*。
