可视化网络的特征层,假如resnet网络输出的特征维度是(batch_size,512). 如果要可视化测试集的每个图片的512高维度特征分布呢?
embeds = resnet18(x),embeds是(batch_size,512)高维度特征。如下可视化。
import torch
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
from sklearn.utils import shuffle
def plot_tsne(labels, embeds, filename):
"""
可视化特征分布
embeds: (image_num,512). torch.float32
labels: (image_num,). torch.bool。控制绘制类别颜色,如果只是绘制特征的空间分布位置,则不要label
"""
# 初始化t-SNE模型
"""
n_components: 指定降维后的维度数量
verbose: 控制算法运行时输出的信息量。设置为1时,会打印出算法的迭代过程等信息;设置为0则不会打印任何信息。
perplexity: 这个参数可以被看作是每个点的有效邻域大小。它平衡了局部和全局结构的权重。较小的值会使t-SNE更关注局部结构,
而较大的值则更倾向于保留全局结构。通常在5到50之间选择一个合适的值,但这个最佳值可能依赖于数据集的具体情况。
n_iter: t-SNE算法的迭代次数。更多的迭代次数可能会导致更好的结果,但也会增加计算时间。通常,推荐至少设置250次以上的迭代以获得可靠的结果。
"""
tsne = TSNE(n_components=2, verbose=1, perplexity=30, n_iter=500)
# 打乱嵌入向量和标签
embeds, labels = shuffle(embeds, labels)
# 将(image_num,512)降为到(image_num,2)
tsne_results = tsne.fit_transform(embeds)
# 创建图形
fig, ax = plt.subplots(1)
colormap = ["b", "r", "c", "y"] # 传入label的意义就是绘制时,label为1,则绘制点为红色,为0则是蓝色。
# 绘制散点图
ax.scatter(x=tsne_results[:, 0], y=tsne_results[:, 1], color=[colormap[l] for l in labels])
fig.savefig(filename)
plt.close()
# get embeddings for test data 可视化整个测试集的所有图片
labels = torch.cat(labels) # (image_num,)
embeds = torch.cat(embeds) # 特征层(image_num,512)
# norm embeds 测试集
# p: 范数的类型。p=2 表示使用L2范数(欧几里得范数)。其他常见的选项包括 p=1(L1范数)和 p=float('inf')(无穷范数)。
# dim: 指定归一化的维度。
embeds = torch.nn.functional.normalize(embeds, p=2, dim=1) # (test_image_num,512)
# plot tsne
plot_tsne(labels, embeds, "tsne.png")