Я сравнил время обработки с theano (CPU), theano (GPU) и Scikit-learn (CPU) с использованием Python. Но я получил странный результат. Вот посмотрите на график, который я рисую.
Сравнение времени обработки:
вы можете увидеть результат scikit-learn, который быстрее, чем theano (GPU). Программа, прошедшее время которой я проверил, состоит в том, чтобы вычислить евклидову матрицу расстояний из матрицы, состоящей из n * 40 элементов.
Вот часть кода.
points = T.fmatrix("points")
edm = T.zeros_like(points)
def get_point_to_points_euclidean_distances(point_id):
euclideans = (T.sqrt((T.sqr(points- points[point_id, : ])).sum(axis=1)))
return euclideans
def get_EDM_CPU(points):
EDM = np.zeros((points.shape[0], points.shape[0])).astype(np.float32)
for row in range(points.shape[0]):
EDM[row, :] = np.sqrt(np.sum((points - points[row, :])**2, axis=1))
return EDM
def get_sk(points):
EDM = sk.pairwise_distances(a, metric='l2')
return EDM
seq = T.arange(T.shape(points)[0])
(result, _) = theano.scan(fn = get_point_to_points_euclidean_distances, \
outputs_info = None , \
sequences = seq)
get_EDM_GPU = theano.function(inputs = [points], outputs = result, allow_input_downcast = True)
Я думал, что причина, по которой GPU работает медленнее, чем обучение с помощью научного набора, вероятно, заключается во времени передачи. Поэтому я профилировал GPU с помощью команды nvprof. тогда я получил это.
==27105== NVPROF is profiling process 27105, command: python ./EDM_test.py
Using gpu device 0: GeForce GTX 580 (CNMeM is disabled, cuDNN not available)
data shape : (10000, 40)
get_EDM_GPU elapsed time : 1.84863090515 (s)
get_EDM_CPU elapsed time : 8.09937691689 (s)
get_EDM_sk elapsed time : 1.10968112946 (s)
ratio : 4.38128395145
==27105== Profiling application: python ./EDM_test.py
==27105== Warning: Found 9 invalid records in the result.
==27105== Warning: This could be because device ran out of memory when profiling.
==27105== Profiling result:
Time(%) Time Calls Avg Min Max Name
71.34% 1.28028s 9998 128.05us 127.65us 128.78us kernel_reduce_01_node_316e2e1cbfbe8cfb8e4a101f329ffeec_0(int, int, float const *, int, int, float*, int)
19.95% 357.97ms 9997 35.807us 35.068us 36.948us kernel_Sub_node_bc41b3f8f12c93d29f2c4360ad445d80_0_2(unsigned int, int, int, float const *, int, int, float const *, int, int, float*, int, int)
7.32% 131.38ms 2 65.690ms 1.2480us 131.38ms [CUDA memcpy DtoH]
1.25% 22.456ms 9996 2.2460us 2.1140us 2.8420us kernel_Sqrt_node_23508f8f49d12f3e8369d543f5620c15_0_Ccontiguous(unsigned int, float const *, float*)
0.12% 2.1847ms 1 2.1847ms 2.1847ms 2.1847ms [CUDA memset]
0.01% 259.73us 5 51.946us 640ns 250.36us [CUDA memcpy HtoD]
0.00% 17.086us 1 17.086us 17.086us 17.086us kernel_reduce_ccontig_node_97496c4d3cf9a06dc4082cc141f918d2_0(unsigned int, float const *, float*)
0.00% 2.0090us 1 2.0090us 2.0090us 2.0090us void copy_kernel<float, int=0>(cublasCopyParams<float>)
Перенос [CUDA memcpy DtoH] был выполнен дважды { 1.248 [us], 131.38 [ms] }
Перенос [CUDA memcpy HtoD] выполнен 5x { min: 640 [ns], max: 250.36 [us] }
Время передачи составляет около 131,639 мс (131,88 мс + 259,73 мкс). но разрыв между GPU и scikit-learn составляет около 700 мс (1,8–1,1 с). Таким образом, разрыв составляет время передачи.
вычисляет ли он только верхнюю треугольную матрицу из симметричной матрицы?
что делает scikit-learn таким быстрым?