402 lines
19 KiB
Python
402 lines
19 KiB
Python
# -*- 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 = r'D:\trainning\trainningCreat0321'
|
||
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.001,
|
||
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.1))
|
||
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.6))
|
||
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.8))
|
||
# 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.6))
|
||
# 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.2))
|
||
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.00001, 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}-{accuracy:.6f}.h5"])
|
||
model_checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(
|
||
filepath=checkpoint_filepath,
|
||
save_weights_only=False,
|
||
monitor='loss',
|
||
mode='min',
|
||
save_best_only=True)
|
||
|
||
checkpoint_filepath = os.path.sep.join(['checkpoint_accuracy',
|
||
"weights-{epoch:03d}-{loss:.9f}-{accuracy:.6f}.h5"])
|
||
model_checkpoint_callback_accuracy = tf.keras.callbacks.ModelCheckpoint(
|
||
filepath=checkpoint_filepath,
|
||
save_weights_only=False,
|
||
monitor='accuracy',
|
||
mode='max',
|
||
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, model_checkpoint_callback_accuracy, 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) # 評估模型(verbose:0或1。詳細模式。 0 =靜音,1 =進度欄。)
|
||
# print('Test loss:', loss)
|
||
# print('Test accuracy:', accuracy)
|
||
|
||
model.save('model0325_4060.h5')
|
||
print(model.summary())
|
||
|
||
# # -*- 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 = 16
|
||
# 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 = './trainningset/0920 Milwaukee_TrainCreat'
|
||
# 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=(224, 224, 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=(224, 224, 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.1))
|
||
# 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))
|
||
# 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.7))
|
||
# 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.8))
|
||
# 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.6))
|
||
# model.add(layers.Dense(units=4096, activation="relu"))
|
||
# model.add(layers.Dense(units=16, activation="softmax")) # 這是類別數
|
||
# # 全連接層 (輸出空間的維數,activation)
|
||
# print('New model created.') # 全連接層 (輸出空間的維數,activation)
|
||
#
|
||
# model.compile(loss=keras.losses.categorical_crossentropy,
|
||
# optimizer=keras.optimizers.Adam(learning_rate=0.00001, 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()
|
||
# train_history = model.fit(np.array(x_train), np.array(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) # 評估模型(verbose:0或1。詳細模式。 0 =靜音,1 =進度欄。)
|
||
# # print('Test loss:', loss)
|
||
# # print('Test accuracy:', accuracy)
|
||
#
|
||
# model.save('model1002.h5')
|
||
# print(model.summary()) |