Value Object
Expression: d = a * b + c
In [6]:
Copied!
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
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
In [12]:
Copied!
a = Value(2.0)
b = Value(-3.0)
c = Value(10.0)
a = Value(2.0)
b = Value(-3.0)
c = Value(10.0)
In [9]:
Copied!
a*b + c
a*b + c
Out[9]:
Value(data=4.0)
SAME THING!! (Up and Down cells)
In [10]:
Copied!
(a.__mul__(b)).__add__(c)
(a.__mul__(b)).__add__(c)
Out[10]:
Value(data=4.0)
Visualization of the expression
In [3]:
Copied!
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
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
In [13]:
Copied!
d = a*b + c
d = a*b + c
In [14]:
Copied!
d._prev
d._prev
Out[14]:
{Value(data=-6.0), Value(data=10.0)}
In [15]:
Copied!
d._op
d._op
Out[15]:
'+'
In [4]:
Copied!
a = Value(2.0)
b = Value(-3.0)
c = Value(10.0)
d= a*b + c
d
a = Value(2.0)
b = Value(-3.0)
c = Value(10.0)
d= a*b + c
d
Out[4]:
Value(data=4.0)
In [1]:
Copied!
%pip install graphviz
%pip install graphviz
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.
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.
In [9]:
Copied!
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
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
In [ ]:
Copied!
draw_dot(d)
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