t-SNE进行分类可视化

0、引入

我们在论文中通常可以看到下图这样的可视化效果,这就是使用t-SNE降维方法进行的可视化,当然除了t-SNE还有其他的比如PCA等降维等方法,关于这些算法的原理有很多文章可以借阅,这里不展开阐释,重点讲讲如何进行可视化。
在这里插入图片描述

1、基本原理

上面的图中一个点就是一个样本,我们需要明白的是一个样本用两个数值表示(x和y坐标),意味着原来高维的样本被降维到低维(2维)的空间中了。

比如在将一个样本图片输入到VGG网络中,在倒数第二了全连接层有4096个神经元,也就是该样本使用了4096维的向量表示。我们获取到这个向量表示后通过t-SNE进行降维,得到2维的向量表示,我们就可以在平面图中画出该点的位置。

我们清楚同一类的样本,它们的4096维向量是有相似性的,并且降维到2维后也是具有相似性的,所以在2维平面上面它们会倾向聚拢在一起。

可视化的过程中,大概步骤就是:

  • 对于500张图片(样本)进行模型推理,获取倒数第二层的4096特征向量,同时获取到标签,至此我们有两个值data_embed=[500,4096],label=[500,]
  • 使用t-SNE降维,将data_embed降维后,每个样本用2维表示,即data_embed=[500,2]
  • 使用plt将data_embed共500个样本绘制,并且同一类的颜色一致。

2、收集模型中的高维向量表示和标签

这一步主要是收集每个样本的高维特征及标签,高维特征是全连接层的输出,所以需要通过推理模型获取到(需要修改模型使同时输出全连接层输出)。

data_embed_collect=[]
label_collect=[]

for ......
	# inputs.shape=[BS,C,H,W]
	# embed_4096.shape=[BS,4096]
	# output.shape=[BS,1000]
	output,embed_4096=model(inputs)
	
	
	data_embed_collect.append(embed_4096)
	label_collect.append(label)
	......


# data_embed_collect.shape=[iters,BS,4096]
# label_collect.shape=[iters,BS,]

# 在这里,所有样本的4096特征都收集了,并且每个样本的标签也收集了
# data_embed_npy.shape=[samples,4096]
# label_npu.shape=[samples,]
data_embed_npy=torch.cat(data_embed_collect,axis=0).cpu().numpy()
label_npu=torch.cat(label_collect,axis=0).cpu().numpy()

np.save("data_embed_npy.npy",data_embed_npy)
np.save("label_npu.npy",label_npu).

3、进行t-SNE降维并可视化

代码也简单,首先调用t-SNE进行降维降到2维,然后使用plt将2维定位坐标进行绘制,代码如下:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE


def get_fer_data(data_path="vis_fer_data.npy",
                 label_path="vis_fer_label.npy"):
    """
	该函数读取上一步保存的两个npy文件,返回data和label数据
    Args:
        data_path:
        label_path:

    Returns:
        data: 样本特征数据,shape=(BS,embed)
        label: 样本标签数据,shape=(BS,)
        n_samples :样本个数
        n_features:样本的特征维度

    """
    data = np.load(data_path)
    label = np.load(label_path)
    n_samples, n_features = data.shape

    return data, label, n_samples, n_features

color_map = ['r','y','k','g','b','m','c'] # 7个类,准备7种颜色
def plot_embedding_2D(data, label, title):
	"""
	
	"""
    x_min, x_max = np.min(data, 0), np.max(data, 0)
    data = (data - x_min) / (x_max - x_min)
    fig = plt.figure()
    for i in range(data.shape[0]):
        plt.plot(data[i, 0], data[i, 1],marker='o',markersize=1,color=color_map[label[i]])
    plt.xticks([])
    plt.yticks([])
    plt.title(title)
    return fig


def main():
    data, label, n_samples, n_features = get_fer_data()  # 根据自己的路径合理更改

    print('Begining......') 	

	# 调用t-SNE对高维的data进行降维,得到的2维的result_2D,shape=(samples,2)
    tsne_2D = TSNE(n_components=2, init='pca', random_state=0) 
    result_2D = tsne_2D.fit_transform(data)
    
    print('Finished......')
    fig1 = plot_embedding_2D(result_2D, label, 't-SNE')	# 将二维数据用plt绘制出来
    fig1.show()
    plt.pause(50)
    
if __name__ == '__main__':
    main()

7个类,共计3589个样本降维到2维后的效果:
在这里插入图片描述

### 使用 t-SNE 进行特征可视化的具体方法 #### 准备工作 为了使用 t-SNE 实现特征可视化,需先安装必要的库。通常情况下会用到 `scikit-learn` 提供的 T-SNE 工具以及 matplotlib 或 seaborn 来绘制图形。 ```bash pip install scikit-learn matplotlib seaborn pandas numpy ``` #### 加载数据集与预处理 假设有一个高维的数据集 X 和对应的标签 y 。对于图像分类任务中的卷积神经网络中间层输出,则可能需要对张量形状做适当调整以便输入给 t-SNE 算法[^3]。 ```python import numpy as np from sklearn.manifold import TSNE import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 假设X是一个numpy数组形式的高维样本矩阵,y是类别标签向量 # 如果是从CNN提取出来的特征图,则应先flatten成一维向量再送入t-sne if len(X.shape) > 2: num_samples = X.shape[0] feature_dim = int(np.prod(X.shape[1:])) X_flatten = X.reshape((num_samples, feature_dim)) else: X_flatten = X.copy() ``` #### 应用 t-SNE 转换 通过设置合适的参数如 perplexity(困惑度)、early_exaggeration、learning_rate 等可以优化最终效果。默认配置下 n_components 设置为 2 ,即目标维度为两维平面坐标系;也可以设定为三维来进行立体展示[^2]。 ```python tsne_model = TSNE(n_components=2, random_state=42, verbose=1) low_dimensional_data = tsne_model.fit_transform(X_flatten) ``` #### 可视化结果 得到降维后的低维表示之后就可以利用散点图画出来观察不同类别的分布情况了。这里还可以进一步自定义颜色方案或者标记样式让图表更加美观易读[^4]。 ```python def plot_embedding(data, label, title): x_min, x_max = np.min(data, axis=0), np.max(data, axis=0) data = (data - x_min) / (x_max - x_min) fig = plt.figure(figsize=(8, 8)) ax = plt.subplot(111) for i in range(data.shape[0]): plt.text(data[i, 0], data[i, 1], str(label[i]), color=plt.cm.Set1(int(y[i])), fontdict={'weight': 'bold', 'size': 9}) plt.xticks([]), plt.yticks([]) plt.title(title) return fig fig = plot_embedding(low_dimensional_data, y, "tSNE Visualization of Features") plt.show(fig) ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一个对称矩阵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值