before we beginthe mathematical building blocks of neural networks repeated times alongside new axis is helpful mental model here' what naive implementation would look likedef naive_add_matrix_and_vector(xy)assert len( shape= assert len( shape= assert shape[ = shape[ copy(for in range( shape[ ])for in range( shape[ ]) [ij+ [jreturn is numpy tensor is numpy vector avoid overwriting the input tensor with broadcastingyou can generally apply two-tensor element-wise operations if one tensor has shape (abnn mand the other has shape (nn mthe broadcasting will then automatically happen for axes through the following example applies the element-wise maximum operation to two tensors of different shapes via broadcastingimport numpy as np np random random(( ) np random random(( ) np maximum(xyx is random tensor with shape ( is random tensor with shape ( the output has shape ( like tensor dot the dot operationalso called tensor product (not to be confused with an elementwise productis the most commonmost useful tensor operation contrary to element-wise operationsit combines entries in the input tensors an element-wise product is done with the operator in numpykerastheanoand tensorflow dot uses different syntax in tensorflowbut in both numpy and keras it' done using the standard dot operatorimport numpy as np np dot(xyin mathematical notationyou' note the operation with dot ) mathematicallywhat does the dot operation dolet' start with the dot product of two vectors and it' computed as followsdef naive_vector_dot(xy)assert len( shape= assert len( shape= assert shape[ = shape[ and are numpy vectors licensed to