import os
import pickle
import numpy as np
from keras import models
from keras import layers
from keras import optimizers
import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
# 將模型寫入到文件
def writer_file(file, model):
f = open(file, "wb")
byte = pickle.dumps(model)
f.write(byte)
f.close()
# 讀取模型文件
def read_file(file):
f = open(file, "rb")
my_byte = f.read()
f.close()
return pickle.loads(my_byte)
# 轉化圖片
def format_pacture(file_dir, ):
datagen = ImageDataGenerator(rescale=1. / 255) # 圖像的三維張量轉爲[0,1]之間
generator = datagen.flow_from_directory(
file_dir,
target_size=(150, 150), # 轉化圖像大小爲150*150
batch_size=120, # 迭代圖片一批有120張
class_mode='binary' # 訓練時使用了binary_crossentropy,所以這裏使用2進制標籤
)
return generator
# 轉化圖片
def rotate(file_dir):
datagen = ImageDataGenerator(
rescale=1. / 255, # 圖像的三維張量轉爲[0,1]之間
rotation_range=40, # 圖像的旋轉範圍爲[0,40]度
width_shift_range=0.2, # 圖像左右平移比例,最大爲1
height_shift_range=0.2, # 圖像上下平移比例,最大爲1
shear_range=0.2, # 隨機錯切變換角度
zoom_range=0.2, # 圖像隨機縮放範圍
horizontal_flip=True # 是否隨機將一半圖像水平翻轉
)
generator = datagen.flow_from_directory(
file_dir,
target_size=(150, 150), # 轉化圖像大小爲150*150
batch_size=200, # 迭代圖片一批有120張
class_mode='binary' # 訓練時使用了binary_crossentropy,所以這裏使用2進制標籤
)
return generator
# 識別測試的時候先修改圖像尺寸,並將圖片設置爲[0,1]之間的數值,神經網絡善於處理這樣的數據,訓練的時候也是用的這個範圍
def format_pucture(file_path, shape):
from keras.preprocessing import image
img = image.load_img(file_path, target_size=shape)
array = image.img_to_array(img)
array = array.reshape((1,) + shape) / 255
return array
# web 展示
def show(history_dict):
loss = history_dict["loss"]
accuracy = history_dict["acc"]
# 驗證曲線衆座標
val_loss = history_dict["val_loss"]
val_accuracy = history_dict["val_acc"]
# 兩條曲線的橫座標
plt.plot(range(1, len(history_dict["loss"])), val_loss, color='blue', ls="--", label="val_loss") # 實線
plt.plot(range(1, len(history_dict["val_loss"])), loss, color='blue', ls="-", label="loss") # 點
plt.plot(range(1, len(history_dict["accuracy"])), accuracy, color='red', ls="-", label="accuracy") # 點
plt.plot(range(1, len(history_dict["val_accuracy"])), val_accuracy, color='red', ls="--",
label="val_accuracy") # 實線
plt.xlabel("epochs")
plt.legend()
plt.show()
#
home = r"D:/data/train"
# 貓狗的訓練圖像
home_train = home + "/train/"
train_cats_dir = os.path.join(home_train, "cats")
train_dogs_dir = os.path.join(home_train, "dogs")
# 貓狗的校驗圖像
home_val = home + "/val/"
val_cats_dir = os.path.join(home_val, "cats")
val_dogs_dir = os.path.join(home_val, "dogs")
model = models.Sequential() # 創建神經網絡
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) # 設置輸入層爲(150,150,3)的彩色圖片,有64個網絡節點
model.add(layers.MaxPool2D(2, 2)) # 將網絡的輸出內容聚合爲之前的1/2
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Flatten()) # 鋪平
model.add(layers.Dropout(0.1)) # 刪除部分數據,防止過擬合
model.add(layers.Dense(512, activation='relu')) # 設置有512個節點的網絡層
model.add(layers.Dense(1, activation='sigmoid')) # 設置一個節點的網絡層使用sigmoid二分類
model.compile(optimizer=optimizers.RMSprop(lr=1e-4), loss='binary_crossentropy', metrics=['acc']) # 定義損失函數
# 創建迭代器
train_generator = rotate(home_train) # 訓練集迭代器,下面有貓和狗的子目錄,每一個目錄都是一個標籤
val_generator = format_pacture(home_val) # 驗證集迭代器,不需要設置旋轉所以不用調用rotate
# 訓練並返回迭代次數的損失與精度集合
history = model.fit_generator( # 編譯模型
train_generator, # 訓練集迭代器
steps_per_epoch=100, # 設置一次迭代分成多少批次
epochs=2, # 設置迭代次數
validation_data=val_generator, # 驗證集迭代器
validation_steps=50 # 驗證一批數據量
)
# 輸出損失與精度,找到最佳迭代次數,用於重新訓練,並防止過擬合
print(history)
# 保存訓練好的模型model
writer_file(r"D:\PyProjects\MyTest\卷積神經網絡貓狗識別\model1", model) # 保存目錄
# 讀取之前保存的模型
model = read_file(r"D:\PyProjects\MyTest\卷積神經網絡貓狗識別\identification")
pucture = format_pucture(r"C:\Users\admin\Desktop\pu\1.jpg", (150, 150, 3))
predict = model.predict(pucture)
print("識別的結果爲:", predict) # 貓和狗被識別爲[0,1]之間的數據,越靠近邊緣,分類越精確
深度訓練web可視化
代碼中嵌入callbacks回調值,用於保存訓練日誌
log = r"C:\log_dir"
import keras
callbacks = [
keras.callbacks.TensorBoard(
log_dir=log,
histogram_freq=1,
embeddings_freq=1
)
]
# 訓練並返回迭代次數的損失與精度集合
history = model.fit_generator( # 編譯模型
train_generator, # 訓練集迭代器
steps_per_epoch=500, # 設置一次迭代分成多少批次
epochs=100, # 設置迭代次數
validation_data=val_generator, # 驗證集迭代器
validation_steps=500, # 驗證一批數據量
callbacks=callbacks
)
1.創建日誌目錄log 啓動python訓練程序
2.啓動tensorboard,並指定日誌目錄位置
tensorboard --logdir=C:\log_dir
3.訪問localhost:6006查詢訓練過程