Road to AI

Value Object

Download notebook (.ipynb)

Expression: d = a * b + c

class Value:

    def __init__(self, data):
        self.data = data

    def __repr__(self):   # This basically allows us to print nicer looking expressions for the final output
        return f"Value(data={self.data})"
    
    def __add__(self, other):
        out = Value(self.data + other.data)
        return out
    
    def __mul__(self, other):
        out = Value(self.data * other.data)
        return out
a = Value(2.0)
b = Value(-3.0)
c = Value(10.0)
a*b + c
Output
Value(data=4.0)

SAME THING!! (Up and Down cells)

(a.__mul__(b)).__add__(c)
Output
Value(data=4.0)

Visualization of the expression

class Value:

    def __init__(self, data, _children=(), _op=''):
        self.data = data
        self._prev = set(_children)
        self._op = _op

    def __repr__(self):   # This basically allows us to print nicer looking expressions for the final output
        return f"Value(data={self.data})"
    
    def __add__(self, other):
        out = Value(self.data + other.data, (self, other), '+')
        return out
    
    def __mul__(self, other):
        out = Value(self.data * other.data, (self, other), '*')
        return out
d = a*b + c
d._prev
Output
{Value(data=-6.0), Value(data=10.0)}
d._op
Output
'+'

a = Value(2.0)
b = Value(-3.0)
c = Value(10.0)

d= a*b + c
d
Output
Value(data=4.0)
%pip install graphviz
Output
Collecting graphviz
  Downloading graphviz-0.20.3-py3-none-any.whl (47 kB)
Installing collected packages: graphviz
Successfully installed graphviz-0.20.3
Note: you may need to restart the kernel to use updated packages.
Output
WARNING: You are using pip version 21.2.3; however, version 24.2 is available.
You should consider upgrading via the 'c:\Users\imdiv\OneDrive\Desktop\GitHub Portal\Micrograd\venv\Scripts\python.exe -m pip install --upgrade pip' command.
from graphviz import Digraph

def trace(root):
    #Builds a set of all nodes and edges in a graph
    nodes, edges = set(), set()
    def build(v):
        if v not in nodes:
            nodes.add(v)
            for child in v._prev:
                edges.add((child, v))
                build(child)
    build(root)
    return nodes, edges

def draw_dot(root):
    dot = Digraph(format='svg', graph_attr={'rankdir': 'LR'}) #LR == Left to Right

    nodes, edges = trace(root)
    for n in nodes:
        uid = str(id(n))
        #For any value in the graph, create a rectangular ('record') node for it
        dot.node(name = uid, label = "{ data %.4f }" % ( n.data, ), shape='record')
        if n._op:
            #If this value is a result of some operation, then create an op node (in a circle/oval shape to distinguish) for it
            dot.node(name = uid + n._op, label=n._op)
            #and connect this node to it
            dot.edge(uid + n._op, uid)

    for n1, n2 in edges:
        #Connect n1 to the node of n2
        dot.edge(str(id(n1)), str(id(n2)) + n2._op)

    return dot
draw_dot(d)

NOTE: The graph will only get generated if you have graphviz installed locally on your machine and the env variable path needs to be set.

If you want to avoid downloading it locally, you can directly run this on Google Colab to view the output, as graphviz is already preinstalled for you

Check 3_1-graph-visualisation.ipynb for viewing the outputs