教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

微調(diào)模型完成熱狗識(shí)別的圖像分類【任務(wù)分解】

更新時(shí)間:2023年03月08日11時(shí)19分 來(lái)源:傳智教育 瀏覽次數(shù):

針對(duì)微調(diào)模型我們來(lái)實(shí)踐一個(gè)具體的例子:熱狗識(shí)別。將基于一個(gè)小數(shù)據(jù)集對(duì)在ImageNet數(shù)據(jù)集上訓(xùn)練好的ResNet模型進(jìn)行微調(diào)。該小數(shù)據(jù)集含有數(shù)千張熱狗或者其他事物的圖像。我們將使用微調(diào)得到的模型來(lái)識(shí)別一張圖像中是否包含熱狗。

首先,導(dǎo)入實(shí)驗(yàn)所需的工具包。

import tensorflow as tf
import numpy as np

獲取數(shù)據(jù)集

我們首先將數(shù)據(jù)集放在路徑hotdog/data之下:

1678083514572_81.png

每個(gè)類別文件夾里面是圖像文件。

上一節(jié)中我們介紹了ImageDataGenerator進(jìn)行圖像增強(qiáng),我們可以通過(guò)以下方法讀取圖像文件,該方法以文件夾路徑為參數(shù),生成經(jīng)過(guò)圖像增強(qiáng)后的結(jié)果,并產(chǎn)生batch數(shù)據(jù):

flow_from_directory(self, directory,
                            target_size=(256, 256), color_mode='rgb',
                            classes=None, class_mode='categorical',
                            batch_size=32, shuffle=True, seed=None,
                            save_to_dir=None)

主要參數(shù):

  ? directory: 目標(biāo)文件夾路徑,對(duì)于每一個(gè)類對(duì)應(yīng)一個(gè)子文件夾,該子文件夾中任何JPG、PNG、BNP、PPM的圖片都可以讀取。

  ? target_size: 默認(rèn)為(256, 256),圖像將被resize成該尺寸。

  ? batch_size: batch數(shù)據(jù)的大小,默認(rèn)32。

  ? shuffle: 是否打亂數(shù)據(jù),默認(rèn)為True。

我們創(chuàng)建兩個(gè)tf.keras.preprocessing.image.ImageDataGenerator實(shí)例來(lái)分別讀取訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集中的所有圖像文件。將訓(xùn)練集圖片全部處理為高和寬均為224像素的輸入。此外,我們對(duì)RGB(紅、綠、藍(lán))三個(gè)顏色通道的數(shù)值做標(biāo)準(zhǔn)化。

# 獲取數(shù)據(jù)集
import pathlib
train_dir = 'transferdata/train'
test_dir = 'transferdata/test'
# 獲取訓(xùn)練集數(shù)據(jù)
train_dir = pathlib.Path(train_dir)
train_count = len(list(train_dir.glob('*/*.jpg')))
# 獲取測(cè)試集數(shù)據(jù)
test_dir = pathlib.Path(test_dir)
test_count = len(list(test_dir.glob('*/*.jpg')))
# 創(chuàng)建imageDataGenerator進(jìn)行圖像處理
image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
# 設(shè)置參數(shù)
BATCH_SIZE = 32
IMG_HEIGHT = 224
IMG_WIDTH = 224
# 獲取訓(xùn)練數(shù)據(jù)
train_data_gen = image_generator.flow_from_directory(directory=str(train_dir),
                                                    batch_size=BATCH_SIZE,
                                                    target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                    shuffle=True)
# 獲取測(cè)試數(shù)據(jù)
test_data_gen = image_generator.flow_from_directory(directory=str(test_dir),
                                                    batch_size=BATCH_SIZE,
                                                    target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                    shuffle=True)

下面我們隨機(jī)取1個(gè)batch的圖片然后繪制出來(lái)。

import matplotlib.pyplot as plt
# 顯示圖像
def show_batch(image_batch, label_batch):
    plt.figure(figsize=(10,10))
    for n in range(15):
        ax = plt.subplot(5,5,n+1)
        plt.imshow(image_batch[n])
        plt.axis('off')
# 隨機(jī)選擇一個(gè)batch的圖像        
image_batch, label_batch = next(train_data_gen)
# 圖像顯示
show_batch(image_batch, label_batch)

1678083965743_82.png

模型構(gòu)建與訓(xùn)練

我們使用在ImageNet數(shù)據(jù)集上預(yù)訓(xùn)練的ResNet-50作為源模型。這里指定weights='imagenet'來(lái)自動(dòng)下載并加載預(yù)訓(xùn)練的模型參數(shù)。在第一次使用時(shí)需要聯(lián)網(wǎng)下載模型參數(shù)。

Keras應(yīng)用程序(keras.applications)是具有預(yù)先訓(xùn)練權(quán)值的固定架構(gòu),該類封裝了很多重量級(jí)的網(wǎng)絡(luò)架構(gòu),如下圖所示:

模型構(gòu)建與訓(xùn)練

實(shí)現(xiàn)時(shí)實(shí)例化模型架構(gòu):

tf.keras.applications.ResNet50(
    include_top=True, weights='imagenet', input_tensor=None, input_shape=None,
    pooling=None, classes=1000, **kwargs
)

主要參數(shù):

? include_top: 是否包括頂層的全連接層。

? weights: None 代表隨機(jī)初始化, 'imagenet' 代表加載在 ImageNet 上預(yù)訓(xùn)練的權(quán)值。

? input_shape: 可選,輸入尺寸元組,僅當(dāng) include_top=False 時(shí)有效,否則輸入形狀必須是 (224, 224, 3)(channels_last 格式)或 (3, 224, 224)(channels_first 格式)。它必須為 3 個(gè)輸入通道,且寬高必須不小于 32,比如 (200, 200, 3) 是一個(gè)合法的輸入尺寸。

在該案例中我們使用resNet50預(yù)訓(xùn)練模型構(gòu)建模型:

# 加載預(yù)訓(xùn)練模型
ResNet50 = tf.keras.applications.ResNet50(weights='imagenet', input_shape=(224,224,3))
# 設(shè)置所有層不可訓(xùn)練
for layer in ResNet50.layers:
    layer.trainable = False
# 設(shè)置模型
net = tf.keras.models.Sequential()
# 預(yù)訓(xùn)練模型
net.add(ResNet50)
# 展開(kāi)
net.add(tf.keras.layers.Flatten())
# 二分類的全連接層
net.add(tf.keras.layers.Dense(2, activation='softmax'))

接下來(lái)我們使用之前定義好的ImageGenerator將訓(xùn)練集圖片送入ResNet50進(jìn)行訓(xùn)練。

# 模型編譯:指定優(yōu)化器,損失函數(shù)和評(píng)價(jià)指標(biāo)net.compile(optimizer='adam',
            loss='categorical_crossentropy',
            metrics=['accuracy'])# 模型訓(xùn)練:指定數(shù)據(jù),每一個(gè)epoch中只運(yùn)行10個(gè)迭代,指定驗(yàn)證數(shù)據(jù)集history = net.fit(
                    train_data_gen,
                    steps_per_epoch=10,
                    epochs=3,
                    validation_data=test_data_gen,
                    validation_steps=10
                    )
Epoch 1/3
10/10 [==============================] - 28s 3s/step - loss: 0.6931 - accuracy: 0.5031 - val_loss: 0.6930 - val_accuracy: 0.5094
Epoch 2/3
10/10 [==============================] - 29s 3s/step - loss: 0.6932 - accuracy: 0.5094 - val_loss: 0.6935 - val_accuracy: 0.4812
Epoch 3/3
10/10 [==============================] - 31s 3s/step - loss: 0.6935 - accuracy: 0.4844 - val_loss: 0.6933 - val_accuracy: 0.4875






0 分享到:
和我們?cè)诰€交談!