यह देखते हुए कि थिएनो संकलन होने से पहले मैट्रिस की संख्या ज्ञात है, कोई भी थैनो मैट्रिस की नियमित पायथन सूची का उपयोग कर सकता है।
यहां एक पूरा उदाहरण है जो numpy और Theano संस्करणों के बीच अंतर दिखा रहा है।
यह कोड @ Divakar के वेक्टरीकृत दृष्टिकोण के साथ तुलना करने के लिए अद्यतन किया गया है जो बेहतर प्रदर्शन करता है। थेनो के लिए दो वेक्टरकृत दृष्टिकोण संभव हैं, जहां एक थैनो संगतता करता है, और एक जहां numpy concatenation करता है जिसके परिणामस्वरूप थानो को पास किया जाता है।
import timeit
import numpy as np
import theano
import theano.tensor as tt
def compile_theano_version1(number_of_matrices, n, dtype):
assert number_of_matrices > 0
assert n > 0
L = [tt.matrix() for _ in xrange(number_of_matrices)]
res = tt.zeros(n, dtype=dtype)
for M in L:
res += tt.dot(M.T, M)
return theano.function(L, res)
def compile_theano_version2(number_of_matrices):
assert number_of_matrices > 0
L = [tt.matrix() for _ in xrange(number_of_matrices)]
concatenated_L = tt.concatenate(L, axis=0)
res = tt.dot(concatenated_L.T, concatenated_L)
return theano.function(L, res)
def compile_theano_version3():
concatenated_L = tt.matrix()
res = tt.dot(concatenated_L.T, concatenated_L)
return theano.function([concatenated_L], res)
def numpy_version1(*L):
assert len(L) > 0
n = L[0].shape[1]
res = np.zeros((n, n), dtype=L[0].dtype)
for M in L:
res += np.dot(M.T, M)
return res
def numpy_version2(*L):
concatenated_L = np.concatenate(L, axis=0)
return np.dot(concatenated_L.T, concatenated_L)
def main():
iteration_count = 100
number_of_matrices = 20
n = 300
min_x = 400
dtype = 'float64'
theano_version1 = compile_theano_version1(number_of_matrices, n, dtype)
theano_version2 = compile_theano_version2(number_of_matrices)
theano_version3 = compile_theano_version3()
L = [np.random.standard_normal(size=(x, n)).astype(dtype)
for x in range(min_x, number_of_matrices + min_x)]
start = timeit.default_timer()
numpy_res1 = np.sum(numpy_version1(*L)
for _ in xrange(iteration_count))
print 'numpy_version1', timeit.default_timer() - start
start = timeit.default_timer()
numpy_res2 = np.sum(numpy_version2(*L)
for _ in xrange(iteration_count))
print 'numpy_version2', timeit.default_timer() - start
start = timeit.default_timer()
theano_res1 = np.sum(theano_version1(*L)
for _ in xrange(iteration_count))
print 'theano_version1', timeit.default_timer() - start
start = timeit.default_timer()
theano_res2 = np.sum(theano_version2(*L)
for _ in xrange(iteration_count))
print 'theano_version2', timeit.default_timer() - start
start = timeit.default_timer()
theano_res3 = np.sum(theano_version3(np.concatenate(L, axis=0))
for _ in xrange(iteration_count))
print 'theano_version3', timeit.default_timer() - start
assert np.allclose(numpy_res1, numpy_res2)
assert np.allclose(numpy_res2, theano_res1)
assert np.allclose(theano_res1, theano_res2)
assert np.allclose(theano_res2, theano_res3)
main()
जब (जैसे कुछ) चलाने इस प्रिंट
numpy_version1 1.47830819649
numpy_version2 1.77405482179
theano_version1 1.3603150303
theano_version2 1.81665318145
theano_version3 1.86912039489
पास का दावा है, दिखा रहा है कि थेनो और numpy संस्करणों दोनों की गणना सटीकता के उच्च स्तर के लिए एक ही परिणाम। float64
के बजाय float32
का उपयोग करते समय स्पष्ट रूप से यह सटीकता कम हो जाएगी।
समय के नतीजे बताते हैं कि वेक्टरिज्ड दृष्टिकोण बेहतर नहीं हो सकता है, यह मैट्रिक्स आकारों पर निर्भर करता है। ऊपर दिए गए उदाहरण में मैट्रिस बड़े हैं और गैर-कॉन्सटेनेशन दृष्टिकोण तेज है, लेकिन n
और min_x
पैरामीटर main
फ़ंक्शन में बहुत छोटे होने के बाद बदल दिए जाते हैं तो कॉन्सटेनेशन दृष्टिकोण तेज होता है। GPU (केवल Theano संस्करण) पर चलते समय अन्य परिणाम हो सकते हैं।
थानो संकलन से पहले 'एल' की लंबाई ज्ञात है? –
@DanielRenshaw हाँ, और एल में प्रत्येक मैट्रिक्स का आकार भी जाना जाता है – dontloo