集成网络,统一训练:
Ensamble Learning
from keras import Model
from keras.layers.core import Dense, Activation
from keras.layers import Conv2D, Conv1D, MaxPooling2D, Reshape, Concatenate, Dropout , MaxPooling1D, Flatten
from keras.layers import Dense, Input
from keras.utils import plot_model
# ----------------------- MODEL 1 ----------------------
model_1D = Input((7380, 128000))
# 1
model_1D = Conv1D(32, kernel_size= 5 , strides=1, activation='relu')(model_1D)
model_1D = MaxPooling1D(pool_size= 4, strides=4)(model_1D)
# 2
model_1D = Conv1D(32, kernel_size= 5 , strides=1 , activation='relu')(model_1D)
model_1D = MaxPooling1D(pool_size= 4, strides=4)(model_1D)
# 3
model_1D = Conv1D(64, kernel_size= 5 , strides=1 , activation='relu')(model_1D)
model_1D = MaxPooling1D(pool_size= 4, strides=4)(model_1D)
# 4
model_1D = Conv1D(64, kernel_size= 5 , strides=1 , activation='relu')(model_1D)
model_1D = MaxPooling1D(pool_size= 2, strides=2)(model_1D)
# 5
model_1D = Conv1D(128, kernel_size= 5 , strides= 1 , activation='relu')(model_1D)
model_1D = MaxPooling1D(pool_size= 2, strides= 2)(model_1D)
# 6
model_1D = Conv1D(128, kernel_size= 5 , strides= 1 , activation='relu')(model_1D)
model_1D = MaxPooling1D(pool_size= 2, strides= 2)(model_1D)
model_1D = Flatten()(model_1D)
model_1D = Dense(9 , activation='relu')(model_1D)
# ----------------------- MODEL 2 ----------------------
# ----------------------- 2D CNN ----------------------
model_2D = Input((7380, 128, 251))
model_2D = Conv2D(32, kernel_size=(3, 3) , strides=(1,1), activation='relu')(model_2D)
model_2D = Conv2D(32, kernel_size=(3, 3) , strides=(1,1), activation='relu')(model_2D)
model_2D = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(model_2D)
model_2D = Conv2D(32, kernel_size=(3, 3) , strides=(1,1), activation='relu')(model_2D)
model_2D = Conv2D(32, kernel_size=(3, 3) , strides=(1,1), activation='relu')(model_2D)
model_2D = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(model_2D)
model_2D = Flatten()(model_2D)
model_2D = Dense(9 , activation='relu')(model_2D)
merged = Concatenate()([model_1D, model_2D])
output = Dense(7, activation='softmax')(merged)
# ----------------------- ensamble----------------------
model_final = Model(inputs=[in_1D, in_2D], outputs=[output])
# ----------------------- compile----------------------
model_final.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
plot_model(model_final, to_file='model_final.png')
集成模型,综合结果:
'''保存模型'''
model.save("./4classify_model14.hdf5")
# 模型文件所在的目录
models_dir = '/kaggle/input/model-ensemble/'
# 用于存储每个模型的预测结果的列表
all_predictions = []
# 用于存储每个模型文件的列表
model_files = os.listdir(models_dir)
# 循环读取每个模型文件并进行预测
for model_file in model_files:
# 加载模型文件并进行预测
model = keras.models.load_model(os.path.join(models_dir, model_file))
predictions = model.predict(X_test)
all_predictions.append(predictions)
print(len(all_predictions), all_predictions[0].shape) # 样本数,分类数
# 使用numpy.concatenate()函数将每个矩阵的同一行合并
merged_matrix = np.concatenate((all_predictions[0], all_predictions[1], all_predictions[2], all_predictions[3], all_predictions[4],
all_predictions[5], all_predictions[6], all_predictions[7], all_predictions[8], all_predictions[9]), axis=1)
print(merged_matrix.shape)
# 训练一层desen,综合结果
#首先把数据换成可训练shape
merged_matrix = merged_matrix.reshape((-1, 33, 1)).astype("float32") # X_train.shape[0], img_rows, img_cols, 1)
merged_matrix.shape, y_test.shape
# 训练 dense
# 使用Dense层学习模型权重
inputs = keras.layers.Input(shape=(33,1))
inputs = Flatten()(inputs)
dense = keras.layers.Dense(4, activation='softmax')(inputs)
model = keras.models.Model(inputs=inputs, outputs=dense)
# 训练模型
adam = Adam(0.001)
model.compile(loss='categorical_crossentropy', optimizer=adam , metrics=['accuracy']) # binary_crossentropy
model.fit(merged_matrix, y_test, epochs=700, batch_size=80)
# 结合预测结果
weighted_predictions = model.predict(merged_matrix)
final_predictions = np.argmax(weighted_predictions, axis=1)
final_predictions
#模型评估
score = model.evaluate(merged_matrix, y_test, verbose=2)
print('Accuracy: {0:.4%}'.format(score[1]/1))
print("Loss: %.4f\n" % score[0])
# 精确率/召回率/F1-score
# accuracy 表示准确率,也即正确预测样本量与总样本量的比值,
# macro avg 表示宏平均,表示所有类别对应指标的平均值(竖上去的平均)
# weighted avg表 示带权重平均,表示类别样本占总样本的比重与对应指标的乘积的累加和
y_predict = np.argmax(model.predict(merged_matrix), axis=1) # 得出 0 1 2 3
y_test1 = np.argmax(y_test, axis=1)
print(metrics.classification_report(y_test1, y_predict ,digits=4, target_names=['EB','PC','V','IS'])) # ['IS','FA/FP','EB','V','CP/KP']
# 混淆矩阵-显示样本数
confusion_mat = confusion_matrix(y_test.argmax(axis=1), y_predict)
cm = pd.DataFrame(confusion_mat, columns=['EB','PC','V','IS/J'],index=['EB','PC','V','IS/J']) # 为了修改矩阵坐标
# 打混淆矩阵
print('混淆矩阵:')
print(confusion_mat)
# 将混淆矩阵以热力图显示
import seaborn as sns
sns.set()
figure, ax = plt.subplots()
# 画热力图
sns.heatmap(cm, cmap='YlOrBr', fmt='.20g', annot=True, ax=ax, ) # cmap="YlGnBu_r", fmt='.0%''Pastel1' Oranges' 'YlOrBr'
# 标题
#ax.set_title('confusion matrix')
# x轴为预测类别
ax.set_xlabel('Predict',fontdict={"family": "Times New Roman", "style": "normal",'size': 13,})
# y轴实际类别
ax.set_ylabel('True',fontdict={"family": "Times New Roman", "style": "normal",'size': 13,})
plt.show()
#混淆矩阵-显示数量占每行比例(召回率)
confusion_mat = confusion_matrix(y_test.argmax(axis=1), y_predict)
# 计算每行的总和
row_sums = np.sum(confusion_mat, axis=1)
# 将矩阵中的每个元素都除以该行的总和
normalized_matrix = (confusion_mat / row_sums[:, np.newaxis])
cm = pd.DataFrame(normalized_matrix , columns=['EB','PC','V','IS/J'],index=['EB','PC','V','IS/J']) # 为了修改矩阵坐标
# 打混淆矩阵
print('混淆矩阵:')
print(confusion_mat)
# 将混淆矩阵以热力图显示
import seaborn as sns
sns.set()
figure, ax = plt.subplots() # dpi=300
# 画热力图
sns.heatmap(cm, annot=True , fmt='.2%', ax=ax , cmap='YlOrBr')
# 标题
#ax.set_title('confusion matrix')
# x轴为预测类别
ax.set_xlabel('Predict',fontdict={"family": "Times New Roman", "style": "normal",'size': 13,})
# y轴实际类别
ax.set_ylabel('True',fontdict={"family": "Times New Roman", "style": "normal",'size': 13,})
plt.show()
# roc曲线
from itertools import cycle
from sklearn.metrics import roc_curve, auc
plt.style.use('seaborn-white') # 控制底色
# roc曲线
y_true = y.argmax(axis=1)
y_pred = model.predict(merged_matrix)
y_score = y_pred
names = ['EB','PC','V','IS'] # /J
# 计算每一类的ROC
fpr = dict()
tpr = dict()
roc_auc = dict()
n_classes= 4
for i in range(4):
fpr[i], tpr[i], _ = roc_curve(y[:, i], y_score[:, i])
roc_auc[i] = auc(fpr[i], tpr[i])
# Compute micro-average ROC curve and ROC area(方法二)
fpr["micro"], tpr["micro"], _ = roc_curve(y.ravel(), y_score.ravel())
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])
# Compute macro-average ROC curve and ROC area(方法一)
# First aggregate all false positive rates
all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)]))
# Then interpolate all ROC curves at this points
mean_tpr = np.zeros_like(all_fpr)
for i in range(n_classes):
mean_tpr += np.interp(all_fpr, fpr[i], tpr[i])
# Finally average it and compute AUC
mean_tpr /= n_classes
fpr["macro"] = all_fpr
tpr["macro"] = mean_tpr
roc_auc["macro"] = auc(fpr["macro"], tpr["macro"])
# Plot all ROC curves
lw=2
plt.figure(figsize=(10, 6))# ,dpi=300
plt.plot(fpr["micro"], tpr["micro"],
label='micro-average ROC curve (area = {0:0.4f})'
''.format(roc_auc["micro"]),
color='deeppink', linestyle=':', linewidth=4)
plt.plot(fpr["macro"], tpr["macro"],
label='macro-average ROC curve (area = {0:0.4f})'
''.format(roc_auc["macro"]),
color='navy', linestyle=':', linewidth=4)
colors = cycle(['blue', 'red', 'green', 'purple'])
for i, color in zip(range(n_classes), colors):
plt.plot(fpr[i], tpr[i], color=color, lw=lw,
label='ROC curve of class {0} (area = {1:0.4f})'
''.format(names[i], roc_auc[i]))
plt.plot([0, 1], [0, 1], 'k--', lw=lw)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate',fontdict={"family": "Times New Roman", "style": "normal",'size': 15,})
plt.ylabel('True Positive Rate',fontdict={"family": "Times New Roman", "style": "normal",'size': 15,})
#plt.title('Some extension of Receiver operating characteristic to multi-class')
plt.legend(loc="lower right",fontsize=11)
plt.xticks(fontsize=13,fontname='Times New Roman')
plt.yticks(fontsize=13,fontname='Times New Roman')
'''ax = plt.gca()
ax.spines['left'].set_color('black')
ax.spines['bottom'].set_color('black')
ax.spines['top'].set_color('black')
ax.spines['right'].set_color('black')'''
plt.show()
sklearn 官方画图
https://scikit-learn.org/stable/modules/model_evaluation.html