2015-08-01 2 views
3

Я учусь использовать theano. Я хочу, чтобы заполнить матрицу терм-документ (NumPy разреженной матрицы) путем вычисления двоичного TF-IDF для каждого элемента внутри него:Платформа Theano GPU медленнее, чем numpy

import theano 
import theano.tensor as T 
import numpy as np 
from time import perf_counter 

def tfidf_gpu(appearance_in_documents,num_documents,document_words): 
    start = perf_counter() 
    APP = T.scalar('APP',dtype='int32') 
    N = T.scalar('N',dtype='int32') 
    SF = T.scalar('S',dtype='int32') 
    F = (T.log(N)-T.log(APP))/SF 
    TFIDF = theano.function([N,APP,SF],F) 
    ret = TFIDF(num_documents,appearance_in_documents,document_words) 
    end = perf_counter() 
    print("\nTFIDF_GPU ",end-start," secs.") 
    return ret 

def tfidf_cpu(appearance_in_documents,num_documents,document_words): 
    start = perf_counter() 
    tfidf = (np.log(num_documents)-np.log(appearance_in_documents))/document_words 
    end = perf_counter() 
    print("TFIDF_CPU ",end-start," secs.\n") 
    return tfidf 

Но Numpy версии гораздо быстрее, чем реализация Theano:

Progress 1/43 
TFIDF_GPU 0.05702276699594222 secs. 
TFIDF_CPU 1.454801531508565e-05 secs. 

Progress 2/43 
TFIDF_GPU 0.023830442980397493 secs. 
TFIDF_CPU 1.1073017958551645e-05 secs. 

Progress 3/43 
TFIDF_GPU 0.021920352999586612 secs. 
TFIDF_CPU 1.0738993296399713e-05 secs. 

Progress 4/43 
TFIDF_GPU 0.02303648801171221 secs. 
TFIDF_CPU 1.1675001587718725e-05 secs. 

Progress 5/43 
TFIDF_GPU 0.02359767400776036 secs. 
TFIDF_CPU 1.4385004760697484e-05 secs. 

.... 

Я читал, что это может быть из-за накладных расходов, что для небольших операций может привести к гибели производительности.

Является ли мой код плохим или мне следует избегать использования графического процессора из-за накладных расходов?

+1

Насколько я могу судить, ваши функции работают только на скалярных входных значениях ('T.scalar'). Нет смысла использовать GPU, если вы не имеете дело с достаточно большими массивами и выполняете векторизованные операции с использованием нескольких элементов массива. –

ответ

7

Дело в том, что вы каждый раз составляете свою функцию Theano. Компиляция требует времени. Попробуйте передать скомпилированную функцию следующим образом:

def tfidf_gpu(appearance_in_documents,num_documents,document_words,TFIDF): 
    start = perf_counter() 
    ret = TFIDF(num_documents,appearance_in_documents,document_words) 
    end = perf_counter() 
    print("\nTFIDF_GPU ",end-start," secs.") 
    return ret 

APP = T.scalar('APP',dtype='int32') 
N = T.scalar('N',dtype='int32') 
SF = T.scalar('S',dtype='int32') 
F = (T.log(N)-T.log(APP))/SF 
TFIDF = theano.function([N,APP,SF],F) 

tfidf_gpu(appearance_in_documents,num_documents,document_words,TFIDF) 

Также ваша задача TFIDF - задача с интенсивной полосой пропускания. Theano и GPU в целом лучше всего подходят для интенсивных вычислений.

Текущая задача будет значительной накладной, взяв данные на GPU и обратно, потому что в конце вам нужно будет прочитать каждый элемент O (1) раз. Но если вы хотите сделать больше вычислений, имеет смысл использовать графический процессор.

+0

Благодарим вас за то, что я каждый раз составлял свою функцию. Это было поучительно. Теперь я получаю аналогичные тайминги, но графический процессор все еще немного медленнее, поэтому я не буду использовать его для такой «простой» задачи. – Vektor88

Смежные вопросы