1+ """
2+ This module implements the Tensor class for automatic differentiation in the ML framework.
3+ """
4+
15import numpy as np
26
7+
38class Tensor :
9+ """
10+ Core tensor class with automatic differentiation capabilities.
11+
12+ Implements a computational graph with automatic gradient calculation
13+ for building and training neural networks.
14+ """
15+
416 def __init__ (self , data , requires_grad = False ):
17+ """
18+ Initialize a new Tensor.
19+
20+ Args:
21+ data: Input data (numpy array or convertible to numpy array)
22+ requires_grad: Whether the tensor requires gradient computation
23+ """
524 if not isinstance (data , np .ndarray ):
625 data = np .array (data , dtype = np .float32 )
726
@@ -12,11 +31,24 @@ def __init__(self, data, requires_grad=False):
1231 self ._prev = set ()
1332
1433 def __repr__ (self ):
34+ """Return string representation of the tensor."""
1535 return f"Tensor(data={ self .data } , grad={ self .grad } )"
1636
1737 def __add__ (self , other ):
38+ """
39+ Add two tensors or a tensor and a scalar.
40+
41+ Args:
42+ other: Another tensor or scalar value
43+
44+ Returns:
45+ A new tensor containing the result
46+ """
1847 other = other if isinstance (other , Tensor ) else Tensor (other )
19- out = Tensor (self .data + other .data , requires_grad = self .requires_grad or other .requires_grad )
48+ out = Tensor (
49+ self .data + other .data ,
50+ requires_grad = self .requires_grad or other .requires_grad ,
51+ )
2052
2153 def _backward ():
2254 if self .requires_grad :
@@ -36,8 +68,20 @@ def _backward():
3668 return out
3769
3870 def __mul__ (self , other ):
71+ """
72+ Multiply two tensors or a tensor and a scalar.
73+
74+ Args:
75+ other: Another tensor or scalar value
76+
77+ Returns:
78+ A new tensor containing the result
79+ """
3980 other = other if isinstance (other , Tensor ) else Tensor (other )
40- out = Tensor (self .data * other .data , requires_grad = self .requires_grad or other .requires_grad )
81+ out = Tensor (
82+ self .data * other .data ,
83+ requires_grad = self .requires_grad or other .requires_grad ,
84+ )
4185
4286 def _backward ():
4387 if self .requires_grad :
@@ -57,18 +101,51 @@ def _backward():
57101 return out
58102
59103 def __sub__ (self , other ):
104+ """
105+ Subtract a tensor or scalar from this tensor.
106+
107+ Args:
108+ other: Another tensor or scalar value
109+
110+ Returns:
111+ A new tensor containing the result
112+ """
60113 other = other if isinstance (other , Tensor ) else Tensor (other )
61114 return self + (- other )
62115
63116 def __neg__ (self ):
117+ """
118+ Negate this tensor.
119+
120+ Returns:
121+ A new tensor with negated values
122+ """
64123 return self * - 1
65124
66125 def __truediv__ (self , other ):
126+ """
127+ Divide this tensor by another tensor or scalar.
128+
129+ Args:
130+ other: Another tensor or scalar value
131+
132+ Returns:
133+ A new tensor containing the result
134+ """
67135 other = other if isinstance (other , Tensor ) else Tensor (other )
68136 return self * other ** - 1
69137
70138 def __pow__ (self , power ):
71- out = Tensor (self .data ** power , requires_grad = self .requires_grad )
139+ """
140+ Raise this tensor to a power.
141+
142+ Args:
143+ power: Exponent value
144+
145+ Returns:
146+ A new tensor containing the result
147+ """
148+ out = Tensor (self .data ** power , requires_grad = self .requires_grad )
72149
73150 def _backward ():
74151 if self .requires_grad :
@@ -80,8 +157,20 @@ def _backward():
80157 return out
81158
82159 def __matmul__ (self , other ):
160+ """
161+ Perform matrix multiplication with another tensor.
162+
163+ Args:
164+ other: Another tensor for matrix multiplication
165+
166+ Returns:
167+ A new tensor containing the result
168+ """
83169 other = other if isinstance (other , Tensor ) else Tensor (other )
84- out = Tensor (self .data @ other .data , requires_grad = self .requires_grad or other .requires_grad )
170+ out = Tensor (
171+ self .data @ other .data ,
172+ requires_grad = self .requires_grad or other .requires_grad ,
173+ )
85174
86175 def _backward ():
87176 if self .requires_grad :
@@ -101,6 +190,15 @@ def _backward():
101190 return out
102191
103192 def __getitem__ (self , idx ):
193+ """
194+ Get items from the tensor at specified indices.
195+
196+ Args:
197+ idx: Index or slice to retrieve
198+
199+ Returns:
200+ A new tensor with the selected items
201+ """
104202 out = Tensor (self .data [idx ], requires_grad = self .requires_grad )
105203
106204 def _backward ():
@@ -114,12 +212,24 @@ def _backward():
114212 return out
115213
116214 def __hash__ (self ):
215+ """Hash function for tensor objects."""
117216 return id (self )
118217
119218 def __eq__ (self , other ):
219+ """Check if two tensor objects are the same."""
120220 return id (self ) == id (other )
121221
122222 def sum (self , axis = None , keepdims = False ):
223+ """
224+ Sum tensor elements along specified axis.
225+
226+ Args:
227+ axis: Axis along which to sum
228+ keepdims: Whether to keep the summed dimensions
229+
230+ Returns:
231+ A new tensor with summed values
232+ """
123233 out_data = np .sum (self .data , axis = axis , keepdims = keepdims )
124234 out = Tensor (out_data , requires_grad = self .requires_grad )
125235
@@ -136,6 +246,12 @@ def _backward():
136246 return out
137247
138248 def mean (self ):
249+ """
250+ Calculate the mean of all tensor elements.
251+
252+ Returns:
253+ A new tensor containing the mean value
254+ """
139255 out = Tensor (self .data .mean (), requires_grad = self .requires_grad )
140256
141257 def _backward ():
@@ -148,6 +264,12 @@ def _backward():
148264 return out
149265
150266 def exp (self ):
267+ """
268+ Calculate the exponential of all tensor elements.
269+
270+ Returns:
271+ A new tensor with exponential values
272+ """
151273 out = Tensor (np .exp (self .data ), requires_grad = self .requires_grad )
152274
153275 def _backward ():
@@ -160,6 +282,12 @@ def _backward():
160282 return out
161283
162284 def log (self ):
285+ """
286+ Calculate the natural logarithm of all tensor elements.
287+
288+ Returns:
289+ A new tensor with logarithm values
290+ """
163291 out = Tensor (np .log (self .data ), requires_grad = self .requires_grad )
164292
165293 def _backward ():
@@ -172,6 +300,16 @@ def _backward():
172300 return out
173301
174302 def max (self , axis = None , keepdims = False ):
303+ """
304+ Find maximum values along specified axis.
305+
306+ Args:
307+ axis: Axis along which to find maximum values
308+ keepdims: Whether to keep the dimensions
309+
310+ Returns:
311+ A new tensor with maximum values
312+ """
175313 data = self .data
176314 max_data = np .max (data , axis = axis , keepdims = keepdims )
177315 out = Tensor (max_data )
@@ -192,6 +330,12 @@ def _backward():
192330 return out
193331
194332 def backward (self ):
333+ """
334+ Perform backpropagation starting from this tensor.
335+
336+ Computes gradients for all tensors in the computational graph
337+ that require gradients.
338+ """
195339 if self .grad is None :
196340 self .grad = np .ones_like (self .data )
197341 print ("Backward on:" , self .data )
@@ -215,7 +359,10 @@ def topo(tensor):
215359
216360 def clip_gradients (self , max_norm ):
217361 """
218- Clips gradients to prevent exploding gradients
362+ Clip gradients to prevent exploding gradients.
363+
364+ Args:
365+ max_norm: Maximum gradient norm
219366 """
220367 if self .grad is None :
221368 return
@@ -226,4 +373,3 @@ def clip_gradients(self, max_norm):
226373 # Clip if necessary
227374 if grad_norm > max_norm :
228375 self .grad = self .grad * (max_norm / (grad_norm + 1e-12 ))
229-
0 commit comments