"""
# -*- coding: utf-8 -*-
# @Time : 2024/1/29 15:12
# @Author : 王摇摆
# @FileName: tSneCurve1.py
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44943389?type=blog
# 在该脚本中完成T-SNE的可视化结果分析,起码要出四张图
"""
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.manifold import TSNE
# 设置matplotlib配置参数,使用支持中文的字体
from tcn import TCN
from tensorflow.keras import Sequential, Model
from tensorflow.keras.layers import Bidirectional, LSTM, Flatten, Dense
from tensorflow.keras.regularizers import l2
from original.attention import Attention
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置宋体用于显示中文标签
num_classes = 7
def data_preprocess():
# 加载数据集
x_train = pd.read_csv(r"../../dataset/X_train.csv", header=None)
y_train = pd.read_csv(r"../../dataset/Y_train.csv", header=None)
x_test = pd.read_csv(r"../../dataset/X_test.csv", header=None)
y_test = pd.read_csv(r"../../dataset/Y_test.csv", header=None)
x_train = x_train.values
y_train = y_train.values
x_test = x_test.values
y_test = y_test.values
x_train, x_test = x_train[:, :, np.newaxis], x_test[:, :, np.newaxis] # 在数据中新添加通道维度,用于扩张成为三维数据
return x_train, y_train, x_test, y_test
# 获取数据
x_train, y_train, x_test, y_test = data_preprocess()
input_shape = x_train.shape[1:] # 输入数据的维度
color_map = y_test.argmax(axis=-1) # 将one-hot标签转为一维标签
# 将模型加载好
def get_model():
model = Sequential()
model.add(TCN(nb_filters=16, # 减少过滤器数量
kernel_size=3, # 使用更小的核大小
nb_stacks=1, # 减少堆叠层数
dilations=[1, 2, 4], # 调整扩张率
padding='causal',
use_skip_connections=True,
dropout_rate=0.0,
return_sequences=True,
activation='relu',
kernel_initializer='he_normal',
input_shape=input_shape,
name='BiTCN'))
# 双向LSTM层
model.add(Bidirectional(LSTM(64, return_sequences=True, name='LSTM_layer_1')))
model.add(Bidirectional(LSTM(32, return_sequences=True, name='LSTM_layer_2')))
# 添加Attention层
model.add(Attention(name='Attention_layer'))
# 添加输出层
model.add(Flatten())
model.add(Dense(num_classes, activation='softmax', kernel_regularizer=l2(1e-4)))
return model
# 模型直接加载权重
model = get_model() # 实例化模型
model.summary()
model.load_weights(r'./BiTCN-BiLSTM-Attention.h5')
# BiTCN层分类可视化,将输入数据进行可视化
BiTCN = Model(inputs=model.input, outputs=model.get_layer('Attention_layer').output)
BiTCN_layer = BiTCN.predict(x_test)
# 打印BiTCN层的输出形状
print("原始BiTCN层输出形状:", BiTCN_layer.shape)
# 由于原始BiTCN层输出形状为 (1050, 2048, 16),我们将最后两个维度相乘来重塑数据
BiTCN_layer = BiTCN_layer.reshape(1050, -1) # -1 会自动计算为 2048*16
# -------------------------------tSNE降维分析--------------------------------
# 定义每个类别的颜色和标记
colors = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'black']
markers = ['o', '^', 's', 'P', '*', 'x', 'D']
tsne = TSNE(n_components=2, init='pca', verbose=1, random_state=402)
tsne_results = tsne.fit_transform(BiTCN_layer)
print(tsne_results.shape)
plt.figure(figsize=(10, 8)) # 设定图表大小
for cl in range(7): # 总的类别
indices = np.where(color_map == cl)
indices = indices[0]
plt.scatter(tsne_results[indices, 0], tsne_results[indices, 1],
label=f'类别 {cl}', c=colors[cl], marker=markers[cl])
font = {'size': 10}
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), prop=font) # 图例放置在右侧
plt.xticks(size=12)
plt.yticks(size=12)
plt.xlabel('特征1', size=15)
plt.ylabel('特征2', size=15)
plt.title('BBA模型全模型可视化', fontsize=18)
plt.tight_layout() # 调整布局以适应图例
plt.show()
# plt.savefig('./2BiTCN层.png', dpi=100, bbox_inches='tight')
# print('图片保存成功')
t-SNE降维可视化分析
根据您提供的 BiTCN
层的原始输出形状 (1050, 2048, 16)
,您需要将这个三维数据重塑成二维数据,以便进行 t-SNE 分析。由于 t-SNE 分析通常在二维数据上进行,您需要将最后两个维度相乘,得到 (1050, 32768)
形状的数据,其中 2048 * 16 = 32768
。
以下是您应该如何调整代码:
# 模型直接加载权重
model = get_model(input_shape=input_shape, num_classes=7) # 实例化模型
model.load_weights(r'./BiTCN-BiLSTM-Attention.h5')
# BiTCN层分类可视化,将输入数据进行可视化
BiTCN = Model(inputs=model.input, outputs=model.get_layer('BiTCN').output)
BiTCN_layer = BiTCN.predict(x_test)
# 由于原始BiTCN层输出形状为 (1050, 2048, 16),我们将最后两个维度相乘来重塑数据
BiTCN_layer_reshaped = BiTCN_layer.reshape(1050, -1) # -1 会自动计算为 2048*16
# 接下来是 t-SNE 降维和绘图的代码...
# 确保在 t-SNE 分析和绘图代码中使用 BiTCN_layer_reshaped 而不是原始的 BiTCN_layer
在这里,.reshape(1050, -1)
会自动计算正确的大小以匹配原始数据的元素总数,因此您不需要手动计算 2048*16
。
请注意,t-SNE 是一个非常内存密集型的过程,如果您的数据集非常大,它可能会消耗大量内存和计算资源。因此,如果您发现这个过程运行非常缓慢或者消耗大量内存,您可能需要考虑在运行 t-SNE 之前对数据进行抽样或使用其他降维技术。