iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0
自我挑戰組

IOS、Python自學心得30天系列 第 22

IOS、Python自學心得30天 Day-22 MacOS訓練模組

前言:
在尋找轉換模組的方法時,也順便寫了MacOS版本的訓練模組

MacOS程式碼:

import os
import tensorflow as tf
import coremltools
import keras
from tensorflow import keras
from tensorflow.python.keras import backend as K
from tensorflow.python.keras.models import Model, Sequential, load_model
from tensorflow.python.keras.layers import LSTM, Flatten, Dense, Dropout
from tensorflow.python.keras.applications.resnet50 import ResNet50
from tensorflow.python.keras.optimizer_v2.adam import Adam
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator
from tensorflow.python.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau
import ssl

from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

ssl._create_default_https_context = ssl._create_unverified_context
                     
def create_model():
    # 捨棄 ResNet50 頂層的 fully connected layers
    net = ResNet50(include_top=False, 
                weights='imagenet', 
                input_tensor=None,
                input_shape=(IMAGE_SIZE[0],IMAGE_SIZE[1],3))
    x = net.output

    x = Flatten()(x)

    # 增加 DropOut layer
    x = Dropout(0.5)(x)

    # 增加 Dense layer,以 softmax 產生個類別的機率值
    output_layer = Dense(NUM_CLASSES, activation='softmax', name='softmax')(x)

    # 設定凍結與要進行訓練的網路層
    net_final = Model(inputs=net.input, outputs=output_layer)
    for layer in net_final.layers[:FREEZE_LAYERS]:
        layer.trainable = False
    for layer in net_final.layers[FREEZE_LAYERS:]:
        layer.trainable = True

    # 使用 Adam optimizer,以較低的 learning rate 進行 fine-tuning
    net_final.compile(optimizer=Adam(learning_rate=1e-5),
                    loss='categorical_crossentropy', metrics=['accuracy'])
    
    return net_final
# 資料路徑
DATASET_PATH  = '/Users/pecajo/Desktop/pyFile/Demo1/'

# 影像大小
IMAGE_SIZE = (300, 300)

# 影像類別數
NUM_CLASSES = 133

# 若 GPU 記憶體不足,可調降 batch size 或凍結更多層網路
BATCH_SIZE = 8

# 凍結網路層數
FREEZE_LAYERS = 0

# Epoch 數
NUM_EPOCHS = 1

# 模型輸出儲存的檔案
WEIGHTS_FINAL = '/Users/使用者名稱/Desktop/pyFile/Demo1/model-resnet50-macOS-1.h5'

# 透過 data augmentation 產生訓練與驗證用的影像資料
train_datagen = ImageDataGenerator(rotation_range=40,
                                   width_shift_range=0.2,
                                   height_shift_range=0.2,
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                   channel_shift_range=10,
                                   horizontal_flip=True,
                                   vertical_flip = True,
                                   fill_mode='nearest',
                                   data_format='channels_last'
                                   )
train_batches = train_datagen.flow_from_directory(DATASET_PATH + 'dogImages/train',
                                                  target_size=IMAGE_SIZE,
                                                  interpolation='bicubic',
                                                  class_mode='categorical',
                                                  shuffle=True,
                                                  batch_size=BATCH_SIZE)

valid_datagen = ImageDataGenerator()
valid_batches = valid_datagen.flow_from_directory(DATASET_PATH + 'dogImages/valid',
                                                  target_size=IMAGE_SIZE,
                                                  interpolation='bicubic',
                                                  class_mode='categorical',
                                                  shuffle=False,
                                                  batch_size=BATCH_SIZE)

# 輸出各類別的索引值
for cls, idx in train_batches.class_indices.items():
    print('Class #{} = {}'.format(idx, cls))

# Create a basic model instance
net_final = create_model()

# 輸出整個網路結構
print(net_final.summary())



if os.path.exists(DATASET_PATH):
    if os.path.exists(DATASET_PATH + WEIGHTS_FINAL):
        print(WEIGHTS_FINAL + "模型存在,將繼續訓練模型")
        # net_final.save(WEIGHTS_FINAL)
        new_net_final = load_model(WEIGHTS_FINAL)
        while True :
            new_net_final.fit(train_batches,
                              steps_per_epoch = train_batches.samples // BATCH_SIZE,
                              validation_data = valid_batches,
                              validation_steps = valid_batches.samples // BATCH_SIZE,
                              epochs = NUM_EPOCHS)#,
                              # callbacks = [LR_function])
            # 儲存訓練好的模型
            print("儲存訓練模型")
            new_net_final.save(WEIGHTS_FINAL) # .h5
            
    else:
        print(WEIGHTS_FINAL + '模型不存在,將新建訓練模型')
        # 訓練模型
        while True :
            net_final.fit(train_batches,
                          # validation_split = 0.2,
                          steps_per_epoch = train_batches.samples // BATCH_SIZE,
                          validation_data = valid_batches,
                          validation_steps = valid_batches.samples // BATCH_SIZE,
                          epochs = NUM_EPOCHS)#,
                          # callbacks = [LR_function])
            # 儲存訓練好的模型
            print("儲存訓練模型")
            net_final.save(WEIGHTS_FINAL) # .h5   
else:
    print(WEIGHTS_FINAL + '路徑不存在,請確認路徑')


上一篇
IOS、Python自學心得30天 Day-21 CoreML範例
下一篇
IOS、Python自學心得30天 Day-23 Firebase銜接Python-1
系列文
IOS、Python自學心得30天30

尚未有邦友留言

立即登入留言