日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

一维卷积网络多分类

發(fā)布時間:2023/11/28 生活经验 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一维卷积网络多分类 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

剛剛接觸到深度學(xué)習(xí),前2個月的時間里,我用一維的卷積神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)了對于一維數(shù)據(jù)集的分類和回歸。由于在做這次課題之前,我對深度學(xué)習(xí)基本上沒有過接觸,所以期間走了很多彎路。

在剛剛收到題目的要求時,我選擇使用TensorFlow來直接編寫函數(shù),結(jié)果由于沒有什么基礎(chǔ),寫了一個周我就放棄了,改用keras來完成我的任務(wù)。

用keras來搭建神經(jīng)網(wǎng)絡(luò)其實(shí)很簡單。我把自己的網(wǎng)絡(luò)模型和數(shù)據(jù)集分享給大家,一起交流一起進(jìn)步。

我們要完成的任務(wù)是對一些給定的濕度特征數(shù)據(jù)進(jìn)行分類,多分類就是最簡單最入門的深度學(xué)習(xí)案例。

我們要完成分類任務(wù)的數(shù)據(jù)集,247*900大小的一個矩陣,其中包含900條濕度信息,每條濕度信息由246位比特構(gòu)成,最后一位表示濕度的類別,數(shù)值1-9,也就是每種濕度有100條。大家可以點(diǎn)擊下邊的鏈接自取。

數(shù)據(jù)集-用做分類.csv

或者百度網(wǎng)盤:

鏈接:https://pan.baidu.com/s/1tZlpRVBjRoGe2jHTKwRm6A
提取碼:bm94

首先是數(shù)據(jù)的導(dǎo)入:

#載入數(shù)據(jù)

df = pd.read_csv(r"數(shù)據(jù)集-用做分類.csv")
X = np.expand_dims(df.values[:, 0:246].astype(float), axis=2)
Y = df.values[:, 246]

X是900條數(shù)據(jù)的特征信息,Y表示真實(shí)類別。特別注意:這里的X在讀取的時候矩陣增加了一維。使用一維卷積神經(jīng)網(wǎng)絡(luò)Conv1D的時候必須要事先這樣對數(shù)據(jù)集進(jìn)行處理,而只使用深度網(wǎng)絡(luò)Dense時不需要額外的增加一維。
具體細(xì)節(jié)大家可以看我之前寫過的一篇博客,比較細(xì)的區(qū)分了這兩種情況:

Conv1D層與Dense層的連接
沒有接觸過的讀者可以查一下只使用深度層和使用卷積層的區(qū)別。CNN眼里只有局部小特征,而DNN只有全局大特征。

最普通的深層神經(jīng)網(wǎng)絡(luò)包含多層神經(jīng)元,從輸入信號中提取信息。每個神經(jīng)元接受來自前一層神經(jīng)元的輸入,并通過權(quán)重和非線性將它們組合起來。與普通神經(jīng)網(wǎng)絡(luò)中每個神經(jīng)元與前一層的所有神經(jīng)元連接不同,CNN中的每個神經(jīng)元只與前一層的少數(shù)神經(jīng)元局部連接。而且,CNN同一層的所有神經(jīng)元都有相同的權(quán)重。CNN層中神經(jīng)元的值通常被稱為特征映射(features maps),因?yàn)樗鼈兛梢员豢醋魇菍?yīng)于輸入的不同部分的特征。卷積神經(jīng)網(wǎng)絡(luò)可以很好地捕獲出原數(shù)據(jù)中的局部簡單特征,隨著層數(shù)的增加,產(chǎn)生的特征映射會捕獲輸入信號越來越多的全局和更復(fù)雜的屬性。它可以在一條數(shù)據(jù)中較短的片段中獲得感興趣的特征,并且該特征在該數(shù)據(jù)片段中的位置不具有高度相關(guān)性

緊接著是對濕度類別的編碼:

# 濕度分類編碼為數(shù)字
encoder = LabelEncoder()
Y_encoded = encoder.fit_transform(Y)
Y_onehot = np_utils.to_categorical(Y_encoded)

Y_onehot編碼是為了讓程序自己來區(qū)分每一條特征信息而添加的編碼。一個簡單的例子解釋一下:

這一步轉(zhuǎn)化工作我們可以利用keras中的np_utils.to_categorical函數(shù)來進(jìn)行。
“one-hot編碼。one-hot編碼的定義是用N位狀態(tài)寄存器來對N個狀態(tài)進(jìn)行編碼。比如[0,…,0],[1,…,1],[2,…,2]有3個分類值,因此N為3,對應(yīng)的one-hot編碼可以表示為100,010,001。”

我們將原始的數(shù)據(jù)集劃分為訓(xùn)練集和測試集:

# 劃分訓(xùn)練集,測試集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y_onehot, test_size=0.3, random_state=0)

我這里把原始數(shù)據(jù)集以7:3的比例劃分為訓(xùn)練集和測試集。訓(xùn)練集用來逼近真實(shí)類別,測試集來測試效果。
接著的是網(wǎng)絡(luò)模型的搭建:

# 定義神經(jīng)網(wǎng)絡(luò)
def baseline_model():model = Sequential()model.add(Conv1D(16, 3, input_shape=(246, 1)))model.add(Conv1D(16, 3, activation='tanh'))model.add(MaxPooling1D(3))model.add(Conv1D(64, 3, activation='tanh'))model.add(Conv1D(64, 3, activation='tanh'))model.add(MaxPooling1D(3))model.add(Conv1D(64, 3, activation='tanh'))model.add(Conv1D(64, 3, activation='tanh'))model.add(MaxPooling1D(3))model.add(Flatten())model.add(Dense(9, activation='softmax'))plot_model(model, to_file='./model_classifier.png', show_shapes=True) # 保存網(wǎng)絡(luò)結(jié)構(gòu)為圖片,這一步可以直接去掉print(model.summary()) # 顯示網(wǎng)絡(luò)結(jié)構(gòu)model.compile(loss='categorical_crossentropy',optimizer='adam', metrics=['accuracy'])return model

這一步往往是最核心的一步,網(wǎng)絡(luò)模型通過卷積層來提取特征,在分類任務(wù)中,網(wǎng)絡(luò)的最后一層為每個類。分類算法得到的是一個決策面,通過對比濕度信息屬于每一類濕度的概率,進(jìn)而對號入座。

經(jīng)過多次調(diào)參嘗試,最后我使用7層Conv1D來提取特征值,每兩層Conv1D后添加一層MaxPooling1D來保留主要特征,減少計算量。每層卷積層使用雙曲正切函數(shù)tanh(hyperbolic tangent function)來提高神經(jīng)網(wǎng)絡(luò)對模型的表達(dá)能力。tanh經(jīng)常被運(yùn)用到多分類任務(wù)中用做激活函數(shù)。

神經(jīng)網(wǎng)絡(luò)本就具有不可解釋性,一般卷積核和全連接的結(jié)點(diǎn)數(shù)按照2的指數(shù)次冪來取。

Flatten()層作為中間層來鏈接卷積神經(jīng)網(wǎng)絡(luò)和全連接層。

神經(jīng)網(wǎng)絡(luò)被訓(xùn)練來最小化一個損失函數(shù)(Softmax loss),該函數(shù)捕捉到網(wǎng)絡(luò)的特征輸出與給定的期望輸出之間的差異。9個輸出結(jié)點(diǎn)對應(yīng)九個類別的濕度,Softmax將每個特征數(shù)據(jù)匹配到概率最大的特征類別。

交叉熵?fù)p失函數(shù)(categorical crossentropy)作為模型訓(xùn)練的損失函數(shù),它刻畫的是當(dāng)前學(xué)習(xí)到的概率分布與實(shí)際概率分布的距離,也就是損失函數(shù)越小,兩個概率分布越相似,此時損失函數(shù)接近于0。

我將網(wǎng)絡(luò)模型繪制成了AlexNet風(fēng)格的示意圖:

這里也給大家安利下這個很好用的繪制神經(jīng)網(wǎng)絡(luò)的工具:

http://alexlenail.me/NN-SVG/AlexNet.html

搭建好網(wǎng)絡(luò)之后就可以開始訓(xùn)練了。

# 訓(xùn)練分類器
estimator = KerasClassifier(build_fn=baseline_model, epochs=40, batch_size=1, verbose=1)
estimator.fit(X_train, Y_train)

batch_size設(shè)為1,然后一共訓(xùn)練40期。

這些數(shù)據(jù)大家都可以根據(jù)自己的實(shí)際情況做出調(diào)整和優(yōu)化。

到這一步已經(jīng)是搭建和訓(xùn)練的部分全部結(jié)束了。

緊接著是測試集來驗(yàn)證訓(xùn)練的準(zhǔn)確性。

為了每次測試前不重復(fù)訓(xùn)練,我們將訓(xùn)練的模型保存下來:

# 將其模型轉(zhuǎn)換為json
model_json = estimator.model.to_json()
with open(r"C:\Users\Desktop\model.json",'w')as json_file:json_file.write(model_json)# 權(quán)重不在json中,只保存網(wǎng)絡(luò)結(jié)構(gòu)
estimator.model.save_weights('model.h5')

下面是讀取模型的部分,這一部分完全可以寫到另一個函數(shù)里:

# 加載模型用做預(yù)測
json_file = open(r"C:\Users\Desktop\model.json", "r")
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights("model.h5")
print("loaded model from disk")
loaded_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 分類準(zhǔn)確率
print("The accuracy of the classification model:")
scores = loaded_model.evaluate(X_test, Y_test, verbose=0)
print('%s: %.2f%%' % (loaded_model.metrics_names[1], scores[1] * 100))
# 輸出預(yù)測類別
predicted = loaded_model.predict(X)
predicted_label = loaded_model.predict_classes(X)
print("predicted label:\n " + str(predicted_label))

當(dāng)然我們也希望可以直觀的顯示出模型的分類精度,和訓(xùn)練的過程。

混淆矩陣經(jīng)常用來表示分類的效果。

#顯示混淆矩陣
plot_confuse(estimator.model, X_test, Y_test)
# 混淆矩陣定義
def plot_confusion_matrix(cm, classes,title='Confusion matrix',cmap=plt.cm.jet):cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]plt.imshow(cm, interpolation='nearest', cmap=cmap)plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標(biāo)簽plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負(fù)號plt.colorbar()tick_marks = np.arange(len(classes))plt.xticks(tick_marks,('0%','3%','5%','8%','10%','12%','15%','18%','20%','25%'))plt.yticks(tick_marks,('0%','3%','5%','8%','10%','12%','15%','18%','20%','25%'))thresh = cm.max() / 2.for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):plt.text(j, i, '{:.2f}'.format(cm[i, j]), horizontalalignment="center",color="white" if cm[i, j] > thresh else "black")plt.tight_layout()plt.ylabel('真實(shí)類別')plt.xlabel('預(yù)測類別')plt.savefig('test_xx.png', dpi=200, bbox_inches='tight', transparent=False)plt.show()# 顯示混淆矩陣
def plot_confuse(model, x_val, y_val):predictions = model.predict_classes(x_val)truelabel = y_val.argmax(axis=-1)   # 將one-hot轉(zhuǎn)化為labelconf_mat = confusion_matrix(y_true=truelabel, y_pred=predictions)plt.figure()plot_confusion_matrix(conf_mat, range(np.max(truelabel)+1))

如果好奇的話你也可以看看每層卷積層到底學(xué)到了什么:

# 可視化卷積層
visual(estimator.model, X_train, 1)

但是我覺得看一維卷積層的特征沒啥意義,畢竟都是一些點(diǎn),看起來有點(diǎn)非人類。

# 卷積網(wǎng)絡(luò)可視化
def visual(model, data, num_layer=1):# data:圖像array數(shù)據(jù)# layer:第n層的輸出layer = keras.backend.function([model.layers[0].input], [model.layers[num_layer].output])f1 = layer([data])[0]print(f1.shape)num = f1.shape[-1]print(num)plt.figure(figsize=(8, 8))for i in range(num):plt.subplot(np.ceil(np.sqrt(num)), np.ceil(np.sqrt(num)), i+1)plt.imshow(f1[:, :, i] * 255, cmap='gray')plt.axis('off')plt.show()

最后運(yùn)行的所有結(jié)果如下:



這個結(jié)果這么好純粹是因?yàn)閿?shù)據(jù)比較好,分類的準(zhǔn)確率很大程度都是依賴你數(shù)據(jù)集本身的區(qū)分度的。

下面是數(shù)據(jù)集的特征圖,從圖上就可以看出數(shù)據(jù)的層次性很直觀。


當(dāng)然我給大家上傳的這部分?jǐn)?shù)據(jù)是我這邊結(jié)果最好的一批,其他數(shù)據(jù)集準(zhǔn)確度達(dá)不到這么高。

下面貼出整個分類過程的完整代碼:

# -*- coding: utf8 -*-
import numpy as np
import pandas as pd
import keras
from keras.models import Sequential
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils,plot_model
from sklearn.model_selection import cross_val_score,train_test_split,KFold
from sklearn.preprocessing import LabelEncoder
from keras.layers import Dense,Dropout,Flatten,Conv1D,MaxPooling1D
from keras.models import model_from_json
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
import itertools# 載入數(shù)據(jù)
df = pd.read_csv(r"C:\Users\Desktop\數(shù)據(jù)集-用做分類.csv")
X = np.expand_dims(df.values[:, 0:246].astype(float), axis=2)
Y = df.values[:, 246]# 濕度分類編碼為數(shù)字
encoder = LabelEncoder()
Y_encoded = encoder.fit_transform(Y)
Y_onehot = np_utils.to_categorical(Y_encoded)# 劃分訓(xùn)練集,測試集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y_onehot, test_size=0.3, random_state=0)# 定義神經(jīng)網(wǎng)絡(luò)
def baseline_model():model = Sequential()model.add(Conv1D(16, 3, input_shape=(246, 1)))model.add(Conv1D(16, 3, activation='tanh'))model.add(MaxPooling1D(3))model.add(Conv1D(64, 3, activation='tanh'))model.add(Conv1D(64, 3, activation='tanh'))model.add(MaxPooling1D(3))model.add(Conv1D(64, 3, activation='tanh'))model.add(Conv1D(64, 3, activation='tanh'))model.add(MaxPooling1D(3))model.add(Flatten())model.add(Dense(9, activation='softmax'))plot_model(model, to_file='./model_classifier.png', show_shapes=True)print(model.summary())model.compile(loss='categorical_crossentropy',optimizer='adam', metrics=['accuracy'])return model# 訓(xùn)練分類器
estimator = KerasClassifier(build_fn=baseline_model, epochs=40, batch_size=1, verbose=1)
estimator.fit(X_train, Y_train)# 卷積網(wǎng)絡(luò)可視化
# def visual(model, data, num_layer=1):
#     # data:圖像array數(shù)據(jù)
#     # layer:第n層的輸出
#     layer = keras.backend.function([model.layers[0].input], [model.layers[num_layer].output])
#     f1 = layer([data])[0]
#     print(f1.shape)
#     num = f1.shape[-1]
#     print(num)
#     plt.figure(figsize=(8, 8))
#     for i in range(num):
#         plt.subplot(np.ceil(np.sqrt(num)), np.ceil(np.sqrt(num)), i+1)
#         plt.imshow(f1[:, :, i] * 255, cmap='gray')
#         plt.axis('off')
#     plt.show()# 混淆矩陣定義
def plot_confusion_matrix(cm, classes,title='Confusion matrix',cmap=plt.cm.jet):cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]plt.imshow(cm, interpolation='nearest', cmap=cmap)plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標(biāo)簽plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負(fù)號plt.colorbar()tick_marks = np.arange(len(classes))plt.xticks(tick_marks,('0%','3%','5%','8%','10%','12%','15%','18%','20%','25%'))plt.yticks(tick_marks,('0%','3%','5%','8%','10%','12%','15%','18%','20%','25%'))thresh = cm.max() / 2.for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):plt.text(j, i, '{:.2f}'.format(cm[i, j]), horizontalalignment="center",color="white" if cm[i, j] > thresh else "black")plt.tight_layout()plt.ylabel('真實(shí)類別')plt.xlabel('預(yù)測類別')plt.savefig('test_xx.png', dpi=200, bbox_inches='tight', transparent=False)plt.show()# seed = 42
# np.random.seed(seed)
# kfold = KFold(n_splits=10, shuffle=True, random_state=seed)
# result = cross_val_score(estimator, X, Y_onehot, cv=kfold)
# print("Accuracy of cross validation, mean %.2f, std %.2f\n" % (result.mean(), result.std()))# 顯示混淆矩陣
def plot_confuse(model, x_val, y_val):predictions = model.predict_classes(x_val)truelabel = y_val.argmax(axis=-1)   # 將one-hot轉(zhuǎn)化為labelconf_mat = confusion_matrix(y_true=truelabel, y_pred=predictions)plt.figure()plot_confusion_matrix(conf_mat, range(np.max(truelabel)+1))# 將其模型轉(zhuǎn)換為json
model_json = estimator.model.to_json()
with open(r"C:\Users\316CJW\Desktop\畢設(shè)代碼\model.json",'w')as json_file:json_file.write(model_json)# 權(quán)重不在json中,只保存網(wǎng)絡(luò)結(jié)構(gòu)
estimator.model.save_weights('model.h5')# 加載模型用做預(yù)測
json_file = open(r"C:\Users\Desktop\model.json", "r")
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights("model.h5")
print("loaded model from disk")
loaded_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 分類準(zhǔn)確率
print("The accuracy of the classification model:")
scores = loaded_model.evaluate(X_test, Y_test, verbose=0)
print('%s: %.2f%%' % (loaded_model.metrics_names[1], scores[1] * 100))
# 輸出預(yù)測類別
predicted = loaded_model.predict(X)
predicted_label = loaded_model.predict_classes(X)
print("predicted label:\n " + str(predicted_label))
#顯示混淆矩陣
plot_confuse(estimator.model, X_test, Y_test)# 可視化卷積層
# visual(estimator.model, X_train, 1)

但是,濕度值到底是連續(xù)的數(shù)值,分類任務(wù)驗(yàn)證了我們數(shù)據(jù)集特征的可分辨性。

下一篇博客中,我將對數(shù)據(jù)集稍作修改,將濕度類別改為真實(shí)濕度值。

利用卷積神經(jīng)網(wǎng)絡(luò)來提取特征,實(shí)現(xiàn)線性回歸,二者同出一脈。

【keras】一維卷積神經(jīng)網(wǎng)絡(luò)做回歸
https://blog.csdn.net/cjw838982809/article/details/106871107

總結(jié)

以上是生活随笔為你收集整理的一维卷积网络多分类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。