tensorboard 数据降维分布图_TSNE如何画出多维数据分布图

论文中一般都会有数据分布的图,很直观的可以看出迁移过程中分类面的改变。

tensorboard 数据降维分布图_TSNE如何画出多维数据分布图_第1张图片

那么这种图是怎么画的呢?很容易想到就是降维(PCA等)了。这里使用更高效的T-SNE流行学习法。如果你想深究,可以看看这个博主的教程写得非常详细,还有其他降维方法。

如果你想学我这样大概了解一下就行了,那就可以跳过。怎么才能简单画出二维分布图呢?(三维一样的道理,不过稍微复杂点)我这里以pytorch自带的MNISTSVHN数据为例。

数据预处理

pytorch里面直接调用是非常方便的,不过是tensor类型,我们要把它转为numpy格式。

MNIST(官方分成train和test了,使用的时候可以根据需要切换):

这里有个问题要注意:因为SVHN是三通道的,MNIST是单通道的,所以要记得expand成三通道的,不然无法concatenate在一起。

def get_mnist(train, path):
    """Get MNIST dataset loader."""
    # image pre-processing
    pre_process = transforms.Compose([transforms.Resize(6),
                                      transforms.ToTensor(),
                                      transforms.Normalize(
                                         [0.5], [0.5])])

    # dataset and data loader
    mnist_dataset = datasets.MNIST(root=path,
                                   train=train,
                                   transform=pre_process,
                                   download=False)
    mnist_data = []
    mnist_label = []
    for i in mnist_dataset:
        # i[0] = i[0].expand(3, 6, 6)
        data = i[0]
        data = data.expand(3,6,6)
        mnist_data.append(data.numpy())
        mnist_label.append(i[1])

    return np.asarray(mnist_data), np.asarray(mnist_label)

SVHN(这里是没有分train和test的):

def get_svhn(path):
    transform = transforms.Compose([
                    transforms.Resize(6),
                    transforms.ToTensor(),
                    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

    svhn = datasets.SVHN(root=path, download=False, transform=transform)

    svhn_data = []
    svhn_label = []
    for i in svhn:
        svhn_data.append(i[0].numpy())
        svhn_label.append(i[1])

    return np.asarray(svhn_data), np.asarray(svhn_label)

注意图像数据应该尽可能resize得很小,不然运算起来会非常慢。图像数量又非常大,这里选取5000个展示。各取2500,然后concatenate在一起(axis=0 0纵1横)。

如果不是jupyter notebook之类的,运算中觉得慢的话可以随时torch.save再torch.load.

定义TSNE,这里是二维的。所以n_components=2

def TSNE(data):
    start = time.time()
    tsne = manifold.TSNE(n_components=2, init='pca', random_state=501)
    datat_tsne = tsne.fit_transform(data)
    # 归一化
    x_min, x_max = datat_tsne.min(0), datat_tsne.max(0)
    X_norm = (datat_tsne - x_min) / (x_max - x_min)  # 归一化
    print("Org data dimension is {}.TSNE data dimension is {}. time:{:.3f}s"
          .format(mnist_data.shape[-1], mnist_tsne.shape[-1], time.time() - start))
    return data

因为是二维,所以降维后就是一个坐标矩阵,[batch_size, 2].

最后使用数据的时候要记得reshape成二维的形式!无论是k-means或者是其他的机器学习方法。

svhn_data = svhn_data.reshape(svhn_data.shape[0], -1)
mnist_data = mnist_data.reshape(mnist_data.shape[0], -1)
m_label = np.ones_like(mnist_label)
s_label = np.zeros_like(svhn_label)
label = np.concatenate((m_label[:1000], s_label[:1000]))
data = np.concatenate((mnist_data[:1000], svhn_data[:1000]), axis=0)

画图

这里使用plt.text进行画图,看起来清晰很多,如果不想显示内容,就plt.scatter即可。而且plt.text使用图例好像麻烦一点,网上找了个方法。

保存图片的时候如果不清晰,记得加上dpi=500

plt.figure(figsize=(8, 8))
    for i in range(X_norm.shape[0]):
        # cm: color map
        plt.text(X_norm[i, 0], X_norm[i, 1], str(label[i]), color=plt.cm.Set1(label[i]),
                 fontdict={'weight': 'bold', 'size': 9})
    plt.xticks([])
    plt.yticks([])
    l = ['MNIST', 'SVHN']
    color = [plt.cm.Set1(1), plt.cm.Set1(0)]
    patches = [mpatches.Patch(color=color[i], label='{:s}'.format(l[i])) for i in range(2)]
    plt.legend(handles=patches)
    plt.savefig('./distribution.jpg', dpi=500)
    plt.show()

tensorboard 数据降维分布图_TSNE如何画出多维数据分布图_第2张图片
单独一个domai的数据分布,classes=10

tensorboard 数据降维分布图_TSNE如何画出多维数据分布图_第3张图片
source domain and target domain

这里不知道怎么把图例的标签设为圆圈?plt.text好像不行,要plt.scatter才行。有会的大佬请指教一下。

你可能感兴趣的:(tensorboard,数据降维分布图)