حسب ضرورت TensorFlow/Keras کال بیکس لکھنے کے لیے گائیڈ

تعارف

فرض کریں کہ آپ چاہتے ہیں کہ آپ کے Keras ماڈل میں تربیت، تشخیص یا پیشین گوئی کے دوران کچھ مخصوص رویہ ہو۔ مثال کے طور پر، آپ ہر تربیتی دور میں اپنے ماڈل کو بچانا چاہتے ہیں۔ ایسا کرنے کا ایک طریقہ کال بیکس کا استعمال ہے۔

عام طور پر، کال بیکس ایسے فنکشنز ہوتے ہیں جن کو اس وقت بلایا جاتا ہے جب کوئی واقعہ ہوتا ہے، اور دوسرے فنکشنز کو دلیل کے طور پر منتقل کیا جاتا ہے۔ Keras کے معاملے میں، وہ آپ کے ماڈل کے طرز عمل کو اپنی مرضی کے مطابق کرنے کا ایک ٹول ہیں - چاہے وہ تربیت، تشخیص یا تخمینہ کے دوران ہو۔ کچھ ایپلیکیشنز لاگنگ، ماڈل استقامت، جلد روکنا یا سیکھنے کی شرح کو تبدیل کر رہے ہیں۔ یہ کال بیکس کی فہرست کو دلائل کے طور پر پاس کرکے کیا جاتا ہے۔ keras.Model.fit(),keras.Model.evaluate() or keras.Model.predict().

کال بیکس کے لیے کچھ عام استعمال کے معاملات سیکھنے کی شرح میں تبدیلی، لاگنگ، نگرانی اور تربیت کو جلد بند کر رہے ہیں۔ کیراس میں متعدد بلٹ ان کال بیکس ہیں، تفصیل سے
دستاویزات میں
.

تاہم، کچھ اور مخصوص ایپلیکیشنز کو حسب ضرورت کال بیک کی ضرورت ہو سکتی ہے۔ مثال کے طور پر، ہولڈنگ پیریڈ کے بعد کوزائن ڈیکی کے ساتھ لرننگ ریٹ وارم اپ کو نافذ کرنا فی الحال بلٹ ان نہیں ہے، لیکن بڑے پیمانے پر استعمال کیا جاتا ہے اور ایک شیڈیولر کے طور پر اپنایا جاتا ہے۔

کال بیک کلاس اور اس کے طریقے

کیراس کی ایک مخصوص کال بیک کلاس ہے، keras.callbacks.Callbackان طریقوں کے ساتھ جنہیں تربیت کے دوران بلایا جا سکتا ہے، ٹیسٹنگ اور عالمی، بیچ یا عہد کی سطح پر اندازہ لگایا جا سکتا ہے۔ کرنے کے لیے حسب ضرورت کال بیکس بنائیں، ہمیں ایک ذیلی کلاس بنانے اور ان طریقوں کو اوور رائڈ کرنے کی ضرورت ہے۔

۔ keras.callbacks.Callback کلاس کے تین قسم کے طریقے ہیں:

  • عالمی طریقے: شروع میں یا آخر میں کہا جاتا ہے۔ fit(), evaluate() اور predict().
  • بیچ کی سطح کے طریقے: بیچ کی پروسیسنگ کے آغاز یا اختتام پر کہا جاتا ہے۔
  • عہد کی سطح کے طریقے: تربیتی بیچ کے آغاز یا اختتام پر کہا جاتا ہے۔

نوٹ: ہر طریقہ کو ایک ڈکٹ تک رسائی حاصل ہوتی ہے۔ logs. کی کلیدیں اور اقدار logs سیاق و سباق سے متعلق ہیں - وہ اس واقعہ پر منحصر ہیں جو طریقہ کو کہتے ہیں۔ مزید یہ کہ، ہمیں ہر طریقہ کے اندر ماڈل تک رسائی حاصل ہے۔ self.model وصف.

آئیے حسب ضرورت کال بیکس کی تین مثالوں پر ایک نظر ڈالتے ہیں - ایک تربیت کے لیے، ایک تشخیص کے لیے اور ایک پیشین گوئی کے لیے۔ ہر ایک ہر مرحلے پر پرنٹ کرے گا کہ ہمارا ماڈل کیا کر رہا ہے اور ہمیں کن لاگز تک رسائی حاصل ہے۔ یہ سمجھنے میں مددگار ہے کہ ہر مرحلے پر حسب ضرورت کال بیکس کے ساتھ کیا کرنا ممکن ہے۔

آئیے ایک کھلونا ماڈل کی وضاحت کرتے ہوئے شروع کریں:

import tensorflow as tf
from tensorflow import keras
import numpy as np

model = keras.Sequential()
model.add(keras.layers.Dense(10, input_dim = 1, activation='relu'))
model.add(keras.layers.Dense(10, activation='relu'))
model.add(keras.layers.Dense(1))
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=0.1),
    loss = "mean_squared_error",
    metrics = ["mean_absolute_error"]
)

x = np.random.uniform(low = 0, high = 10, size = 1000)
y = x**2
x_train, x_test = (x[:900],x[900:])
y_train, y_test = (y[:900],y[900:])

کسٹم ٹریننگ کال بیک

تربیت کے دوران ہمارا پہلا کال بیک کال کرنا ہے۔ آئیے ذیلی کلاس کریں۔ Callback کلاس:

class TrainingCallback(keras.callbacks.Callback):
    def __init__(self):
        self.tabulation = {"train":"", 'batch': " "*8, 'epoch':" "*4}
    def on_train_begin(self, logs=None):
        tab = self.tabulation['train']
        print(f"{tab}Training!")
        print(f"{tab}available logs: {logs}")

    def on_train_batch_begin(self, batch, logs=None):
        tab = self.tabulation['batch']
        print(f"{tab}Batch {batch}")
        print(f"{tab}available logs: {logs}")

    def on_train_batch_end(self, batch, logs=None):
        tab = self.tabulation['batch']
        print(f"{tab}End of Batch {batch}")
        print(f"{tab}available logs: {logs}")

    def on_epoch_begin(self, epoch, logs=None):
        tab = self.tabulation['epoch']
        print(f"{tab}Epoch {epoch} of training")
        print(f"{tab}available logs: {logs}")

    def on_epoch_end(self, epoch, logs=None):
        tab = self.tabulation['epoch']
        print(f"{tab}End of Epoch {epoch} of training")
        print(f"{tab}available logs: {logs}")

    def on_train_end(self, logs=None):
        tab = self.tabulation['train']
        print(f"{tab}Finishing training!")
        print(f"{tab}available logs: {logs}")

اگر ان طریقوں میں سے کسی کو اوور رائڈ نہیں کیا جاتا ہے تو - پہلے سے طے شدہ رویہ پہلے کی طرح جاری رہے گا۔ ہماری مثال میں - ہم صرف دستیاب لاگز اور اس سطح کو پرنٹ کرتے ہیں جس پر کال بیک لاگو ہوتا ہے، مناسب انڈینٹیشن کے ساتھ۔

آئیے آؤٹ پٹ پر ایک نظر ڈالیں:

model.fit(
    x_train,
    y_train,
    batch_size=500,
    epochs=2,
    verbose=0,
    callbacks=[TrainingCallback()],
)
Training!
available logs: {}
    Epoch 0 of training
    available logs: {}
        Batch 0
        available logs: {}
        End of Batch 0
        available logs: {'loss': 2172.373291015625, 'mean_absolute_error': 34.79669952392578}
        Batch 1
        available logs: {}
        End of Batch 1
        available logs: {'loss': 2030.1309814453125, 'mean_absolute_error': 33.30256271362305}
    End of Epoch 0 of training
    available logs: {'loss': 2030.1309814453125, 'mean_absolute_error': 33.30256271362305}
    Epoch 1 of training
    available logs: {}
        Batch 0
        available logs: {}
        End of Batch 0
        available logs: {'loss': 1746.2772216796875, 'mean_absolute_error': 30.268001556396484}
        Batch 1
        available logs: {}
        End of Batch 1
        available logs: {'loss': 1467.36376953125, 'mean_absolute_error': 27.10252571105957}
    End of Epoch 1 of training
    available logs: {'loss': 1467.36376953125, 'mean_absolute_error': 27.10252571105957}
Finishing training!
available logs: {'loss': 1467.36376953125, 'mean_absolute_error': 27.10252571105957}


نوٹ کریں کہ ہم ہر قدم پر پیروی کر سکتے ہیں کہ ماڈل کیا کر رہا ہے، اور ہمیں کن میٹرکس تک رسائی حاصل ہے۔ ہر بیچ اور عہد کے اختتام پر، ہمیں نمونے کے نقصان کے فنکشن اور اپنے ماڈل کے میٹرکس تک رسائی حاصل ہوتی ہے۔

حسب ضرورت تشخیص کال بیک

اب، آئیے کال کرتے ہیں۔ Model.evaluate() طریقہ ہم دیکھ سکتے ہیں کہ بیچ کے اختتام پر ہمیں نقصان کے فنکشن اور اس وقت کے میٹرکس تک رسائی حاصل ہے، اور تشخیص کے اختتام پر ہمیں مجموعی نقصان اور میٹرکس تک رسائی حاصل ہے:

class TestingCallback(keras.callbacks.Callback):
    def __init__(self):
          self.tabulation = {"test":"", 'batch': " "*8}
      
    def on_test_begin(self, logs=None):
        tab = self.tabulation['test']
        print(f'{tab}Evaluating!')
        print(f'{tab}available logs: {logs}')

    def on_test_end(self, logs=None):
        tab = self.tabulation['test']
        print(f'{tab}Finishing evaluation!')
        print(f'{tab}available logs: {logs}')

    def on_test_batch_begin(self, batch, logs=None):
        tab = self.tabulation['batch']
        print(f"{tab}Batch {batch}")
        print(f"{tab}available logs: {logs}")

    def on_test_batch_end(self, batch, logs=None):
        tab = self.tabulation['batch']
        print(f"{tab}End of batch {batch}")
        print(f"{tab}available logs: {logs}")
res = model.evaluate(
    x_test, y_test, batch_size=100, verbose=0, callbacks=[TestingCallback()]
)
Evaluating!
available logs: {}
        Batch 0
        available logs: {}
        End of batch 0
        available logs: {'loss': 382.2723083496094, 'mean_absolute_error': 14.069927215576172}
Finishing evaluation!
available logs: {'loss': 382.2723083496094, 'mean_absolute_error': 14.069927215576172}

حسب ضرورت پیشین گوئی کال بیک

آخر میں، آئیے کال کرتے ہیں۔ Model.predict() طریقہ نوٹ کریں کہ ہر بیچ کے آخر میں ہمارے پاس اپنے ماڈل کے پیش گوئی شدہ آؤٹ پٹس تک رسائی ہے:

class PredictionCallback(keras.callbacks.Callback):
    def __init__(self):
        self.tabulation = {"prediction":"", 'batch': " "*8}

    def on_predict_begin(self, logs=None):
        tab = self.tabulation['prediction']
        print(f"{tab}Predicting!")
        print(f"{tab}available logs: {logs}")

    def on_predict_end(self, logs=None):
        tab = self.tabulation['prediction']
        print(f"{tab}End of Prediction!")
        print(f"{tab}available logs: {logs}")

    def on_predict_batch_begin(self, batch, logs=None):
        tab = self.tabulation['batch']
        print(f"{tab}batch {batch}")
        print(f"{tab}available logs: {logs}")

    def on_predict_batch_end(self, batch, logs=None):
        tab = self.tabulation['batch']
        print(f"{tab}End of batch {batch}")
        print(f"{tab}available logs:n {logs}")
res = model.predict(x_test[:10],
                    verbose = 0, 
                    callbacks=[PredictionCallback()])

بہترین طرز عمل، صنعت کے لیے منظور شدہ معیارات، اور چیٹ شیٹ کے ساتھ Git سیکھنے کے لیے ہمارے ہینڈ آن، عملی گائیڈ کو دیکھیں۔ گوگلنگ گٹ کمانڈز کو روکیں اور اصل میں سیکھ یہ!

Predicting!
available logs: {}
        batch 0
        available logs: {}
        End of batch 0
        available logs:
 {'outputs': array([[ 7.743822],
       [27.748264],
       [33.082104],
       [26.530678],
       [27.939169],
       [18.414223],
       [42.610645],
       [36.69335 ],
       [13.096557],
       [37.120853]], dtype=float32)}
End of Prediction!
available logs: {}

ان کے ساتھ - آپ رویے کو اپنی مرضی کے مطابق بنا سکتے ہیں، نگرانی ترتیب دے سکتے ہیں یا بصورت دیگر تربیت، تشخیص یا تخمینہ کے عمل کو تبدیل کر سکتے ہیں۔ sublcassing کا ایک متبادل استعمال کرنا ہے۔ LambdaCallback.

LambaCallback استعمال کرنا

کیراس میں بلٹ ان کال بیکس میں سے ایک ہے۔ LambdaCallback کلاس یہ کال بیک ایک فنکشن کو قبول کرتا ہے جو اس بات کی وضاحت کرتا ہے کہ یہ کیسا برتاؤ کرتا ہے اور یہ کیا کرتا ہے! ایک لحاظ سے، یہ آپ کو کسی بھی صوابدیدی فنکشن کو بطور کال بیک استعمال کرنے کی اجازت دیتا ہے، اس طرح آپ کو حسب ضرورت کال بیکس بنانے کی اجازت ملتی ہے۔

کلاس میں اختیاری پیرامیٹرز ہیں:
-on_epoch_begin

  • on_epoch_end
  • on_batch_begin
  • on_batch_end
  • on_train_begin
  • on_train_end

ہر پیرامیٹر قبول کرتا ہے۔ ایک فنکشن جسے متعلقہ ماڈل ایونٹ میں کہا جاتا ہے۔ مثال کے طور پر، ماڈل کے تربیت مکمل ہونے پر ای میل بھیجنے کے لیے ایک کال بیک کریں:

import smtplib
from email.message import EmailMessage

def send_email(logs): 
    msg = EmailMessage()
    content = f"""The model has finished training."""
    for key, value in logs.items():
      content = content + f"n{key}:{value:.2f}"
    msg.set_content(content)
    msg['Subject'] = f'Training report'
    msg['From'] = '[email protected]'
    msg['To'] = 'receiver-email'

    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.starttls()
    s.login("[email protected]", "your-gmail-app-password")
    s.send_message(msg)
    s.quit()

lambda_send_email = lambda logs : send_email(logs)

email_callback = keras.callbacks.LambdaCallback(on_train_end = lambda_send_email)

model.fit(
    x_train,
    y_train,
    batch_size=100,
    epochs=1,
    verbose=0,
    callbacks=[email_callback],
)

کا استعمال کرتے ہوئے اپنی مرضی کے مطابق کال بیک کرنے کے لیے LambdaCallbackہمیں صرف اس فنکشن کو لاگو کرنے کی ضرورت ہے جسے ہم بلایا جانا چاہتے ہیں، اسے a کے طور پر لپیٹیں۔ lambda فنکشن کریں اور اسے پاس کریں۔
LambdaCallback ایک پیرامیٹر کے طور پر کلاس.

ماڈل ٹریننگ کو دیکھنے کے لیے ایک کال بیک

اس سیکشن میں، ہم ایک حسب ضرورت کال بیک کی مثال دیں گے جو تربیت کے دوران ہمارے ماڈل کی کارکردگی کو بہتر بنانے کا ایک اینیمیشن بناتا ہے۔ ایسا کرنے کے لیے، ہم لاگز کی قدروں کو ہر بیچ کے آخر میں محفوظ کرتے ہیں۔ پھر، ٹریننگ لوپ کے اختتام پر، ہم استعمال کرتے ہوئے ایک اینیمیشن بناتے ہیں۔ matplotlib.

تصور کو بڑھانے کے لیے، نقصان اور میٹرکس کو لاگ اسکیل میں پلاٹ کیا جائے گا:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
from IPython import display

class TrainingAnimationCallback(keras.callbacks.Callback):
    def __init__(self, duration = 40, fps = 1000/25):
        self.duration = duration
        self.fps = fps
        self.logs_history = []

    def set_plot(self):   
        self.figure = plt.figure()
        
        plt.xticks(
            range(0,self.params['steps']*self.params['epochs'], self.params['steps']),
            range(0,self.params['epochs']))
        plt.xlabel('Epoch')
        plt.ylabel('Loss & Metrics ($Log_{10}$ scale)')

        self.plot = {}
        for metric in self.model.metrics_names:
          self.plot[metric], = plt.plot([],[], label = metric)
          
        max_y = [max(log.values()) for log in self.logs_history]
        
        self.title = plt.title(f'batches:0')
        plt.xlim(0,len(self.logs_history)) 
        plt.ylim(0,max(max_y))

           
        plt.legend(loc='upper right')
  
    def animation_function(self,frame):
        batch = frame % self.params['steps']
        self.title.set_text(f'batch:{batch}')
        x = list(range(frame))
        
        for metric in self.model.metrics_names:
            y = [log[metric] for log in self.logs_history[:frame]]
            self.plot[metric].set_data(x,y)
        
    def on_train_batch_end(self, batch, logs=None):
        logarithm_transform = lambda item: (item[0], np.log(item[1]))
        logs = dict(map(logarithm_transform,logs.items()))
        self.logs_history.append(logs)
       
    def on_train_end(self, logs=None):
        self.set_plot()
        num_frames = int(self.duration*self.fps)
        num_batches = self.params['steps']*self.params['epochs']
        selected_batches = range(0, num_batches , num_batches//num_frames )
        interval = 1000*(1/self.fps)
        anim_created = FuncAnimation(self.figure, 
                                     self.animation_function,
                                     frames=selected_batches,
                                     interval=interval)
        video = anim_created.to_html5_video()
        
        html = display.HTML(video)
        display.display(html)
        plt.close()

ہم پہلے جیسا ہی ماڈل استعمال کریں گے، لیکن مزید تربیتی نمونوں کے ساتھ:

import tensorflow as tf
from tensorflow import keras
import numpy as np

model = keras.Sequential()
model.add(keras.layers.Dense(10, input_dim = 1, activation='relu'))
model.add(keras.layers.Dense(10, activation='relu'))
model.add(keras.layers.Dense(1))
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=0.1),
    loss = "mean_squared_error",
    metrics = ["mean_absolute_error"]
)

def create_sample(sample_size, train_test_proportion = 0.9):
    x = np.random.uniform(low = 0, high = 10, size = sample_size)
    y = x**2
    train_test_split = int(sample_size*train_test_proportion)
    x_train, x_test = (x[:train_test_split],x[train_test_split:])
    y_train, y_test = (y[:train_test_split],y[train_test_split:])
    return (x_train,x_test,y_train,y_test)

x_train,x_test,y_train,y_test = create_sample(35200)


model.fit(
    x_train,
    y_train,
    batch_size=32,
    epochs=2,
    verbose=0,
    callbacks=[TrainingAnimationCallback()],
)

ہمارا آؤٹ پٹ میٹرکس اور نقصان کے فنکشن کی ایک اینیمیشن ہے کیونکہ وہ تربیتی عمل کے ذریعے تبدیل ہوتے ہیں:

آپ کا براؤزر HTML ویڈیو کی حمایت نہیں کرتا ہے۔

نتیجہ

اس گائیڈ میں، ہم نے کیراس میں حسب ضرورت کال بیکس کے نفاذ پر ایک نظر ڈالی ہے۔
حسب ضرورت کال بیکس کو لاگو کرنے کے لیے دو اختیارات ہیں - ذیلی کلاس کے ذریعے keras.callbacks.Callback کلاس، یا استعمال کرتے ہوئے keras.callbacks.LambdaCallback کلاس.

ہم نے استعمال کرتے ہوئے ایک عملی مثال دیکھی ہے۔ LambdaCallbackٹریننگ لوپ کے اختتام پر ایک ای میل بھیجنے کے لیے، اور ایک مثال ذیلی کلاس کرنے کے لیے Callback کلاس جو ٹریننگ لوپ کی اینیمیشن بناتی ہے۔

اگرچہ کیراس کے پاس بہت سے بلٹ ان کال بیکس ہیں، لیکن یہ جاننا کہ کسٹم کال بیک کو کیسے لاگو کیا جائے زیادہ مخصوص ایپلی کیشنز کے لیے مفید ہو سکتا ہے۔

ٹائم اسٹیمپ:

سے زیادہ Stackabuse