<jupyter_start><jupyter_text>Callbacks  Callbacks as GUI events<jupyter_code>import ipywidgets as widgets
def f(o): print('hi')
w = widgets.Button(description='Click me')
w
w.on_click(f)<jupyter_output><empty_output><jupyter_text>Creating your own callback<jupyter_code>from time import sleep
def slow_calculation():
    res = 0
    for i in range(5):
        res += i*i
        sleep(1)
    return res
slow_calculation()
def slow_calculation(cb=None):
    res = 0
    for i in range(5):
        res += i*i
        sleep(1)
        if cb: cb(i)
    return res
def show_progress(epoch):
    print(f'Awesome! We finished epoch {epoch}!')
slow_calculation(show_progress)
slow_calculation(lambda epoch: print(f'Awesome! We finished epoch {epoch}'))
def show_progress(exclamation, epoch):
    print(f"{exclamation}! We've finished epoch {epoch}")
slow_calculation(lambda epoch: show_progress("Ok i guess", epoch))
def make_show_progress(exclamation):
    def _inner(epoch): print(f"{exclamation}! We've finished epoch {epoch}!")
    
    return _inner
slow_calculation(make_show_progress("nice"))
def make_show_progress(exclamation):
    _inner = lambda epoch: print(f"{exclamation}! We've finished epoch {epoch}")
    
    return _inner
slow_calculation(make_show_progress('Nice'))
f2 = make_show_progress('Terrific')
slow_calculation(f2)
from functools import partial
f2 = partial(show_progress, 'terrific')
slow_calculation(f2)<jupyter_output>terrific! We've finished epoch 0
terrific! We've finished epoch 1
terrific! We've finished epoch 2
terrific! We've finished epoch 3
terrific! We've finished epoch 4<jupyter_text>Callbacks as callable classes<jupyter_code>class ProgressShowingCallback():
    def __init__(self, exclamation='Awesome'): self.exclamation = exclamation
    def __call__(self, epoch): print(f'{self.exclamation}! We have finished epoch {epoch}!')
cb = ProgressShowingCallback('Just super')
slow_calculation(cb)<jupyter_output>Just super! We have finished epoch 0!
Just super! We have finished epoch 1!
Just super! We have finished epoch 2!
Just super! We have finished epoch 3!
Just super! We have finished epoch 4!<jupyter_text>Multiple Callbacks funcs; *args and **kwargs<jupyter_code>def f(*args, **kwargs): print(f"args: {args}; kwargs: {kwargs}")
f(3, 'a', testing='hello')
def slow_calculation(cb=None):
    res = 0
    for i in range(5):
        if cb: cb.before_calc(i)
        res += i*i
        sleep(1)
        if cb: cb.after_calc(i, val=res)
    return res
class PrintStepCallback():
    def __init__(self): pass
    def before_calc(self, *args, **kwargs): print("About to start")
    def after_calc(self, *args, **kwargs): print("Done step")
slow_calculation(PrintStepCallback())
class PrintStatusCallback():
    def __init__(self): pass
    def before_calc(self, epoch, **kwargs): print(f"About to start: {epoch}")
    def after_calc(self, epoch, val, **kwargs): print(f"After {epoch}: {val}")
slow_calculation(PrintStatusCallback())
PrintStatusCallback
PrintStatusCallback()<jupyter_output><empty_output><jupyter_text>Modyfing behaviour<jupyter_code>def slow_calculation(cb=None):
    res = 0
    for i in range(5):
        if cb and hasattr(cb, 'before_calc'): cb.before_calc(i)
        res += i*i
        sleep(1)
        if cb and  hasattr(cb, 'after_calc'):
            if cb.after_calc(i, res):
                print('Stopping early')
                break
    return res
class PrintAfterCallback():
    def after_calc(self, epoch, val):
        print(f"After {epoch}: {val}")
        if val > 10: return True
slow_calculation(PrintAfterCallback())
class SlowCalculator():
    def __init__(self, cb=None): self.cb, self.res = cb, 0
    
    def callback(self, cb_name, *args):
        if not self.cb: return
        cb = getattr(self.cb, cb_name, None)
        if cb: return cb(self, *args)
        
    def calc(self):
        for i in range(5):
            self.callback('before_calc', i)
            self.res += i*i
            sleep(1)
            if self.callback('after_calc', i):
                print('stopping early')
                break
class ModyfyingCallback():
    def after_calc(self, calc, epoch):
        print(f"After {epoch}: {calc.res}")
        if calc.res > 10: return True
        if calc.res < 3:  calc.res = calc.res * 2
calculator = SlowCalculator(ModyfyingCallback())
calculator.res
calculator.calc()
calculator.res<jupyter_output>After 0: 0
After 1: 1
After 2: 6
After 3: 15
stopping early<jupyter_text>`__dunder__` thingies<jupyter_code>class SloppyAdder():
    def __init__(self, o): self.o = o
    def __add__(self, b): return SloppyAdder(self.o + b.o + 0.01)
    def __repr__(self): return str(self.o)
a = SloppyAdder(1)
b = SloppyAdder(2)
a + b
a<jupyter_output><empty_output><jupyter_text>Variance and stuff<jupyter_code>t = torch.tensor([1., 2, 4, 18])
m = t.mean(); m
(t-m).mean()
(t-m).abs().mean()
(t-m).pow(2).mean()
(t-m).pow(2).mean().sqrt()
(t-m).pow(2).mean(), (t*t).mean() - (m*m)<jupyter_output><empty_output><jupyter_text>Covariance and correlation<jupyter_code>t 
torch.randn_like(t)/10 + 0.95
u = 2 * t
u *= torch.randn_like(t) / 10 + 0.95

plt.scatter(t,u);
prod = (t-t.mean()) * (u-u.mean()); prod
prod.mean()
v = torch.randn_like(t)

plt.scatter(t,v);
((t-t.mean()) * (v-v.mean())).mean()
cov = (t*v).mean() - t.mean()*v.mean(); cov
cov / (t.std() * v.std())
def log_softmax(x): return x - x.exp().sum(-1, keepdim=True).log()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14191297962181018, 'fraction_numerical': 0.012851110703139343, 'mean_word_length': 4.101123595505618, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '664010', 'license': 'Apache-2.0', 'n_tokens_mistral': 2009, 'n_tokens_neox': 1913, 'n_words': 476, 'path': 'nbs/dl2/selfmade/05a_foundations.ipynb', 'repo_name': 'Hustens0hn/fastai-course-v3', 'size': '5447'}