TensorFlow.org पर देखें | Google Colab में चलाएं | GitHub पर स्रोत देखें | नोटबुक डाउनलोड करें |
पिछले गाइड में, आपने टेंसर , वेरिएबल , ग्रेडिएंट टेप और मॉड्यूल के बारे में सीखा। इस गाइड में, आप मॉडलों को प्रशिक्षित करने के लिए इन सभी को एक साथ फिट करेंगे।
TensorFlow में tf.Keras API भी शामिल है, जो एक उच्च-स्तरीय तंत्रिका नेटवर्क API है जो बॉयलरप्लेट को कम करने के लिए उपयोगी अमूर्तता प्रदान करता है। हालांकि, इस गाइड में, आप बुनियादी कक्षाओं का उपयोग करेंगे।
सेट अप
import tensorflow as tf
import matplotlib.pyplot as plt
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
मशीन सीखने की समस्याओं का समाधान
मशीन सीखने की समस्या को हल करने में आमतौर पर निम्नलिखित चरण होते हैं:
- प्रशिक्षण डेटा प्राप्त करें।
- मॉडल को परिभाषित करें।
- हानि फ़ंक्शन को परिभाषित करें।
- आदर्श मूल्य से नुकसान की गणना करते हुए, प्रशिक्षण डेटा के माध्यम से चलाएँ
- उस नुकसान के लिए ग्रेडिएंट की गणना करें और डेटा को फिट करने के लिए चर को समायोजित करने के लिए एक अनुकूलक का उपयोग करें।
- अपने परिणामों का मूल्यांकन करें।
उदाहरण के लिए, इस गाइड में आप एक साधारण रैखिक मॉडल विकसित करेंगे, \(f(x) = x * W + b\), जिसमें दो चर हैं: \(W\) (भार) और \(b\) 3 (पूर्वाग्रह)।
यह मशीन सीखने की सबसे बुनियादी समस्या है: \(x\) और \(y\)को देखते हुए, सरल रेखीय प्रतिगमन के माध्यम से एक रेखा के ढलान और ऑफसेट को खोजने का प्रयास करें।
आंकड़े
पर्यवेक्षित शिक्षण इनपुट (आमतौर पर x के रूप में निरूपित) और आउटपुट (निरूपित y , जिसे अक्सर लेबल कहा जाता है) का उपयोग करता है। लक्ष्य युग्मित इनपुट और आउटपुट से सीखना है ताकि आप इनपुट से आउटपुट के मूल्य की भविष्यवाणी कर सकें।
आपके डेटा का प्रत्येक इनपुट, TensorFlow में, लगभग हमेशा एक टेंसर द्वारा दर्शाया जाता है, और अक्सर एक वेक्टर होता है। पर्यवेक्षित प्रशिक्षण में, आउटपुट (या मूल्य जिसका आप अनुमान लगाना चाहते हैं) भी एक टेंसर है।
यहाँ कुछ डेटा को एक रेखा के साथ बिंदुओं पर गाऊसी (सामान्य) शोर जोड़कर संश्लेषित किया गया है।
# The actual line
TRUE_W = 3.0
TRUE_B = 2.0
NUM_EXAMPLES = 201
# A vector of random x values
x = tf.linspace(-2,2, NUM_EXAMPLES)
x = tf.cast(x, tf.float32)
def f(x):
return x * TRUE_W + TRUE_B
# Generate some noise
noise = tf.random.normal(shape=[NUM_EXAMPLES])
# Calculate y
y = f(x) + noise
# Plot all the data
plt.plot(x, y, '.')
plt.show()
टेंसर को आमतौर पर बैचों में एक साथ इकट्ठा किया जाता है, या इनपुट और आउटपुट के समूह को एक साथ रखा जाता है। बैचिंग कुछ प्रशिक्षण लाभ प्रदान कर सकता है और त्वरक और वेक्टरकृत गणना के साथ अच्छी तरह से काम करता है। यह डेटासेट कितना छोटा है, इसे देखते हुए आप पूरे डेटासेट को एक बैच के रूप में मान सकते हैं।
मॉडल को परिभाषित करें
एक मॉडल में सभी भारों का प्रतिनिधित्व करने के लिए tf.Variable
का उपयोग करें। एक tf.Variable
एक मान संग्रहीत करता है और इसे आवश्यकतानुसार टेंसर रूप में प्रदान करता है। अधिक विवरण के लिए परिवर्तनीय मार्गदर्शिका देखें।
चर और गणना को समाहित करने के लिए tf.Module
का उपयोग करें। आप किसी भी पायथन ऑब्जेक्ट का उपयोग कर सकते हैं, लेकिन इस तरह इसे आसानी से सहेजा जा सकता है।
यहां, आप w और b दोनों को चर के रूप में परिभाषित करते हैं।
class MyModel(tf.Module):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Initialize the weights to `5.0` and the bias to `0.0`
# In practice, these should be randomly initialized
self.w = tf.Variable(5.0)
self.b = tf.Variable(0.0)
def __call__(self, x):
return self.w * x + self.b
model = MyModel()
# List the variables tf.modules's built-in variable aggregation.
print("Variables:", model.variables)
# Verify the model works
assert model(3.0).numpy() == 15.0
Variables: (<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=5.0>) 2021-12-08 17:11:44.542944: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
आरंभिक चर यहां एक निश्चित तरीके से सेट किए गए हैं, लेकिन केरस किसी भी इनिटलाइज़र के साथ आता है जिसका आप उपयोग कर सकते हैं, बाकी केरस के साथ या उसके बिना।
हानि फ़ंक्शन को परिभाषित करें
एक हानि फ़ंक्शन मापता है कि किसी दिए गए इनपुट के लिए मॉडल का आउटपुट लक्ष्य आउटपुट से कितनी अच्छी तरह मेल खाता है। लक्ष्य प्रशिक्षण के दौरान इस अंतर को कम करना है। मानक L2 हानि को परिभाषित करें, जिसे "माध्य चुकता" त्रुटि के रूप में भी जाना जाता है:
# This computes a single loss value for an entire batch
def loss(target_y, predicted_y):
return tf.reduce_mean(tf.square(target_y - predicted_y))
मॉडल को प्रशिक्षित करने से पहले, आप मॉडल की भविष्यवाणियों को लाल रंग में और प्रशिक्षण डेटा को नीले रंग में प्लॉट करके नुकसान के मूल्य की कल्पना कर सकते हैं:
plt.plot(x, y, '.', label="Data")
plt.plot(x, f(x), label="Ground truth")
plt.plot(x, model(x), label="Predictions")
plt.legend()
plt.show()
print("Current loss: %1.6f" % loss(y, model(x)).numpy())
Current loss: 10.301712
एक प्रशिक्षण लूप को परिभाषित करें
प्रशिक्षण लूप में क्रम में बार-बार तीन कार्य करना होता है:
- आउटपुट उत्पन्न करने के लिए मॉडल के माध्यम से इनपुट का एक बैच भेजना
- आउटपुट को आउटपुट (या लेबल) से तुलना करके नुकसान की गणना करना
- ग्रेडिएंट खोजने के लिए ग्रेडिएंट टेप का उपयोग करना
- उन ग्रेडिएंट्स के साथ वेरिएबल को ऑप्टिमाइज़ करना
इस उदाहरण के लिए, आप ग्रेडिएंट डिसेंट का उपयोग करके मॉडल को प्रशिक्षित कर सकते हैं।
ग्रेडिएंट डिसेंट स्कीम के कई रूप हैं जो tf.keras.optimizers
में कैप्चर किए गए हैं। लेकिन पहले सिद्धांतों से निर्माण की भावना में, यहां आप मूल गणित को tf.GradientTape
की मदद से स्वचालित भेदभाव और tf.assign_sub
की मदद से मूल्य को कम करने के लिए लागू करेंगे (जो tf.assign
और tf.sub
को जोड़ती है):
# Given a callable model, inputs, outputs, and a learning rate...
def train(model, x, y, learning_rate):
with tf.GradientTape() as t:
# Trainable variables are automatically tracked by GradientTape
current_loss = loss(y, model(x))
# Use GradientTape to calculate the gradients with respect to W and b
dw, db = t.gradient(current_loss, [model.w, model.b])
# Subtract the gradient scaled by the learning rate
model.w.assign_sub(learning_rate * dw)
model.b.assign_sub(learning_rate * db)
प्रशिक्षण पर एक नज़र के लिए, आप प्रशिक्षण लूप के माध्यम से x और y का एक ही बैच भेज सकते हैं, और देख सकते हैं कि W
और b
कैसे विकसित होते हैं।
model = MyModel()
# Collect the history of W-values and b-values to plot later
weights = []
biases = []
epochs = range(10)
# Define a training loop
def report(model, loss):
return f"W = {model.w.numpy():1.2f}, b = {model.b.numpy():1.2f}, loss={current_loss:2.5f}"
def training_loop(model, x, y):
for epoch in epochs:
# Update the model with the single giant batch
train(model, x, y, learning_rate=0.1)
# Track this before I update
weights.append(model.w.numpy())
biases.append(model.b.numpy())
current_loss = loss(y, model(x))
print(f"Epoch {epoch:2d}:")
print(" ", report(model, current_loss))
ट्रेनिंग करें
current_loss = loss(y, model(x))
print(f"Starting:")
print(" ", report(model, current_loss))
training_loop(model, x, y)
Starting: W = 5.00, b = 0.00, loss=10.30171 Epoch 0: W = 4.46, b = 0.40, loss=10.30171 Epoch 1: W = 4.06, b = 0.72, loss=10.30171 Epoch 2: W = 3.77, b = 0.97, loss=10.30171 Epoch 3: W = 3.56, b = 1.18, loss=10.30171 Epoch 4: W = 3.40, b = 1.34, loss=10.30171 Epoch 5: W = 3.29, b = 1.47, loss=10.30171 Epoch 6: W = 3.21, b = 1.58, loss=10.30171 Epoch 7: W = 3.15, b = 1.66, loss=10.30171 Epoch 8: W = 3.10, b = 1.73, loss=10.30171 Epoch 9: W = 3.07, b = 1.78, loss=10.30171प्लेसहोल्डर17
समय के साथ वजन के विकास को प्लॉट करें:
plt.plot(epochs, weights, label='Weights', color=colors[0])
plt.plot(epochs, [TRUE_W] * len(epochs), '--',
label = "True weight", color=colors[0])
plt.plot(epochs, biases, label='bias', color=colors[1])
plt.plot(epochs, [TRUE_B] * len(epochs), "--",
label="True bias", color=colors[1])
plt.legend()
plt.show()
देखें कि प्रशिक्षित मॉडल कैसा प्रदर्शन करता है
plt.plot(x, y, '.', label="Data")
plt.plot(x, f(x), label="Ground truth")
plt.plot(x, model(x), label="Predictions")
plt.legend()
plt.show()
print("Current loss: %1.6f" % loss(model(x), y).numpy())
Current loss: 0.897898
वही उपाय, लेकिन केरासो के साथ
उपरोक्त कोड को केरस में समकक्ष के साथ विपरीत करना उपयोगी है।
यदि आप tf.keras.Model
उपवर्ग करते हैं तो मॉडल को परिभाषित करना बिल्कुल वैसा ही दिखता है। याद रखें कि केरस मॉडल अंततः मॉड्यूल से प्राप्त होते हैं।
class MyModelKeras(tf.keras.Model):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Initialize the weights to `5.0` and the bias to `0.0`
# In practice, these should be randomly initialized
self.w = tf.Variable(5.0)
self.b = tf.Variable(0.0)
def call(self, x):
return self.w * x + self.b
keras_model = MyModelKeras()
# Reuse the training loop with a Keras model
training_loop(keras_model, x, y)
# You can also save a checkpoint using Keras's built-in support
keras_model.save_weights("my_checkpoint")
Epoch 0: W = 4.46, b = 0.40, loss=10.30171 Epoch 1: W = 4.06, b = 0.72, loss=10.30171 Epoch 2: W = 3.77, b = 0.97, loss=10.30171 Epoch 3: W = 3.56, b = 1.18, loss=10.30171 Epoch 4: W = 3.40, b = 1.34, loss=10.30171 Epoch 5: W = 3.29, b = 1.47, loss=10.30171 Epoch 6: W = 3.21, b = 1.58, loss=10.30171 Epoch 7: W = 3.15, b = 1.66, loss=10.30171 Epoch 8: W = 3.10, b = 1.73, loss=10.30171 Epoch 9: W = 3.07, b = 1.78, loss=10.30171प्लेसहोल्डर22
हर बार जब आप एक मॉडल बनाते हैं तो नए प्रशिक्षण लूप लिखने के बजाय, आप केरस की अंतर्निहित सुविधाओं को शॉर्टकट के रूप में उपयोग कर सकते हैं। यह तब उपयोगी हो सकता है जब आप पायथन प्रशिक्षण लूप को लिखना या डिबग नहीं करना चाहते हैं।
यदि आप करते हैं, तो आपको पैरामीटर सेट करने के लिए model.fit()
और प्रशिक्षित करने के लिए model.fit() का उपयोग model.compile()
होगा। L2 नुकसान और ग्रेडिएंट डिसेंट के केरस कार्यान्वयन को फिर से शॉर्टकट के रूप में उपयोग करने के लिए यह कम कोड हो सकता है। इन सुविधा कार्यों के बाहर भी केरस नुकसान और अनुकूलक का उपयोग किया जा सकता है, और पिछले उदाहरण में उनका उपयोग किया जा सकता था।
keras_model = MyModelKeras()
# compile sets the training parameters
keras_model.compile(
# By default, fit() uses tf.function(). You can
# turn that off for debugging, but it is on now.
run_eagerly=False,
# Using a built-in optimizer, configuring as an object
optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),
# Keras comes with built-in MSE error
# However, you could use the loss function
# defined above
loss=tf.keras.losses.mean_squared_error,
)
केरस fit
बैच किए गए डेटा या एक पूर्ण डेटासेट को एक NumPy सरणी के रूप में अपेक्षा करता है। NumPy सरणियों को बैचों में काटा जाता है और डिफ़ॉल्ट रूप से 32 के बैच आकार में किया जाता है।
इस मामले में, हाथ से लिखे लूप के व्यवहार से मेल खाने के लिए, आपको x
को आकार 1000 के एकल बैच के रूप में पास करना चाहिए।
print(x.shape[0])
keras_model.fit(x, y, epochs=10, batch_size=1000)
201 Epoch 1/10 1/1 [==============================] - 0s 242ms/step - loss: 10.3017 Epoch 2/10 1/1 [==============================] - 0s 3ms/step - loss: 6.3148 Epoch 3/10 1/1 [==============================] - 0s 3ms/step - loss: 4.0341 Epoch 4/10 1/1 [==============================] - 0s 3ms/step - loss: 2.7191 Epoch 5/10 1/1 [==============================] - 0s 3ms/step - loss: 1.9548 Epoch 6/10 1/1 [==============================] - 0s 2ms/step - loss: 1.5068 Epoch 7/10 1/1 [==============================] - 0s 3ms/step - loss: 1.2422 Epoch 8/10 1/1 [==============================] - 0s 2ms/step - loss: 1.0845 Epoch 9/10 1/1 [==============================] - 0s 2ms/step - loss: 0.9899 Epoch 10/10 1/1 [==============================] - 0s 3ms/step - loss: 0.9327 <keras.callbacks.History at 0x7f02ad940050>
ध्यान दें कि केरस प्रशिक्षण के बाद नुकसान को प्रिंट करता है, पहले नहीं, इसलिए पहला नुकसान कम दिखाई देता है, लेकिन अन्यथा यह अनिवार्य रूप से समान प्रशिक्षण प्रदर्शन दिखाता है।
अगले कदम
इस गाइड में, आपने देखा कि मॉडल बनाने और प्रशिक्षित करने के लिए टेंसर, वेरिएबल, मॉड्यूल और ग्रेडिएंट टेप के मुख्य वर्गों का उपयोग कैसे किया जाता है, और आगे उन विचारों को केरस के लिए कैसे मैप किया जाता है।
हालाँकि, यह एक अत्यंत सरल समस्या है। अधिक व्यावहारिक परिचय के लिए, कस्टम प्रशिक्षण पूर्वाभ्यास देखें।
बिल्ट-इन केरस ट्रेनिंग लूप्स का उपयोग करने के बारे में अधिक जानकारी के लिए, इस गाइड को देखें। प्रशिक्षण लूप और केरस के बारे में अधिक जानकारी के लिए, यह मार्गदर्शिका देखें। कस्टम वितरित प्रशिक्षण लूप लिखने के लिए, यह मार्गदर्शिका देखें।