TensorFlow.org पर देखें | Google Colab में चलाएं | गिटहब पर देखें | नोटबुक डाउनलोड करें |
बहुत सारे शून्य मान वाले टेंसर के साथ काम करते समय, उन्हें एक स्थान- और समय-कुशल तरीके से संग्रहीत करना महत्वपूर्ण है। विरल टेंसर कुशल भंडारण और टेंसर के प्रसंस्करण को सक्षम करते हैं जिसमें बहुत अधिक शून्य मान होते हैं। एनएलपी अनुप्रयोगों में डेटा प्री-प्रोसेसिंग के हिस्से के रूप में टीएफ-आईडीएफ जैसी एन्कोडिंग योजनाओं में विरल टेंसर का व्यापक रूप से उपयोग किया जाता है और कंप्यूटर विज़न अनुप्रयोगों में बहुत सारे डार्क पिक्सल के साथ प्री-प्रोसेसिंग छवियों के लिए।
TensorFlow में विरल टेंसर
TensorFlow tf.SparseTensor
ऑब्जेक्ट के माध्यम से विरल टेंसर का प्रतिनिधित्व करता है। वर्तमान में, TensorFlow में विरल टेंसर समन्वय सूची (COO) प्रारूप का उपयोग करके एन्कोड किए गए हैं। यह एन्कोडिंग प्रारूप एम्बेडिंग जैसे हाइपर-स्पैस मैट्रिसेस के लिए अनुकूलित है।
विरल टेंसर के लिए सीओओ एन्कोडिंग में निम्न शामिल हैं:
-
values
: आकार के साथ एक 1D टेंसर[N]
जिसमें सभी गैर-शून्य मान होते हैं। -
indices
: आकार के साथ एक 2D टेंसर[N, rank]
, जिसमें गैर-शून्य मानों के सूचकांक होते हैं। -
dense_shape
: आकार के साथ एक 1D टेंसर[rank]
, टेंसर के आकार को निर्दिष्ट करता है।
tf.SparseTensor
के संदर्भ में एक गैर-शून्य मान एक ऐसा मान है जो स्पष्ट रूप से एन्कोड नहीं किया गया है। सीओओ विरल मैट्रिक्स के values
में शून्य मानों को स्पष्ट रूप से शामिल करना संभव है, लेकिन इन "स्पष्ट शून्य" को आम तौर पर शामिल नहीं किया जाता है जब एक विरल टेंसर में गैर-शून्य मानों का जिक्र होता है।
एक tf.SparseTensor
Creating बनाना
विरल टेंसरों का निर्माण सीधे उनके values
, indices
और dense_shape
को निर्दिष्ट करके करें।
import tensorflow as tf
st1 = tf.SparseTensor(indices=[[0, 3], [2, 4]],
values=[10, 20],
dense_shape=[3, 10])
जब आप विरल टेंसर को प्रिंट करने के लिए print()
फ़ंक्शन का उपयोग करते हैं, तो यह तीन घटक टेंसर की सामग्री को दिखाता है:
print(st1)
SparseTensor(indices=tf.Tensor( [[0 3] [2 4]], shape=(2, 2), dtype=int64), values=tf.Tensor([10 20], shape=(2,), dtype=int32), dense_shape=tf.Tensor([ 3 10], shape=(2,), dtype=int64))
एक विरल टेंसर की सामग्री को समझना आसान है यदि गैर-शून्य values
को उनके संबंधित indices
के साथ संरेखित किया जाता है। एक सहायक फ़ंक्शन को सुंदर-प्रिंट विरल टेंसर के लिए परिभाषित करें जैसे कि प्रत्येक गैर-शून्य मान अपनी लाइन पर दिखाया गया हो।
def pprint_sparse_tensor(st):
s = "<SparseTensor shape=%s \n values={" % (st.dense_shape.numpy().tolist(),)
for (index, value) in zip(st.indices, st.values):
s += f"\n %s: %s" % (index.numpy().tolist(), value.numpy().tolist())
return s + "}>"
print(pprint_sparse_tensor(st1))
<SparseTensor shape=[3, 10] values={ [0, 3]: 10 [2, 4]: 20}>
आप tf.sparse.from_dense का उपयोग करके घने टेंसर से विरल टेंसर भी बना सकते हैं, और tf.sparse.from_dense
का उपयोग करके उन्हें वापस घने टेंसर में tf.sparse.to_dense
हैं।
st2 = tf.sparse.from_dense([[1, 0, 0, 8], [0, 0, 0, 0], [0, 0, 3, 0]])
print(pprint_sparse_tensor(st2))
<SparseTensor shape=[3, 4] values={ [0, 0]: 1 [0, 3]: 8 [2, 2]: 3}>
st3 = tf.sparse.to_dense(st2)
print(st3)
tf.Tensor( [[1 0 0 8] [0 0 0 0] [0 0 3 0]], shape=(3, 4), dtype=int32)
विरल टेंसर में हेरफेर
विरल टेंसर में हेरफेर करने के लिए tf.sparse
पैकेज में उपयोगिताओं का उपयोग करें। tf.math.add
जैसे ऑप्स जिनका उपयोग आप घने टेंसर के अंकगणितीय हेरफेर के लिए कर सकते हैं, विरल टेंसर के साथ काम नहीं करते हैं।
tf.sparse.add
का उपयोग करके समान आकार के विरल टेंसर जोड़ें।
st_a = tf.SparseTensor(indices=[[0, 2], [3, 4]],
values=[31, 2],
dense_shape=[4, 10])
st_b = tf.SparseTensor(indices=[[0, 2], [7, 0]],
values=[56, 38],
dense_shape=[4, 10])
st_sum = tf.sparse.add(st_a, st_b)
print(pprint_sparse_tensor(st_sum))
<SparseTensor shape=[4, 10] values={ [0, 2]: 87 [3, 4]: 2 [7, 0]: 38}>
घने मैट्रिसेस के साथ विरल टेंसर को गुणा करने के लिए tf.sparse.sparse_dense_matmul
का उपयोग करें।
st_c = tf.SparseTensor(indices=([0, 1], [1, 0], [1, 1]),
values=[13, 15, 17],
dense_shape=(2,2))
mb = tf.constant([[4], [6]])
product = tf.sparse.sparse_dense_matmul(st_c, mb)
print(product)
tf.Tensor( [[ 78] [162]], shape=(2, 1), dtype=int32)
tf.sparse.concat का उपयोग करके विरल टेंसरों को एक साथ रखें और tf.sparse.concat
का उपयोग करके उन्हें अलग tf.sparse.slice
।
sparse_pattern_A = tf.SparseTensor(indices = [[2,4], [3,3], [3,4], [4,3], [4,4], [5,4]],
values = [1,1,1,1,1,1],
dense_shape = [8,5])
sparse_pattern_B = tf.SparseTensor(indices = [[0,2], [1,1], [1,3], [2,0], [2,4], [2,5], [3,5],
[4,5], [5,0], [5,4], [5,5], [6,1], [6,3], [7,2]],
values = [1,1,1,1,1,1,1,1,1,1,1,1,1,1],
dense_shape = [8,6])
sparse_pattern_C = tf.SparseTensor(indices = [[3,0], [4,0]],
values = [1,1],
dense_shape = [8,6])
sparse_patterns_list = [sparse_pattern_A, sparse_pattern_B, sparse_pattern_C]
sparse_pattern = tf.sparse.concat(axis=1, sp_inputs=sparse_patterns_list)
print(tf.sparse.to_dense(sparse_pattern))
tf.Tensor( [[0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0] [0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0] [0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0] [0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0] [0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0] [0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]], shape=(8, 17), dtype=int32)
sparse_slice_A = tf.sparse.slice(sparse_pattern_A, start = [0,0], size = [8,5])
sparse_slice_B = tf.sparse.slice(sparse_pattern_B, start = [0,5], size = [8,6])
sparse_slice_C = tf.sparse.slice(sparse_pattern_C, start = [0,10], size = [8,6])
print(tf.sparse.to_dense(sparse_slice_A))
print(tf.sparse.to_dense(sparse_slice_B))
print(tf.sparse.to_dense(sparse_slice_C))
tf.Tensor( [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 1] [0 0 0 1 1] [0 0 0 1 1] [0 0 0 0 1] [0 0 0 0 0] [0 0 0 0 0]], shape=(8, 5), dtype=int32) tf.Tensor( [[0] [0] [1] [1] [1] [1] [0] [0]], shape=(8, 1), dtype=int32) tf.Tensor([], shape=(8, 0), dtype=int32)
यदि आप TensorFlow 2.4 या इसके बाद के संस्करण का उपयोग कर रहे हैं, तो tf.sparse.map_values
का उपयोग विरल टेंसर में गैर-शून्य मानों पर तत्व-वार संचालन के लिए करें।
st2_plus_5 = tf.sparse.map_values(tf.add, st2, 5)
print(tf.sparse.to_dense(st2_plus_5))
tf.Tensor( [[ 6 0 0 13] [ 0 0 0 0] [ 0 0 8 0]], shape=(3, 4), dtype=int32)
ध्यान दें कि केवल गैर-शून्य मान संशोधित किए गए थे - शून्य मान शून्य रहते हैं।
समान रूप से, आप TensorFlow के पुराने संस्करणों के लिए नीचे दिए गए डिज़ाइन पैटर्न का अनुसरण कर सकते हैं:
st2_plus_5 = tf.SparseTensor(
st2.indices,
st2.values + 5,
st2.dense_shape)
print(tf.sparse.to_dense(st2_plus_5))
tf.Tensor( [[ 6 0 0 13] [ 0 0 0 0] [ 0 0 8 0]], shape=(3, 4), dtype=int32)
अन्य TensorFlow API के साथ tf.SparseTensor
का उपयोग करना
विरल टेंसर इन TensorFlow API के साथ पारदर्शी रूप से काम करते हैं:
-
tf.keras
-
tf.data
-
tf.Train.Example
-
tf.function
-
tf.while_loop
-
tf.cond
-
tf.identity
-
tf.cast
-
tf.print
-
tf.saved_model
-
tf.io.serialize_sparse
-
tf.io.serialize_many_sparse
-
tf.io.deserialize_many_sparse
-
tf.math.abs
-
tf.math.negative
-
tf.math.sign
-
tf.math.square
-
tf.math.sqrt
-
tf.math.erf
-
tf.math.tanh
-
tf.math.bessel_i0e
-
tf.math.bessel_i1e
उपरोक्त कुछ एपीआई के उदाहरण नीचे दिखाए गए हैं।
tf.keras
tf.keras
API का एक सबसेट महंगी कास्टिंग या रूपांतरण ऑप्स के बिना विरल टेंसर का समर्थन करता है। Keras API आपको Keras मॉडल के इनपुट के रूप में विरल टेंसर पास करने देता है। tf.keras.Input
या tf.keras.layers.InputLayer
को कॉल करते समय sparse sparse=True
सेट करें। आप केरस परतों के बीच विरल टेंसर पास कर सकते हैं, और केरस मॉडल भी उन्हें आउटपुट के रूप में वापस कर सकते हैं। यदि आप अपने मॉडल में tf.keras.layers.Dense
परतों में विरल टेंसर का उपयोग करते हैं, तो वे घने टेंसर का उत्पादन करेंगे।
नीचे दिया गया उदाहरण आपको दिखाता है कि केरस मॉडल के इनपुट के रूप में एक विरल टेंसर को कैसे पास किया जाए यदि आप केवल उन परतों का उपयोग करते हैं जो विरल इनपुट का समर्थन करती हैं।
x = tf.keras.Input(shape=(4,), sparse=True)
y = tf.keras.layers.Dense(4)(x)
model = tf.keras.Model(x, y)
sparse_data = tf.SparseTensor(
indices = [(0,0),(0,1),(0,2),
(4,3),(5,0),(5,1)],
values = [1,1,1,1,1,1],
dense_shape = (6,4)
)
model(sparse_data)
model.predict(sparse_data)
array([[-1.3111044 , -1.7598825 , 0.07225233, -0.44544357], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. ], [ 0.8517609 , -0.16835624, 0.7307872 , -0.14531797], [-0.8916302 , -0.9417639 , 0.24563438, -0.9029659 ]], dtype=float32)
tf.data
tf.data
API आपको सरल, पुन: प्रयोज्य टुकड़ों से जटिल इनपुट पाइपलाइन बनाने में सक्षम बनाता है। इसकी मूल डेटा संरचना tf.data.Dataset
है, जो तत्वों के अनुक्रम का प्रतिनिधित्व करती है जिसमें प्रत्येक तत्व में एक या अधिक घटक होते हैं।
विरल टेंसर के साथ डेटासेट बनाना
tf.Tensor
s या NumPy सरणियों, जैसे tf.data.Dataset.from_tensor_slices
से उन्हें बनाने के लिए उपयोग की जाने वाली समान विधियों का उपयोग करके विरल टेंसर से डेटासेट बनाएं। यह ऑप डेटा की विरलता (या विरल प्रकृति) को सुरक्षित रखता है।
dataset = tf.data.Dataset.from_tensor_slices(sparse_data)
for element in dataset:
print(pprint_sparse_tensor(element))
<SparseTensor shape=[4] values={ [0]: 1 [1]: 1 [2]: 1}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={ [3]: 1}> <SparseTensor shape=[4] values={ [0]: 1 [1]: 1}>
विरल टेंसर के साथ बैचिंग और अनबैचिंग डेटासेट
आप क्रमशः Dataset.batch
और Dataset.unbatch
विधियों का उपयोग करके बैच (लगातार तत्वों को एक तत्व में संयोजित) कर सकते हैं और विरल टेंसर के साथ डेटासेट को अनबैच कर सकते हैं।
batched_dataset = dataset.batch(2)
for element in batched_dataset:
print (pprint_sparse_tensor(element))
<SparseTensor shape=[2, 4] values={ [0, 0]: 1 [0, 1]: 1 [0, 2]: 1}> <SparseTensor shape=[2, 4] values={}> <SparseTensor shape=[2, 4] values={ [0, 3]: 1 [1, 0]: 1 [1, 1]: 1}>
unbatched_dataset = batched_dataset.unbatch()
for element in unbatched_dataset:
print (pprint_sparse_tensor(element))
<SparseTensor shape=[4] values={ [0]: 1 [1]: 1 [2]: 1}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={ [3]: 1}> <SparseTensor shape=[4] values={ [0]: 1 [1]: 1}>
आप tf.data.experimental.dense_to_sparse_batch
का उपयोग अलग-अलग आकार के डेटासेट तत्वों को विरल टेंसर में बैचने के लिए भी कर सकते हैं।
विरल टेंसर के साथ डेटासेट बदलना
Dataset.map
का उपयोग करके डेटासेट में विरल टेंसर को ट्रांसफ़ॉर्म और बनाएं।
transform_dataset = dataset.map(lambda x: x*2)
for i in transform_dataset:
print(pprint_sparse_tensor(i))
<SparseTensor shape=[4] values={ [0]: 2 [1]: 2 [2]: 2}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={}> <SparseTensor shape=[4] values={ [3]: 2}> <SparseTensor shape=[4] values={ [0]: 2 [1]: 2}>प्लेसहोल्डर33
tf.ट्रेन।उदाहरण
tf.train.Example
TensorFlow डेटा के लिए एक मानक प्रोटोबफ़ एन्कोडिंग है। tf.train.Example
के साथ विरल टेंसर का उपयोग करते समय, आप यह कर सकते हैं:
चर-लंबाई वाले डेटा को
tf.SparseTensor
का उपयोग करकेtf.io.VarLenFeature
में पढ़ें। हालांकि, आपको इसके बजायtf.io.RaggedFeature
का उपयोग करने पर विचार करना चाहिए।tf.io.SparseFeature
tf.SparseTensor
मनमाने ढंग से विरल डेटा पढ़ें, जोindices
,values
औरdense_shape
को संग्रहीत करने के लिए तीन अलग-अलग सुविधा कुंजियों का उपयोग करता है।
tf.function
tf.function
डेकोरेटर पायथन फ़ंक्शन के लिए TensorFlow ग्राफ़ की पूर्व-गणना करता है, जो आपके TensorFlow कोड के प्रदर्शन में काफी सुधार कर सकता है। विरल टेंसर tf.function
और ठोस दोनों कार्यों के साथ पारदर्शी रूप से काम करते हैं।
@tf.function
def f(x,y):
return tf.sparse.sparse_dense_matmul(x,y)
a = tf.SparseTensor(indices=[[0, 3], [2, 4]],
values=[15, 25],
dense_shape=[3, 10])
b = tf.sparse.to_dense(tf.sparse.transpose(a))
c = f(a,b)
print(c)
34 एल10एन-प्लेसहोल्डरtf.Tensor( [[225 0 0] [ 0 0 0] [ 0 0 625]], shape=(3, 3), dtype=int32)
लापता मानों को शून्य मानों से अलग करना
tf.SparseTensor
के अधिकांश ऑप्स लापता मानों और स्पष्ट शून्य मानों को समान मानते हैं। यह डिज़ाइन द्वारा है - एक tf.SparseTensor
को घने टेंसर की तरह ही कार्य करना चाहिए।
हालांकि, ऐसे कुछ मामले हैं जहां शून्य मानों को लापता मानों से अलग करना उपयोगी हो सकता है। विशेष रूप से, यह आपके प्रशिक्षण डेटा में गुम/अज्ञात डेटा को एन्कोड करने का एक तरीका देता है। उदाहरण के लिए, एक उपयोग के मामले पर विचार करें जहां आपके पास स्कोर का एक टेंसर है (जिसमें -Inf से +Inf तक कोई भी फ्लोटिंग पॉइंट मान हो सकता है), कुछ लापता स्कोर के साथ। आप इस टेंसर को एक विरल टेंसर का उपयोग करके एन्कोड कर सकते हैं जहां स्पष्ट शून्य शून्य स्कोर के रूप में जाना जाता है लेकिन निहित शून्य मान वास्तव में लापता डेटा का प्रतिनिधित्व करते हैं और शून्य नहीं।
ध्यान दें कि कुछ ऑप्स जैसे tf.sparse.reduce_max
लापता मानों को शून्य मानो नहीं मानते हैं। उदाहरण के लिए, जब आप नीचे कोड ब्लॉक चलाते हैं, तो अपेक्षित आउटपुट 0
होता है। हालाँकि, इस अपवाद के कारण, आउटपुट -3
है।
print(tf.sparse.reduce_max(tf.sparse.from_dense([-5, 0, -3])))
tf.Tensor(-3, shape=(), dtype=int32)
इसके विपरीत, जब आप tf.math.reduce_max
को सघन टेंसर पर लागू करते हैं, तो आउटपुट अपेक्षा के अनुरूप 0 होता है।
print(tf.math.reduce_max([-5, 0, -3]))
tf.Tensor(0, shape=(), dtype=int32)
आगे पढ़ने और संसाधन
- टेंसर के बारे में जानने के लिए टेंसर गाइड देखें।
- रैग्ड टेंसर के साथ काम करने का तरीका जानने के लिए रैग्ड टेंसर गाइड पढ़ें, एक प्रकार का टेंसर जो आपको गैर-समान डेटा के साथ काम करने देता है।
- TensorFlow मॉडल गार्डन में इस ऑब्जेक्ट डिटेक्शन मॉडल को देखें जो
tf.Example
डेटा डिकोडर में विरल टेंसर का उपयोग करता है।