Note
Go to the end to download the full example code.
Custom: Vector dot product
Making a custom module for the vector-vector dot-product
\(y = \mathbf{u}\cdot\mathbf{v}\)
In this example, a custom module for the vector-vector dot-product is implemented. The same behavior can be realized
with the pymoto.EinSum module, which relies on the numpy function einsum().
11 import pymoto as pym
12 import numpy as np
13
14
15 class MyDotProduct(pym.Module):
16 """ Calculates vector dot-product
17 y = u . v
18 """
19 def __call__(self, vec1, vec2):
20 """ This is the response (forward) behavior used to calculate the dot product """
21 return np.dot(vec1, vec2)
22
23 def _sensitivity(self, dfdy):
24 """ This is the sensitivity (backward) behavior used for the derivative calculation. The argument `dfdy` is the
25 sensitivity of the response `f` with respect to this module's output `y`. It returns the sensitivity of the
26 response `f` with respect to the module's inputs `vec1` and `vec2`
27 """
28 vec1 = self.sig_in[0].state
29 vec2 = self.sig_in[1].state
30 return vec2*dfdy, vec1*dfdy
31
32
33 if __name__ == '__main__':
34 print(__doc__)
35
36 # --- SETUP ---
37 # Initialize signals
38 u = pym.Signal("u", np.array([2.1, 3.2, 4.3, 5.4]))
39 v = pym.Signal("v", np.array([-1.5, 3.8, 2.3, 8.5]))
40
41 with pym.Network() as fn:
42 # Initialize module and connect signals
43 use_einsum = False # Set to True to use pymoto.EinSum instead of MyDotProduct
44 if use_einsum:
45 y = pym.EinSum("i,i->")(u, v)
46 else:
47 y = MyDotProduct()(u, v)
48 y.tag = "u.v" # Set a name for the output signal
49
50 print(f"The response is u . v = dot({u.state}, {v.state}) = {y.state}")
51
52 # --- BACKPROPAGATION ---
53 y.sensitivity = 1.0
54 fn.sensitivity()
55
56 print("\nThe sensitivities are:")
57 print(f"d{y.tag}/d{u.tag} = {u.sensitivity}")
58 print(f"d{y.tag}/d{v.tag} = {v.sensitivity}")
59
60 # --- Finite difference check ---
61 pym.finite_difference([u, v], y, random=False)