天天看點

keras_卷積神經網絡_貓狗分類案例(一)

參考:

https://blog.csdn.net/fioletfly/article/details/101345549

Python深度學習

代碼清單 5-2 在卷積神經網絡上添加分類器

代碼清單 5-3 在 MNIST 圖像上訓練卷積神經網絡

代碼清單 5-4 将圖像複制到訓練、驗證和測試的目錄

代碼清單 5-5 将貓狗分類的小型卷積神經網絡執行個體化

代碼清單 5-6 配置模型用于訓練

5.2.4 資料預處理

代碼清單 5-7 使用 ImageDataGenerator 從目錄中讀取圖像

代碼清單 5-8 利用批量生成器拟合模型

代碼清單 5-9 儲存模型

代碼清單 5-10 繪制訓練過程中的損失曲線和精度曲線

5.2.5 使用資料增強

代碼清單 5-11 利用 ImageDataGenerator 來設定資料增強

代碼清單 5-12 顯示幾個随機增強後的訓練圖像

代碼清單 5-13 定義一個包含 dropout 的新卷積神經網絡

代碼清單 5-14 利用資料增強生成器訓練卷積神經網絡

代碼清單 5-15 儲存模型

在這裡插入代碼片
```sql
import keras
keras.__version__


import os, shutil
# 我們将重點讨論貓狗圖像分類,資料集中包含 4000 張貓和狗的圖像
# (2000 張貓的圖像, 2000 張狗的圖像)。我們将 2000 張圖像用于訓練, 1000 張用于驗證, 1000
# 張用于測試。
​
​
# The path to the directory where the original
# dataset was uncompressed
# 原始資料集解壓目錄的路徑
original_dataset_dir = '/Users/fchollet/Downloads/kaggle_original_data'
​
# The directory where we will
# store our smaller dataset
# 儲存較小資料集的目錄
base_dir = '/Users/fchollet/Downloads/cats_and_dogs_small'
os.mkdir(base_dir)
​
​
​
# 分别對應劃分後的訓練、# 驗證和測試的目錄
# Directories for our training,
# validation and test splits
train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir, 'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_dir, 'test')
os.mkdir(test_dir)
​
​
# 貓的訓練圖像目錄
# Directory with our training cat pictures
train_cats_dir = os.path.join(train_dir, 'cats')
os.mkdir(train_cats_dir)
​
​
# 狗的訓練圖像目錄
# Directory with our training dog pictures
train_dogs_dir = os.path.join(train_dir, 'dogs')
os.mkdir(train_dogs_dir)
​
# 貓的驗證圖像目錄
# Directory with our validation cat pictures
validation_cats_dir = os.path.join(validation_dir, 'cats')
os.mkdir(validation_cats_dir)
​
# 狗的驗證圖像目錄
# Directory with our validation dog pictures
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
os.mkdir(validation_dogs_dir)
​
# 貓的測試圖像目錄
# Directory with our validation cat pictures
test_cats_dir = os.path.join(test_dir, 'cats')
os.mkdir(test_cats_dir)
​
# 狗的測試圖像目錄
# Directory with our validation dog pictures
test_dogs_dir = os.path.join(test_dir, 'dogs')
os.mkdir(test_dogs_dir)
​
# 将前 1000 張貓的圖像複制
# 到 train_cats_dir
# Copy first 1000 cat images to train_cats_dir
fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(train_cats_dir, fname)
    shutil.copyfile(src, dst)
​
    
#     将接下來 500 張貓的圖像複
# 制到 validation_cats_dir
# Copy next 500 cat images to validation_cats_dir
fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(validation_cats_dir, fname)
    shutil.copyfile(src, dst)
    
    
# 将接下來的 500 張貓的圖像
# 複制到 test_cats_dir
# Copy next 500 cat images to test_cats_dir
fnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(test_cats_dir, fname)
    shutil.copyfile(src, dst)
​
    
# Copy first 1000 dog images to train_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(train_dogs_dir, fname)
    shutil.copyfile(src, dst)
    
# Copy next 500 dog images to validation_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(validation_dogs_dir, fname)
    shutil.copyfile(src, dst)
    
# Copy next 500 dog images to test_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(test_dogs_dir, fname)
    shutil.copyfile(src, dst)
As a sanity check, let's count how many pictures we have in each training split (train/validation/test):

# 我們來檢查一下,看看每個分組(訓練 / 驗證 / 測試)中分别包含多少張圖像
​
print('total training cat images:', len(os.listdir(train_cats_dir)))
total training cat images: 1000
print('total training dog images:', len(os.listdir(train_dogs_dir)))
total training dog images: 1000
print('total validation cat images:', len(os.listdir(validation_cats_dir)))
total validation cat images: 500
print('total validation dog images:', len(os.listdir(validation_dogs_dir)))
total validation dog images: 500
print('total test cat images:', len(os.listdir(test_cats_dir)))
total test cat images: 500
print('total test dog images:', len(os.listdir(test_dogs_dir)))
total test dog images: 500


# 建構網絡
# 在前一個 MNIST 示例中,我們建構了一個小型卷積神經網絡,是以你應該已經熟悉這
# 種網絡。我們将複用相同的總體結構,即卷積神經網絡由 Conv2D 層(使用 relu 激活)和
# MaxPooling2D 層交替堆疊構成。
# 但由于這裡要處理的是更大的圖像和更複雜的問題,你需要相應地增大網絡,即再增加一
# 個 Conv2D+MaxPooling2D 的組合。這既可以增大網絡容量,也可以進一步減小特征圖的尺寸,
# 使其在連接配接 Flatten 層時尺寸不會太大。本例中初始輸入的尺寸為 150×150(有些随意的選
# 擇),是以最後在 Flatten 層之前的特征圖大小為 7×7。
# 注意 網絡中特征圖的深度在逐漸增大(從 32 增大到 128),而特征圖的尺寸在逐漸減小(從
# 150×150 減小到 7×7)。這幾乎是所有卷積神經網絡的模式
​
from keras import layers
from keras import models
​
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
                        input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
Let's take a look at how the dimensions of the feature maps change with every successive layer:

model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 148, 148, 32)      896       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 74, 74, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 72, 72, 64)        18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 36, 36, 64)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 34, 34, 128)       73856     
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 17, 17, 128)       0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 15, 15, 128)       147584    
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 7, 7, 128)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 6272)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               3211776   
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 513       
=================================================================
Total params: 3,453,121
Trainable params: 3,453,121
Non-trainable params: 0
_________________________________________________________________
For our compilation step, we'll go with the RMSprop optimizer as usual. Since we ended our network with a single sigmoid unit, we will use binary crossentropy as our loss (as a reminder, check out the table in Chapter 4, section 5 for a cheatsheet on what loss function to use in various situations).

在編譯這一步,和前面一樣,我們将使用 RMSprop 優化器。因為網絡最後一層是單一 sigmoid
# 單元,是以我們将使用二進制交叉熵作為損失函數(提醒一下,表 4-1 列出了各種情況下應該使
# 用的損失函數)。

# 在編譯這一步,和前面一樣,我們将使用 RMSprop 優化器。因為網絡最後一層是單一 sigmoid
# 單元,是以我們将使用二進制交叉熵作為損失函數(提醒一下,表 4-1 列出了各種情況下應該使
# 用的損失函數)。
​
from keras import optimizers
​
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])


因為使用了 binary_crossentropy
# 損失,是以需要用二進制标簽
# 資料預處理
# 你現在已經知道,将資料輸入神經網絡之前,應該将資料格式化為經過預處理的浮點數張量。
# 現在,資料以 JPEG 檔案的形式儲存在硬碟中,是以資料預處理步驟大緻如下。108  第 5 章 深度學習用于計算機視覺
# (1) 讀取圖像檔案。
# (2) 将 JPEG 檔案解碼為 RGB 像素網格。
# (3) 将這些像素網格轉換為浮點數張量。
# (4) 将像素值(0~255 範圍内)縮放到 [0, 1] 區間(正如你所知,神經網絡喜歡處理較小的輸
# 入值)。
# 這些步驟可能看起來有點吓人,但幸運的是, Keras 擁有自動完成這些步驟的工具。 Keras
# 有一個圖像處理輔助工具的子產品,位于 keras.preprocessing.image。特别地,它包含
# ImageDataGenerator 類,可以快速建立 Python 生成器,能夠将硬碟上的圖像檔案自動轉換
# 為預處理好的張量批量。下面我們将用到這個類。
​
​
from keras.preprocessing.image import ImageDataGenerator
​
# 将所有圖像乘以 1/255 縮放
# All images will be rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
​
# 将所有圖像的大小調整為 150×150
# 因為使用了 binary_crossentropy
# 損失,是以需要用二進制标簽
train_generator = train_datagen.flow_from_directory(
        # This is the target directory
        train_dir,
        # All images will be resized to 150x150
        target_size=(150, 150),
        batch_size=20,
        # Since we use binary_crossentropy loss, we need binary labels
        class_mode='binary')
​
validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=20,
        class_mode='binary')
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
Let's take a look at the output of one of these generators: it yields batches of 150x150 RGB images (shape (20, 150, 150, 3)) and binary labels (shape (20,)). 20 is the number of samples in each batch (the batch size). Note that the generator yields these batches indefinitely: it just loops endlessly over the images present in the target folder. For this reason, we need to break the iteration loop at some point.

for data_batch, labels_batch in train_generator:
    print('data batch shape:', data_batch.shape)
    print('labels batch shape:', labels_batch.shape)
    break
    
    
# 我們來看一下其中一個生成器的輸出:它生成了 150×150 的 RGB 圖像[形狀為 (20,
# 150, 150, 3)]與二進制标簽[形狀為 (20,)]組成的批量。每個批量中包含 20 個樣本(批
# 量大小)。注意,生成器會不停地生成這些批量,它會不斷循環目标檔案夾中的圖像。是以,你
# 需要在某個時刻終止(break)疊代循環。    
data batch shape: (20, 150, 150, 3)
labels batch shape: (20,)



# 利用生成器,我們讓模型對資料進行拟合。我們将使用 fit_generator 方法來拟合,它
# 在資料生成器上的效果和 fit 相同。它的第一個參數應該是一個 Python 生成器,可以不停地生
# 成輸入和目标組成的批量,比如 train_generator。因為資料是不斷生成的,是以 Keras 模型
# 要知道每一輪需要從生成器中抽取多少個樣本。這是 steps_per_epoch 參數的作用:從生成
# 器中抽取 steps_per_epoch 個批量後(即運作了 steps_per_epoch 次梯度下降),拟合過程
# 将進入下一個輪次。本例中,每個批量包含 20 個樣本,是以讀取完所有 2000 個樣本需要 100
# 個批量。
# 使用 fit_generator 時,你可以傳入一個 validation_data 參數,其作用和在 fit 方
# 法中類似。值得注意的是,這個參數可以是一個資料生成器,但也可以是 Numpy 數組組成的元
# 組。如果向 validation_data 傳入一個生成器,那麼這個生成器應該能夠不停地生成驗證數
# 據批量,是以你還需要指定 validation_steps 參數,說明需要從驗證生成器中抽取多少個批
# 次用于評估。
# 代碼清單 5-8 利用批量生成器拟合模型
​
history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,
      epochs=30,
      validation_data=validation_generator,
      validation_steps=50)
Epoch 1/30
100/100 [==============================] - 9s - loss: 0.6898 - acc: 0.5285 - val_loss: 0.6724 - val_acc: 0.5950
Epoch 2/30
100/100 [==============================] - 8s - loss: 0.6543 - acc: 0.6340 - val_loss: 0.6565 - val_acc: 0.5950
Epoch 3/30
100/100 [==============================] - 8s - loss: 0.6143 - acc: 0.6690 - val_loss: 0.6116 - val_acc: 0.6650
Epoch 4/30
100/100 [==============================] - 8s - loss: 0.5626 - acc: 0.7125 - val_loss: 0.5774 - val_acc: 0.6970
Epoch 5/30
100/100 [==============================] - 8s - loss: 0.5266 - acc: 0.7335 - val_loss: 0.5726 - val_acc: 0.6960


# 儲存模型
model.save('cats_and_dogs_small_1.h5')
Let's plot the loss and accuracy of the model over the training and validation data during training:
從這些圖像中都能看出過拟合的特征。訓練精度随着時間線性增加,直到接近 100%,而驗
# 證精度則停留在 70%~72%。驗證損失僅在 5 輪後就達到最小值,然後保持不變,而訓練損失則
# 一直線性下降,直到接近于 0。
# 因為訓練樣本相對較少(2000 個),是以過拟合是你最關心的問題。前面已經介紹過幾種
# 降低過拟合的技巧,比如 dropout 和權重衰減(L2 正則化)。現在我們将使用一種針對于計算
# 機視覺領域的新方法,在用深度學習模型處理圖像時幾乎都會用到這種方法,它就是資料增強
# (data augmentation)。
# 代碼清單 5-10 繪制訓練過程中的損失曲線和精度曲線
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(len(acc))
​
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()
​
# 從這些圖像中都能看出過拟合的特征。訓練精度随着時間線性增加,直到接近 100%,而驗
# 證精度則停留在 70%~72%。驗證損失僅在 5 輪後就達到最小值,然後保持不變,而訓練損失則
# 一直線性下降,直到接近于 0。
# 因為訓練樣本相對較少(2000 個),是以過拟合是你最關心的問題。前面已經介紹過幾種
# 降低過拟合的技巧,比如 dropout 和權重衰減(L2 正則化)。現在我們将使用一種針對于計算
# 機視覺領域的新方法,在用深度學習模型處理圖像時幾乎都會用到這種方法,它就是資料增強
# (data augmentation)。


# 5.2.5 使用資料增強
# 過拟合的原因是學習樣本太少,導緻無法訓練出能夠泛化到新資料的模型。如果擁有無限
# 的資料,那麼模型能夠觀察到資料分布的所有内容,這樣就永遠不會過拟合。資料增強是從現
# 有的訓練樣本中生成更多的訓練資料,其方法是利用多種能夠生成可信圖像的随機變換來增加
# (augment)樣本。其目标是,模型在訓練時不會兩次檢視完全相同的圖像。這讓模型能夠觀察
# 到資料的更多内容,進而具有更好的泛化能力。
# 在 Keras 中,這可以通過對 ImageDataGenerator 執行個體讀取的圖像執行多次随機變換來實
# 現。我們先來看一個例子。
​
​
# 這裡隻選擇了幾個參數(想了解更多參數,請查閱 Keras 文檔)。我們來快速介紹一下這些
# 參數的含義。
# • rotation_range 是角度值(在 0~180 範圍内),表示圖像随機旋轉的角度範圍。
# • width_shift 和 height_shift 是圖像在水準或垂直方向上平移的範圍(相對于總寬
# 度或總高度的比例)。
# • shear_range 是随機錯切變換的角度。
# • zoom_range 是圖像随機縮放的範圍。
# • horizontal_flip 是随機将一半圖像水準翻轉。如果沒有水準不對稱的假設(比如真
# 實世界的圖像),這種做法是有意義的。
# • fill_mode是用于填充新建立像素的方法,這些新像素可能來自于旋轉或寬度/高度平移。
# 我們來看一下增強後的圖像(見圖 5-11)
datagen = ImageDataGenerator(
      rotation_range=40,
      width_shift_range=0.2,
      height_shift_range=0.2,
      shear_range=0.2,
      zoom_range=0.2,
      horizontal_flip=True,
      fill_mode='nearest')



如果你使用這種資料增強來訓練一個新網絡,那麼網絡将不會兩次看到同樣的輸入。但網
# 絡看到的輸入仍然是高度相關的,因為這些輸入都來自于少量的原始圖像。你無法生成新資訊,
# 而隻能混合現有資訊。是以,這種方法可能不足以完全消除過拟合。為了進一步降低過拟合,
# 你還需要向模型中添加一個 Dropout 層,添加到密集連接配接分類器之前
# 顯示幾個随機增強後的訓練圖像
​
# 圖像預處理工具的子產品
# This is module with image preprocessing utilities
from keras.preprocessing import image
​
fnames = [os.path.join(train_cats_dir, fname) for fname in os.listdir(train_cats_dir)]
​
# We pick one image to "augment"
# 選擇一張圖像進行增強
# 讀取圖像并調整大小
# 将其轉換為形狀 (150, 150, 3) 的 Numpy 數組
# 将其形狀改變為 (1, 150, 150, 3)
# 生成随機變換後的圖像批量。
# 循環是無限的,是以你需要
# 在某個時刻終止循環
​
img_path = fnames[3]
​
# Read the image and resize it
img = image.load_img(img_path, target_size=(150, 150))
​
# Convert it to a Numpy array with shape (150, 150, 3)
x = image.img_to_array(img)
​
# Reshape it to (1, 150, 150, 3)
x = x.reshape((1,) + x.shape)
​
# The .flow() command below generates batches of randomly transformed images.
# It will loop indefinitely, so we need to `break` the loop at some point!
i = 0
for batch in datagen.flow(x, batch_size=1):
    plt.figure(i)
    imgplot = plt.imshow(image.array_to_img(batch[0]))
    i += 1
    if i % 4 == 0:
        break
​
plt.show()
​
# 如果你使用這種資料增強來訓練一個新網絡,那麼網絡将不會兩次看到同樣的輸入。但網
# 絡看到的輸入仍然是高度相關的,因為這些輸入都來自于少量的原始圖像。你無法生成新資訊,
# 而隻能混合現有資訊。是以,這種方法可能不足以完全消除過拟合。為了進一步降低過拟合,
# 你還需要向模型中添加一個 Dropout 層,添加到密集連接配接分類器之前


# 定義一個包含 dropout 的新卷積神經網絡
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
                        input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 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'))
model.add(layers.Dense(1, activation='sigmoid'))
​
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])
Let's train our network using data augmentation and dropout:

# 我們來訓練這個使用了資料增強和 dropout 的網絡。
# 代碼清單 5-14 利用資料增強生成器訓練卷積神經網絡
​
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,)
​
# Note that the validation data should not be augmented!
# 注意,不能增強驗證資料
test_datagen = ImageDataGenerator(rescale=1./255)
​
train_generator = train_datagen.flow_from_directory(
        # This is the target directory
        train_dir,
        # All images will be resized to 150x150
#     将所有圖像的大小調整為 150×150
        target_size=(150, 150),
        batch_size=32,
#     因為使用了 binary_crossentropy損失,是以需要用二進制标簽
        # Since we use binary_crossentropy loss, we need binary labels
        class_mode='binary')
​
validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')
​
history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,
      epochs=100,
      validation_data=validation_generator,
      validation_steps=50)
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
Epoch 1/100
100/100 [==============================] - 24s - loss: 0.6857 - acc: 0.5447 - val_loss: 0.6620 - val_acc: 0.5888
Epoch 2/100
100/100 [==============================] - 23s - loss: 0.6710 - acc: 0.5675 - val_loss: 0.6606 - val_acc: 0.5825
Epoch 3/100
100/100 [==============================] - 22s - loss: 0.6609 - acc: 0.5913 - val_loss: 0.6663 - val_acc: 0.5711.594 - ETA: 7s - loss: 0.6655 - ETA: 5s - los - ETA: 1s - loss: 0.6620 - acc: 
Epoch 4/100
100/100 [==============================] - 22s - loss: 0.6446 - acc: 0.6178 - val_loss: 0.6200 - val_acc: 0.6379



# 儲存模型
model.save('cats_and_dogs_small_2.h5')
Let's plot our results again:

通過進一步使用正則化方法以及調節網絡參數(比如每個卷積層的過濾器個數或網絡中的
# 層數),你可以得到更高的精度,可以達到 86%或 87%。但隻靠從頭開始訓練自己的卷積神經網絡,
# 再想提高精度就十分困難,因為可用的資料太少。想要在這個問題上進一步提高精度,下一步
# 需要使用預訓練的模型,這是接下來兩節的重點
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
​
epochs = range(len(acc))
​
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()
​
# 我們再次繪制結果(見圖 5-12 和圖 5-13)。使用了資料增強和 dropout 之後,模型不再過拟合:
# 訓練曲線緊緊跟随着驗證曲線。現在的精度為 82%,比未正則化的模型提高了 15%(相對比例)
​
# 通過進一步使用正則化方法以及調節網絡參數(比如每個卷積層的過濾器個數或網絡中的
# 層數),你可以得到更高的精度,可以達到 86%或 87%。但隻靠從頭開始訓練自己的卷積神經網絡,
# 再想提高精度就十分困難,因為可用的資料太少。想要在這個問題上進一步提高精度,下一步
# 需要使用預訓練的模型,這是接下來兩節的重點
           

繼續閱讀