并行T-SNE计算

上篇记录TSNE的文章中,我说体会到TSNE计算慢,耗时长的问题,那么有没有快速、并行的版本可以拿来使用呢?经过搜索后,我找到了MulticoreTSNEopenTSNE,经过测试之后,目前选择了MulticoreTSNE作为Sklearn中的TSNE替代品。那么接下来就看一下,MulticoreTSNE和Sklearn中TSNE的对比。

踩坑

首先一上来就是踩坑,在安装上使用时,就遇到的坑:

1
2
3
4
# 未安装Cmake的话需要执行
pip install cmake
# 已安装CMake的话,可以直接
pip install MulticoreTSNE

但是,当我去执行代码时遇到报错:

1
2
raise RuntimeError('Cannot find/open tsne_multicore shared library')
RuntimeError: Cannot find/open tsne_multicore shared library

在MulticoreTSNE的issues中找到了解决方案: https://github.com/DmitryUlyanov/Multicore-TSNE/issues/32#issuecomment-452848576

卸载之前安装的MulticoreTSNE以后,在Pypi的MulticoreTSNE下载压缩包进行解压,将其中的setup.py文件进行修改:

1
2
3
4
5
6
7
8
9
10
11
if 0 != execute(['cmake',
# 添加该行
'-DCMAKE_GENERATOR_PLATFORM=x64',
'-DCMAKE_BUILD_TYPE={}'.format(build_type),
'-DCMAKE_VERBOSE_MAKEFILE={}'.format(int(self.verbose)),
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY='{}'".format(EXT_DIR),
# set Debug and Release paths to the output directory on Windows
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG='{}'".format(EXT_DIR),
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE='{}'".format(EXT_DIR),
self.cmake_args or "--",
SOURCE_DIR], cwd=BUILD_TEMP):

之后执行

1
python setup.py install

另外,此处大概需要VS2017、g++的编译环境(我的电脑之前就有装,从输出看是需要的),接下来,代码就可以正常工作了。

效果对比

对比的标准就是耗时长短了,将之前的代码进行一些修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE as S_TSNE
from mpl_toolkits.mplot3d import Axes3D
from sklearn.datasets import load_digits
from MulticoreTSNE import MulticoreTSNE as M_TSNE

digits = load_digits()


def s_t_sne(n_components):
s_tsne_digits = S_TSNE(n_components=n_components, random_state=35).fit_transform(digits.data)
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(s_tsne_digits[:, 0], s_tsne_digits[:, 1], s_tsne_digits[:, 2], c=digits.target)
plt.title("S_T-SNE Digits")
plt.savefig("S_T-SNE_Digits_3d.png")


def m_t_sne(n_components):
m_tsne_digits = M_TSNE(n_components=n_components, random_state=35, n_jobs=12).fit_transform(digits.data)
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(m_tsne_digits[:, 0], m_tsne_digits[:, 1], m_tsne_digits[:, 2], c=digits.target)
plt.title("M_T-SNE Digits")
plt.savefig("M_T-SNE_Digits_3d.png")

使用timeit进行基准测试

1
2
3
4
5
%timeit s_t_sne(3)
%timeit m_t_sne(3)

32.5 s ± 873 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
12.6 s ± 400 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

可以看出,MulticoreTSNE的耗时明显短,图片表现出的效果也能满足需要,就只贴MulticoreTSNE版本的图片好了。

但是,MulticoreTSNE中的某些参数在使用时要注意,文档有提到:

Also note that some parameters are there just for the sake of compatibility with sklearn and are otherwise ignored. See MulticoreTSNE class docstring for more info.

openTSNE

之前提到openTSNE同样支持并行计算,为什么没有使用呢,因为如果使用3维的话,openTSNE会报错:

1
Interpolation based t-SNE for >2 dimensions is currently unsupported (and generally a bad idea)

为什么说高于2维是个坏主意,等有时间了解一下是什么原因…

0%