CNN進行示功圖分類
-
- 資料讀入
- 批量加載
- 模組化訓練
圖檔存放在12個檔案夾裡面,一共12個類,相同類别的圖檔存在放在同一個檔案夾中。整個模型的建立過程分為資料讀入,使用批量生成器生成訓練集,模組化訓練。
資料讀入
使用os自帶的檔案讀入機制,先讀入每一個檔案夾的路徑,一共得到12個檔案夾路徑,再通過每一個檔案夾路徑,将這個檔案夾下的圖檔讀入到一個清單裡。
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
import os
from keras.utils.np_utils import to_categorical
from keras.models import Sequential
from keras.layers.core import Dense ,Dropout, Flatten
from keras.callbacks import EarlyStopping
from keras.layers import Conv2D
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split
import tensorflow as tf
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
config = tf.ConfigProto(allow_soft_placement = True)
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction = 0.5)
config.gpu_options.allow_growth = True
sess0 = tf.InteractiveSession(config = config)
path_1=r'C:\Users\22167\Desktop\Machine Learnning Datasets\Diagram_Train_CNN'
file1=os.listdir(path_1)
labels = [os.path.join(path_1,i) for i in file1]
image_routes=[]#存儲訓練集的圖檔路徑
image_labels=[]#存儲對應的标簽
for i in range(len(labels)):
for filename in os.listdir(labels[i]):
image_routes.append(os.path.join(labels[i], filename))
image_labels.append(i)
n_classes = len(set(labels)) #得到圖檔類别數量
image_labels = to_categorical(image_labels, n_classes) #進行獨熱編碼
批量加載
由于圖檔數量太多,無法一次性讀入記憶體進行訓練,不然會顯示記憶體錯誤,采用批量加載,一邊讀入圖檔到記憶體,一邊訓練,,這樣的訓練方式節省了記憶體,但是時間消耗大,而且對于訓練集的覆寫率沒有全部讀取到記憶體再訓練這種方式高。
def batchgen(image_routes_train,batch_size,image_size_rows,image_size_cols):#建立批量加載圖檔的生成器
batch_images = np.zeros((batch_size,image_size_rows,image_size_cols,4))#儲存加載的圖檔數字矩陣
batch_labels = np.zeros((batch_size,len(labels)))#儲存每個類别
i=0
while True:
n=0
while n<batch_size: #定義每一個批次加載的圖檔的數量
#i=np.random.randint(len(image_routes_train))
if(i>=len(image_routes_train)):
i=0
img =mpimg.imread(image_routes_train[i])
img=np.array(img)
batch_images[n]=img
batch_labels[n]=image_labels_train[i]
n=n+1
i=i+1
yield batch_images, batch_labels #傳回訓練集的生成器
模組化訓練
使用keras的fit_generator進行訓練,将剛才的批量生成器添加到模型訓練。
#定義訓練集,測試集合和其他超參數
image_routes_train,image_routes_test,image_labels_train,image_labels_test = train_test_split(image_routes,image_labels,test_size=0.3)
input_shape = (190,400,4)
batch_size = 8
n_epochs =4
steps_per_epoch=round(len(image_routes_train)/batch_size) #定義内一個e_pochs訓練多少個批次
validation_steps=round(len(image_routes_test)/batch_size) #定義每一次測試,測試多少個批次
train_generator = batchgen(image_routes_train,batch_size,190,400)
val_generator = batchgen(image_routes_test,batch_size,190,400)
callbacks = [EarlyStopping(monitor='val_accuracy', patience=5)]
#使用fit_generator進行訓練
model_batch = Sequential()
model_batch.add(Conv2D(16, kernel_size=(4,4), activation = 'relu', input_shape=input_shape))
model_batch.add(Conv2D(32, kernel_size=(4,4), activation='relu' ))
model_batch.add(Flatten()) #卷積層連結全連接配接層需要展平
model_batch.add(Dense(16, activation='relu'))
model_batch.add(Dense(n_classes, activation='softmax'))
opt = Adam()
model_batch.compile(loss='categorical_crossentropy',optimizer=opt, metrics=['accuracy'])
model_batch.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=n_epochs)
模型訓練完成後,發現測試效果并不理想,準确率在90%左右波動。
後面準備從,特征降維,更換神經網絡,或者資料集方面去尋找解決方案。