screwdriver/training.py
2025-02-06 16:10:58 +08:00

198 lines
9.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
Spyder Editor
This is a temporary script file.
python 3.6
pip install tensorflow-gpu==2.6.0
pip install keras==2.6.0
pip install opencv-python==3.4.2.16
pip install matplotlib==3.3.4
"""
import numpy as np
import os
# import cv2
from sklearn.model_selection import train_test_split # pip install scikit-learn
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras import models
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
import tensorflow as tf
import os
class LearningRateTracker(keras.callbacks.Callback):
def __init__(self):
self._lr = list()
def on_epoch_end(self, epoch, logs=None):
optimizer = self.model.optimizer
self._lr.append(tf.keras.backend.get_value(optimizer.lr))
print(f'Epoch {epoch + 1}: Learning rate is {tf.keras.backend.get_value(optimizer.lr)}.\n')
def show_train_learningRate(self):
plt.plot(self._lr)
plt.title('learningRate')
plt.ylabel('learningRate')
plt.xlabel('Epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.savefig('LearningRate.png')
plt.show()
# os.environ['']
# =============================================================================
from keras.utils import np_utils
# =============================================================================
config = tf.compat.v1.ConfigProto()
gpus = tf.config.experimental.list_physical_devices('GPU')
os.environ["CUDA_VISIBLE_DEVICES"] = '0'
session = tf.compat.v1.Session(config=config)
epochs = 150 # 訓練的次數
batch_size = 18
img_rows = None # 驗證碼影像檔的高
img_cols = None # 驗證碼影像檔的寬
# digits_in_img = 6 #驗證碼影像檔中有幾位數
x_list = list() # 存所有驗證碼數字影像檔的array
y_list = list() # 存所有的驗證碼數字影像檔array代表的正確數字
x_train = list() # 存訓練用驗證碼數字影像檔的array
y_train = list() # 存訓練用驗證碼數字影像檔array代表的正確數字
x_test = list() # 存測試用驗證碼數字影像檔的array
y_test = list() # 存測試用驗證碼數字影像檔array代表的正確數字
def split_digits_in_img(img_array, x_list, y_list=None): # 副函式:分割及儲存驗證碼
# for i in range(digits_in_img):
# step = img_cols // digits_in_img #step=圖片總寬度除六
# y_list.append(img_filename[:2]) #將圖片正確數字(檔名)存進 y_list
x_list.append(img_array) # 將圖片存進x_list
input_filepath = './trainingset/1205_Trainning'
file_list = sorted(os.listdir(input_filepath)) # 获取文件名列表.
print(f'file_list = {file_list}')
for classnumber in file_list:
img_filenames = os.listdir(f'{input_filepath}/{classnumber}')
count = 0 # os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表
for img_filename in img_filenames:
count += 1
if '.png' not in img_filename: # 只讀取PNG檔
continue
# img = load_img('./output_file(00)/{0}/{1}'.format(classnumber, img_filename), color_mode='rgb', target_size=(224, 224, 3)) #將圖片依序以灰階讀取
img = load_img('{0}/{1}/{2}'.format(input_filepath, classnumber, img_filename), color_mode='grayscale',
target_size=(112, 112, 1)) # 將圖片依序以灰階讀取
img_array = img_to_array(img) # 將圖片轉換成數值
img_rows, img_cols, _ = img_array.shape # 將圖片長寬分別儲存在img_rows, img_cols,
# print(img_array.shape)
y_list.append(classnumber[:2]) # 將圖片正確數字(檔名)存進 y_list
split_digits_in_img(img_array, x_list, y_list) # 呼叫 副函式:分割及儲存驗證碼
print(f'{classnumber} is ok --> 有{count}')
x_train, x_test, y_train, y_test = train_test_split(x_list, y_list, test_size=0.1,
stratify=y_list) # , stratify=y_list随机划分训练集和测试集
# print(x_train)
# print(y_train)
y_train = keras.utils.to_categorical(y_train) # 將y_list 轉換成categorical形式
y_test = keras.utils.to_categorical(y_test)
# =============================================================================
# y_train_onehot = np_utils.to_categorical(y_train)
# y_test_onehot = np_utils.to_categorical(y_test)
# =============================================================================
# =============================================================================
# if os.path.isfile('cnn_model.h5'): #檢測是否已有模型
# model = models.load_model('cnn_model.h5') #將該模型導入
# print('Model loaded from file.')
# else: #否則:建立新模型
# =============================================================================
model = models.Sequential()
# 創建模型
model.add(layers.Conv2D(input_shape=(112, 112, 1), filters=64, kernel_size=(4, 4), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=64, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2)))
model.add(layers.Dropout(rate=0.3)) # 0
model.add(layers.Conv2D(filters=128, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=128, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2)))
model.add(layers.Dropout(rate=0.2)) # 0
model.add(layers.Conv2D(filters=256, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=256, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=256, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=256, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2)))
model.add(layers.Dropout(rate=0.2)) # 0
model.add(layers.Conv2D(filters=512, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=512, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=512, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=512, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2)))
model.add(layers.Dropout(rate=0.2)) # 5
model.add(layers.Conv2D(filters=512, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=512, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=512, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.Conv2D(filters=512, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(units=4096, activation="relu"))
model.add(layers.Dropout(rate=0.5)) # 6
model.add(layers.Dense(units=4096, activation="relu"))
model.add(layers.Dense(units=17, activation="softmax")) # 這是類別數
# 全連接層 (輸出空間的維數,activation)
print('New model created.') # 全連接層 (輸出空間的維數,activation)
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(learning_rate=0.000001, beta_1=0.9, beta_2=0.999), metrics=['accuracy'])
# model.compile 編譯模型optimizer =優化器loss =損失函數, metrics= [“準確率”]
# model.fit(np.array(x_train), np.array(y_train), batch_size=digits_in_img, epochs=epochs, verbose=1, validation_data=(np.array(x_test), np.array(y_test)))
# =============================================================================
checkpoint_filepath = os.path.sep.join(['checkpoint',
"weights-{epoch:03d}-{loss:.9f}-{val_accuracy:.4f}.h5"])
model_checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_filepath,
save_weights_only=False,
monitor='loss',
mode='min',
save_best_only=True)
lr_tracker = LearningRateTracker()
with tf.device('/cpu:0'):
x_train = tf.convert_to_tensor(x_train, np.float32)
y_train = tf.convert_to_tensor(y_train, np.float32)
train_history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1,
callbacks=[model_checkpoint_callback, lr_tracker],
validation_data=(np.array(x_test), np.array(y_test)), shuffle=True)
import matplotlib.pyplot as plt
def show_train_history(train_history, title, train_metric, val_metric):
plt.plot(train_history.history[train_metric])
plt.plot(train_history.history[val_metric])
plt.title(title)
plt.ylabel(train_metric)
plt.xlabel('Epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.savefig(f'{title}.png')
plt.show()
show_train_history(train_history, 'Accuracy', 'accuracy', 'val_accuracy')
show_train_history(train_history, 'Loss', 'loss', 'val_loss')
lr_tracker.show_train_learningRate()
# =============================================================================
loss, accuracy = model.evaluate(np.array(x_test), np.array(y_test), verbose=1) # 評估模型(verbose0或1。詳細模式。 0 =靜音1 =進度欄。)
# print('Test loss:', loss)
# print('Test accuracy:', accuracy)
model.save('model1124.h5')
print(model.summary())