使用Keras訓(xùn)練自己的數(shù)據(jù)集——以圖像多分類為例(基于傳統(tǒng)神經(jīng)網(wǎng)絡(luò))

1.準(zhǔn)備數(shù)據(jù)集:

本次以圖像三分類為例捺弦,準(zhǔn)備貓沐绒、狗剖毯、熊貓三種動(dòng)物的圖片數(shù)據(jù)(每種各1000張圖片),依次存放在'./dataset/cats'堂淡、'./dataset/dogs'馋缅、'./dataset/pandas'文件夾中。

2.訓(xùn)練模型:

# 導(dǎo)入所需工具包
import matplotlib
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from keras.models import Sequential
from keras.layers import Dropout
from keras.layers.core import Dense
from keras.optimizers import SGD
from keras import initializers
from keras import regularizers
import utils_paths # 主要用于圖像路徑處理操作绢淀,具體代碼參考最后的附錄
import matplotlib.pyplot as plt
import numpy as np
import argparse
import random
import pickle
import cv2
import os


print("------開始讀取數(shù)據(jù)------")
data = []
labels = []

# 拿到圖像數(shù)據(jù)路徑萤悴,方便后續(xù)讀取
imagePaths = sorted(list(utils_paths.list_images('./dataset')))
random.seed(42)
random.shuffle(imagePaths)


# 遍歷讀取數(shù)據(jù)
for imagePath in imagePaths:
    # 讀取圖像數(shù)據(jù),由于使用神經(jīng)網(wǎng)絡(luò)皆的,需要給拉平成一維
    image = cv2.imread(imagePath)
    image = cv2.resize(image, (32, 32)).flatten()
    data.append(image)

    # 讀取標(biāo)簽
    label = imagePath.split(os.path.sep)[-2]
    labels.append(label)

# 對(duì)圖像數(shù)據(jù)做scale操作
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)

# 切分?jǐn)?shù)據(jù)集
(trainX, testX, trainY, testY) = train_test_split(data,
    labels, test_size=0.25, random_state=42)

# 轉(zhuǎn)換標(biāo)簽為one-hot encoding格式
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)

# 構(gòu)造網(wǎng)絡(luò)模型結(jié)構(gòu):本次為3072-128-64-3
model = Sequential()
# kernel_regularizer=regularizers.l2(0.01) L2正則化項(xiàng)
# initializers.TruncatedNormal 初始化參數(shù)方法覆履,截?cái)喔咚狗植?model.add(Dense(128, input_shape=(3072,), activation="relu" ,kernel_initializer = initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None),kernel_regularizer=regularizers.l2(0.01)))
model.add(Dropout(0.5))
model.add(Dense(64, activation="relu",kernel_initializer = initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None),kernel_regularizer=regularizers.l2(0.01)))
model.add(Dropout(0.5))
model.add(Dense(len(lb.classes_), activation="softmax",kernel_initializer = initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None),kernel_regularizer=regularizers.l2(0.01)))

# 初始化參數(shù)
INIT_LR = 0.001
EPOCHS = 2000

# 模型編譯
print("------準(zhǔn)備訓(xùn)練網(wǎng)絡(luò)------")
opt = SGD(lr=INIT_LR)
model.compile(loss="categorical_crossentropy", optimizer=opt,
    metrics=["accuracy"])

# 擬合模型
H = model.fit(trainX, trainY, validation_data=(testX, testY),
    epochs=EPOCHS, batch_size=32)

# 測(cè)試網(wǎng)絡(luò)模型
print("------正在評(píng)估模型------")
predictions = model.predict(testX, batch_size=32)
print(classification_report(testY.argmax(axis=1),
    predictions.argmax(axis=1), target_names=lb.classes_))


# 繪制結(jié)果曲線
N = np.arange(0, EPOCHS)
plt.style.use("ggplot")
plt.figure()
plt.plot(N[1500:], H.history["accuracy"][1500:], label="train_acc")
plt.plot(N[1500:], H.history["val_accuracy"][1500:], label="val_acc")
plt.title("Training and Validation Accuracy (Simple NN)")
plt.xlabel("Epoch #")
plt.ylabel("Accuracy")
plt.legend()
plt.savefig('./output/simple_nn_plot_acc.png')

plt.figure()
plt.plot(N, H.history["loss"], label="train_loss")
plt.plot(N, H.history["val_loss"], label="val_loss")
plt.title("Training and Validation Loss (Simple NN)")
plt.xlabel("Epoch #")
plt.ylabel("Loss")
plt.legend()
plt.savefig('./output/simple_nn_plot_loss.png')


# 保存模型到本地
print("------正在保存模型------")
model.save('././output/simple_nn.model')
f = open('./output/simple_nn_lb.pickle', "wb") # 保存標(biāo)簽數(shù)據(jù)
f.write(pickle.dumps(lb))
f.close()

運(yùn)行得到如下文件數(shù)據(jù):

3.加載模型進(jìn)行預(yù)測(cè):

# 導(dǎo)入所需工具包
from keras.models import load_model
import argparse
import pickle
import cv2


# 加載測(cè)試數(shù)據(jù)并進(jìn)行相同預(yù)處理操作
image = cv2.imread('./cs_image/panda.jpg')
output = image.copy()
image = cv2.resize(image, (32, 32))

# scale圖像數(shù)據(jù)
image = image.astype("float") / 255.0

# 對(duì)圖像進(jìn)行拉平操作
image = image.flatten()
image = image.reshape((1, image.shape[0]))

# 讀取模型和標(biāo)簽
print("------讀取模型和標(biāo)簽------")
model = load_model('./output/simple_nn.model')
lb = pickle.loads(open('./output/simple_nn_lb.pickle', "rb").read())

# 預(yù)測(cè)
preds = model.predict(image)

# 得到預(yù)測(cè)結(jié)果以及其對(duì)應(yīng)的標(biāo)簽
i = preds.argmax(axis=1)[0]
label = lb.classes_[i]

# 在圖像中把結(jié)果畫出來(lái)
text = "{}: {:.2f}%".format(label, preds[0][i] * 100)
cv2.putText(output, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7,(0, 0, 255), 2)

# 繪圖
cv2.imshow("Image", output)
cv2.waitKey(0)

最終得到預(yù)測(cè)結(jié)果:

4.附錄:

utils_paths.py代碼如下:

import os


image_types = (".jpg", ".jpeg", ".png", ".bmp", ".tif", ".tiff")


def list_images(basePath, contains=None):
    # 返回有效的圖片路徑數(shù)據(jù)集
    return list_files(basePath, validExts=image_types, contains=contains)


def list_files(basePath, validExts=None, contains=None):
    # 遍歷圖片數(shù)據(jù)目錄,生成每張圖片的路徑
    for (rootDir, dirNames, filenames) in os.walk(basePath):
        # 循環(huán)遍歷當(dāng)前目錄中的文件名
        for filename in filenames:
            # if the contains string is not none and the filename does not contain
            # the supplied string, then ignore the file
            if contains is not None and filename.find(contains) == -1:
                continue

            # 通過(guò)確定.的位置费薄,從而確定當(dāng)前文件的文件擴(kuò)展名
            ext = filename[filename.rfind("."):].lower()

            # 檢查文件是否為圖像硝全,是否應(yīng)進(jìn)行處理
            if validExts is None or ext.endswith(validExts):
                # 構(gòu)造圖像路徑
                imagePath = os.path.join(rootDir, filename)
                yield imagePath

卷積神經(jīng)網(wǎng)絡(luò)可以參看使用Keras訓(xùn)練自己的數(shù)據(jù)集——以圖像多分類為例(基于卷積神經(jīng)網(wǎng)絡(luò))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市义锥,隨后出現(xiàn)的幾起案子柳沙,更是在濱河造成了極大的恐慌,老刑警劉巖拌倍,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赂鲤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡柱恤,警方通過(guò)查閱死者的電腦和手機(jī)数初,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)梗顺,“玉大人泡孩,你說(shuō)我怎么就攤上這事∷掳” “怎么了仑鸥?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)变屁。 經(jīng)常有香客問(wèn)我眼俊,道長(zhǎng),這世上最難降的妖魔是什么粟关? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任疮胖,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘澎灸。我一直安慰自己院塞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布性昭。 她就那樣靜靜地躺著拦止,像睡著了一般。 火紅的嫁衣襯著肌膚如雪糜颠。 梳的紋絲不亂的頭發(fā)上创泄,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音括蝠,去河邊找鬼鞠抑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛忌警,可吹牛的內(nèi)容都是我干的搁拙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼法绵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼箕速!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起朋譬,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤盐茎,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后徙赢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體字柠,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年狡赐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窑业。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡枕屉,死狀恐怖常柄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搀擂,我是刑警寧澤西潘,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站哨颂,受9級(jí)特大地震影響喷市,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咆蒿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一东抹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沃测,春花似錦缭黔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至附迷,卻和暖如春惧互,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背喇伯。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工喊儡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人稻据。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓艾猜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親捻悯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匆赃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容