मशीन लर्निंग का परिचय - टेंसरफ्लो | मूल, AI द्वारा अनुवादित

Home 2021.03

यह पोस्ट मूल रूप से चाइनीज़ में लिखी गई थी। इसे अन्य भाषाओं में अनुवाद की सुविधा के लिए अंग्रेज़ी में अनुवादित किया गया है।


चूंकि हम Python सीख रहे हैं, इसलिए हमें मशीन लर्निंग के बारे में ज़रूर बात करनी चाहिए। इसकी कई लाइब्रेरियाँ Python में लिखी गई हैं। आइए इन्हें इंस्टॉल करके और ट्राई करके शुरू करें।

TensorFlow

आइए इसे इंस्टॉल करें।

$ pip install tensorflow
ERROR: Could not find a version that satisfies the requirement tensorflow
ERROR: No matching distribution found for tensorflow
$ type python
python is aliased to `/usr/local/Cellar/python@3.9/3.9.1_6/bin/python3'

हालांकि, TensorFlow 2 केवल Python 3.5–3.8 को सपोर्ट करता है। हम 3.9 का उपयोग कर रहे हैं।

% type python3
python3 is /usr/bin/python3
% python3 -V
Python 3.8.2

ध्यान दें कि मेरे सिस्टम पर python3 का वर्जन 3.8.2 है। इस Python वर्जन के लिए संगत pip कहां पैकेज इंस्टॉल करता है?

% python3 -m pip -V
pip 21.0.1 from /Users/lzw/Library/Python/3.8/lib/python/site-packages/pip (python 3.8)

संगत pip यहाँ है। तो, मैं .zprofile फाइल को संशोधित करूंगा। हाल ही में, मैंने अपना shell बदल दिया है, और .zprofile पहले के .bash_profile के समान है। एक लाइन जोड़ें:

alias pip3=/Users/lzw/Library/Python/3.8/bin/pip3

इस तरह, हम python3 और pip3 का उपयोग TensorFlow के साथ कर सकते हैं।

% pip3 install tensorflow
...
Successfully installed absl-py-0.12.0 astunparse-1.6.3 cachetools-4.2.1 certifi-2020.12.5 chardet-4.0.0 flatbuffers-1.12 gast-0.3.3 google-auth-1.27.1 google-auth-oauthlib-0.4.3 google-pasta-0.2.0 grpcio-1.32.0 h5py-2.10.0 idna-2.10 keras-preprocessing-1.1.2 markdown-3.3.4 numpy-1.19.5 oauthlib-3.1.0 opt-einsum-3.3.0 protobuf-3.15.6 pyasn1-0.4.8 pyasn1-modules-0.2.8 requests-2.25.1 requests-oauthlib-1.3.0 rsa-4.7.2 tensorboard-2.4.1 tensorboard-plugin-wit-1.8.0 tensorflow-2.4.1 tensorflow-estimator-2.4.0 termcolor-1.1.0 typing-extensions-3.7.4.3 urllib3-1.26.3 werkzeug-1.0.1 wheel-0.36.2 wrapt-1.12.1

कई लाइब्रेरियाँ इंस्टॉल हुई हैं। आइए आधिकारिक वेबसाइट से एक उदाहरण का उपयोग करें।

import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10)
])

predictions = model(x_train[:1]).numpy()
print(predictions)

आइए इसे चलाएं।

$ /usr/bin/python3 tf.py
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 10s 1us/step
[[ 0.15477428 -0.3877643   0.0994779   0.07474922 -0.26219758 -0.03550266
   0.32226565 -0.37141111  0.10925996 -0.0115255 ]]

जैसा कि आप देख सकते हैं, डेटासेट डाउनलोड हो गया, और परिणाम आउटपुट हुए।

अगला, आइए एक इमेज क्लासिफिकेशन उदाहरण देखें।

# TensorFlow और tf.keras
import tensorflow as tf

# सहायक लाइब्रेरियाँ
import numpy as np
import matplotlib.pyplot as plt

print(tf.__version__)

एक त्रुटि हुई।

ModuleNotFoundError: No module named 'matplotlib'

आइए इसे इंस्टॉल करें।

% pip3 install matplotlib

अब यह सही है।

$ /usr/bin/python3 image.py
2.4.1

आइए उदाहरण कोड को कॉपी और पेस्ट करें।

# TensorFlow और tf.keras
import tensorflow as tf

# सहायक लाइब्रेरियाँ
import numpy as np
import matplotlib.pyplot as plt

fashion_mnist = tf.keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
print(train_images.shape)
print(len(train_labels))

परिणाम आउटपुट हुए। ध्यान दें कि हमारे पास train_images, train_labels, test_images, और test_labels हैं। ये ट्रेनिंग और टेस्ट डेटासेट में विभाजित हैं।

(60000, 28, 28)
60000

अगला, आइए एक इमेज डिस्प्ले करने का प्रयास करें।

print(train_images[0])

आइए परिणाम देखें।

[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   1   0   0  13  73   0
    0   1   4   0   0   0   0   1   1   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   3   0  36 136 127  62
   54   0   0   0   1   3   4   0   0   3]
 [  0   0   0   0   0   0   0   0   0   0   0   0   6   0 102 204 176 134
  144 123  23   0   0   0   0  12  10   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0 155 236 207 178
  107 156 161 109  64  23  77 130  72  15]
  ....

यहां, परिणाम का एक भाग दिया गया है।

print(len(train_images[0][0]))

आउटपुट 28 है। तो, यह स्पष्ट है कि यह एक 28 की चौड़ाई वाली मैट्रिक्स है। आइए प्रिंट करना जारी रखें।

print(len(train_images[0][0][0]))
TypeError: object of type 'numpy.uint8' has no len()

तो, यह स्पष्ट है। प्रत्येक इमेज एक 28*28*3 एरे है। आखिरी आयाम RGB वैल्यूज़ स्टोर करता है। हालांकि, हम इसमें गलत हो सकते हैं।

print(train_images[0][1][20])
0
print(train_images[0][1])
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

यह दिखाता है कि प्रत्येक इमेज एक 28*28 एरे है। कुछ प्रयासों के बाद, हम अंततः रहस्य को समझ गए।

आइए पहले आउटपुट इमेज देखें।

plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()

tf

क्या आप दाईं ओर कलर बार देखते हैं? 0 से 250 तक। पता चलता है कि यह दो रंगों के बीच एक ग्रेडिएंट है। लेकिन यह कैसे जानता है कि कौन से दो रंग? हमने यह कहां निर्दिष्ट किया?

अगला, आइए दूसरी इमेज भी प्रिंट करें।

plt.imshow(train_images[1])

plt

बहुत दिलचस्प। क्या यह pyplot लाइब्रेरी का डिफ़ॉल्ट है? आइए आधिकारिक वेबसाइट द्वारा प्रदान किए गए कोड को चलाना जारी रखें।

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

tf2

ध्यान दें कि यहां इमेज और उनके क्लासिफिकेशन दिखाए गए हैं। अंततः हम cmap पैरामीटर को समझते हैं। यदि cmap निर्दिष्ट नहीं किया गया है, तो यह पहले देखे गए रंग योजना पर डिफ़ॉल्ट होगा। वास्तव में।

plt.imshow(train_images[i])

cmap

इस बार, हम pyplot cmap खोजते हैं और कुछ संसाधन पाते हैं।

plt.imshow(train_images[i], cmap=plt.cm.PiYG)

cmap1

आइए कोड को संशोधित करें।

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(2,5,i+1)   ## इस लाइन को संशोधित किया
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.Blues)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

हालांकि, एक त्रुटि हुई।

ValueError: num must be 1 <= num <= 10, not 11

इसका क्या अर्थ है? पिछले 5,5,i+1 का वास्तव में क्या अर्थ है? जब इसे 2 में बदल दिया जाता है तो यह क्यों काम नहीं करता? हालांकि हम अनुभव से समझते हैं कि इसका अर्थ 5 पंक्तियाँ और 5 कॉलम हो सकते हैं, लेकिन यह त्रुटि क्यों होती है? 11 की गणना कैसे की जाती है? num का क्या अर्थ है? 10 का क्या अर्थ है? ध्यान दें कि 2*5=10। इसलिए, हो सकता है कि जब i=11 हो तो त्रुटि हो। जब इसे for i in range(10): में बदल दिया जाता है, तो हमें निम्न परिणाम मिलता है।

plot3

इस बार, संक्षेप में दस्तावेज़ीकरण को देखने के बाद, हम subplot(nrows, ncols, index, **kwargs) के बारे में जानते हैं। ठीक है, अब हम समझ गए।

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    # plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.Blues)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

plot_xticks

ध्यान दें कि 0 25 जैसी चीजों को xticks कहा जाता है। जब हम इस फ्रेम को ज़ूम इन या आउट करते हैं, तो डिस्प्ले बदल जाता है।

plot_scale

ध्यान दें कि ज़ूम इन या आउट करने पर, xticks और xlabels अलग-अलग दिखते हैं।

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10)
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=10)

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)

ध्यान दें कि यहाँ मॉडल को Sequential क्लास का उपयोग करके परिभाषित किया गया है। इन पैरामीटर पर ध्यान दें: 28,28, 128, relu, 10। ध्यान दें कि आपको compile और fit करने की आवश्यकता है। fit का अर्थ फिटिंग है। ध्यान दें कि 28,28 इमेज के साइज़ से मेल खाता है।

Epoch 1/10
1875/1875 [==============================] - 2s 928us/step - loss: 0.6331 - accuracy: 0.7769
Epoch 2/10
1875/1875 [==============================] - 2s 961us/step - loss: 0.3860 - accuracy: 0.8615
Epoch 3/10
1875/1875 [==============================] - 2s 930us/step - loss: 0.3395 - accuracy: 0.8755
Epoch 4/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.3071 - accuracy: 0.8890
Epoch 5/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2964 - accuracy: 0.8927
Epoch 6/10
1875/1875 [==============================] - 2s 985us/step - loss: 0.2764 - accuracy: 0.8955
Epoch 7/10
1875/1875 [==============================] - 2s 961us/step - loss: 0.2653 - accuracy: 0.8996
Epoch 8/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2549 - accuracy: 0.9052
Epoch 9/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2416 - accuracy: 0.9090
Epoch 10/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2372 - accuracy: 0.9086
313/313 - 0s - loss: 0.3422 - accuracy: 0.8798

Test accuracy: 0.879800021648407

मॉडल को ट्रेन किया गया है। आइए पैरामीटर को संशोधित करें।

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(28, activation='relu'),    # 128 -> 28
    tf.keras.layers.Dense(10)
])

Dense के पहले पैरामीटर को संशोधित करें।

Epoch 1/10
1875/1875 [==============================] - 2s 714us/step - loss: 6.9774 - accuracy: 0.3294
Epoch 2/10
1875/1875 [==============================] - 1s 715us/step - loss: 1.3038 - accuracy: 0.4831
Epoch 3/10
1875/1875 [==============================] - 1s 747us/step - loss: 1.0160 - accuracy: 0.6197
Epoch 4/10
1875/1875 [==============================] - 1s 800us/step - loss: 0.7963 - accuracy: 0.6939
Epoch 5/10
1875/1875 [==============================] - 2s 893us/step - loss: 0.7006 - accuracy: 0.7183
Epoch 6/10
1875/1875 [==============================] - 1s 747us/step - loss: 0.6675 - accuracy: 0.7299
Epoch 7/10
1875/1875 [==============================] - 1s 694us/step - loss: 0.6681 - accuracy: 0.7330
Epoch 8/10
1875/1875 [==============================] - 1s 702us/step - loss: 0.6675 - accuracy: 0.7356
Epoch 9/10
1875/1875 [==============================] - 1s 778us/step - loss: 0.6508 - accuracy: 0.7363
Epoch 10/10
1875/1875 [==============================] - 1s 732us/step - loss: 0.6532 - accuracy: 0.7350
313/313 - 0s - loss: 0.6816 - accuracy: 0.7230

Test accuracy: 0.7229999899864197

ध्यान दें कि Test accuracy में परिवर्तन। Epoch लॉग fit फंक्शन द्वारा आउटपुट किए जाते हैं। ध्यान दें कि 128 के साथ, accuracy 0.7769 से 0.9086 तक जाता है। 28 के साथ, accuracy 0.3294 से 0.7350 तक जाता है। इस बार, हम देखते हैं कि हम पहले ट्रेनिंग सेट का उपयोग loss और accuracy को ऑप्टिमाइज़ करने के लिए करते हैं, फिर टेस्ट डेटासेट का उपयोग मूल्यांकन के लिए करते हैं। आइए train_labels देखें।

print(train_labels)
[9 0 0 ... 3 0 5]
print(len(train_labels))
60000

इसका अर्थ है कि 0 से 9 तक की संख्याएं इन श्रेणियों का प्रतिनिधित्व करती हैं। संयोग से, class_names में भी 10 आइटम हैं।

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

आइए एक और परिवर्तन करें।

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(28, activation='relu'),
    tf.keras.layers.Dense(5)   # 10 -> 5
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=10)

एक त्रुटि हुई।

tensorflow.python.framework.errors_impl.InvalidArgumentError:  Received a label value of 9 which is outside the valid range of [0, 5).  Label values: 4 3 2 9 4 1 6 0 7 9 1 6 5 2 3 8 6 3 8 0 3 5 6 1 2 6 3 6 8 4 8 4
         [[node sparse_categorical_crossentropy/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits (defined at /curiosity-courses/ml/tf/image.py:53) ]] [Op:__inference_train_function_538]

Function call stack:
train_function

Sequential के तीसरे पैरामीटर, Dense, को 15 में बदलना समस्या को हल करता है। परिणाम बहुत अलग नहीं हैं। आइए Epoch बदलने का प्रयास करें।

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(28, activation='relu'),
    tf.keras.layers.Dense(15)
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=15)  # 10 -> 15

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)
Epoch 1/15
1875/1875 [==============================] - 2s 892us/step - loss: 6.5778 - accuracy: 0.3771
Epoch 2/15
1875/1875 [==============================] - 2s 872us/step - loss: 1.3121 - accuracy: 0.4910
Epoch 3/15
1875/1875 [==============================] - 2s 909us/step - loss: 1.0900 - accuracy: 0.5389
Epoch 4/15
1875/1875 [==============================] - 1s 730us/step - loss: 1.0422 - accuracy: 0.5577
Epoch 5/15
1875/1875 [==============================] - 1s 709us/step - loss: 0.9529 - accuracy: 0.5952
Epoch 6/15
1875/1875 [==============================] - 1s 714us/step - loss: 0.9888 - accuracy: 0.5950
Epoch 7/15
1875/1875 [==============================] - 1s 767us/step - loss: 0.8678 - accuracy: 0.6355
Epoch 8/15
1875/1875 [==============================] - 1s 715us/step - loss: 0.8247 - accuracy: 0.6611
Epoch 9/15
1875/1875 [==============================] - 1s 721us/step - loss: 0.8011 - accuracy: 0.6626
Epoch 10/15
1875/1875 [==============================] - 1s 711us/step - loss: 0.8024 - accuracy: 0.6622
Epoch 11/15
1875/1875 [==============================] - 1s 781us/step - loss: 0.7777 - accuracy: 0.6696
Epoch 12/15
1875/1875 [==============================] - 1s 724us/step - loss: 0.7764 - accuracy: 0.6728
Epoch 13/15
1875/1875 [==============================] - 1s 731us/step - loss: 0.7688 - accuracy: 0.6767
Epoch 14/15
1875/1875 [==============================] - 1s 715us/step - loss: 0.7592 - accuracy: 0.6793
Epoch 15/15
1875/1875 [==============================] - 1s 786us/step - loss: 0.7526 - accuracy: 0.6792
313/313 - 0s - loss: 0.8555 - accuracy: 0.6418

Test accuracy: 0.6417999863624573

ध्यान दें कि इसे 15 में बदलने से बहुत ज्यादा अंतर नहीं पड़ता। tf.keras.layers.Dense(88, activation='relu') महत्वपूर्ण है। 128 को 88 में बदलने पर Test accuracy: 0.824999988079071 मिलता है। 128 के साथ यह 0.879800021648407 था। 28 के साथ यह 0.7229999899864197 था। क्या बड़ा मान बेहतर परिणाम देता है? हालांकि, जब इसे 256 में बदल दिया गया, तो यह Test accuracy: 0.8409000039100647 था। इससे हमें loss और accuracy के अर्थ पर विचार करना पड़ता है।

probability_model = tf.keras.Sequential([model,
                                         tf.keras.layers.Softmax()])

अगला, आइए एक भविष्यवाणी करें। ध्यान दें कि Sequential ऊपर के समान है। model और tf.keras.layers.Softmax() पैरामीटर पर ध्यान दें।

probability_model = tf.keras.Sequential([model,
                                         tf.keras.layers.Softmax()])
predictions = probability_model.predict(test_images)

def plot_image(i, predictions_array, true_label, img):
  true_label, img = true_label[i], img[i]
  plt.grid(False)
  plt.xticks([])
  plt.yticks([])

  plt.imshow(img, cmap=plt.cm.binary)

  predicted_label = np.argmax(predictions_array)
  if predicted_label == true_label:
    color = 'blue'
  else:
    color = 'red'

  plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                100*np.max(predictions_array),
                                class_names[true_label]),
                                color=color)

def plot_value_array(i, predictions_array, true_label):
  true_label = true_label[i]
  plt.grid(False)
  plt.xticks(range(10))
  plt.yticks([])
  thisplot = plt.bar(range(10), predictions_array, color="#777777")
  plt.ylim([0, 1])
  predicted_label = np.argmax(predictions_array)

  thisplot[predicted_label].set_color('red')
  thisplot[true_label].set_color('blue')

i = 0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i],  test_labels)
plt.show()

pred

यह दर्शाता है कि इस इमेज के Ankle boot होने की 99% संभावना है। ध्यान दें कि plot_image बाएं चार्ट को प्रदर्शित करता है, और plot_value_array दाएं चार्ट को आउटपुट करता है।

num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions[i], test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()

pred1

ध्यान दें कि यह सिर्फ अधिक टेस्ट परिणाम प्रदर्शित करता है। तो, हम उपयोग के प्रवाह को लगभग समझते हैं। हम अभी भी नहीं जानते कि पर्दे के पीछे की गणनाएँ कैसे काम करती हैं, लेकिन हम जानते हैं कि उनका उपयोग कैसे करना है। इसके पीछे कैलकुलस है। हम कैलकुलस को कैसे समझते हैं?

उदाहरण के लिए, 1 से 100 के बीच एक संख्या है जिसे आपको अनुमान लगाना है। हर बार जब आप अनुमान लगाते हैं, तो मैं आपको बताता हूं कि यह बहुत कम है या बहुत अधिक। आप 50 का अनुमान लगाते हैं। मैं कहता हूं बहुत कम। आप 80 का अनुमान लगाते हैं। मैं कहता हूं बहुत अधिक। आप 65 का अनुमान लगाते हैं। मैं कहता हूं बहुत अधिक। आप 55 का अनुमान लगाते हैं। मैं कहता हूं बहुत कम। आप 58 का अनुमान लगाते हैं। मैं कहता हूं, हां, आपने इसे पकड़ लिया।

मशीन लर्निंग पर्दे के पीछे इसी तरह की प्रक्रिया का अनुकरण करती है, बस अधिक जटिल। इसमें कई रेंज जैसे 1 से 100 शामिल हो सकते हैं, एक साथ कई संख्याओं का अनुमान लगाना। प्रत्येक अनुमान में बहुत सारी गणनाएँ शामिल होती हैं, और यह निर्धारित करना कि यह बहुत अधिक है या बहुत कम है, इसके लिए भी कई गणनाओं की आवश्यकता होती है।


Back Donate