<jupyter_start><jupyter_text>Loop vs Vectorization in  Logistic regression derivatives by <NAME><jupyter_code>import numpy as np
#            x1(1) x1(2) x1(3)
X =np.array([[1.,   2.,   3.], 
             [4.,   5.,   6.]])
#            x2(1) x2(2) x2(3)
# Shape of X is (2, 3), rows are input features (i.e. x1 & x2), and columns are number of training examples.

w =  np.array([[0.],
               [0.]])
# Shape of w is (2, 1). Where 2 is for input features, 1 is for output.

b = 3.,

Y = np.array([[1, 0, 1]])

# Number of input features.
n_x = X.shape[0]

# Number of training examples.
m = X.shape[1]<jupyter_output><empty_output><jupyter_text>For loop approach<jupyter_code># Here we are taking different input features seperately (for clear understanding).
x1 = X[0].reshape(1,3)  # [[1.,   2.,   3.]]
x2 = X[1].reshape(1,3)  # [[4.,   5.,   6.]]
# initializing all parameters.

J = dw1 = dw2 = db = 0
z = np.zeros((1, 3))
a = np.zeros((1, 3))
dz = np.zeros((1, 3))
#grads = {"dw1": dw1, "dw2": dw2}

for i in range(X.shape[1]): #(iteration on training examples)
    z[0][i] = np.dot(w.T, X[:,i]) + b
    a[0][i] = 1 / (1 + np.exp(-z[0][i]))
    J += -(Y[0][i] * np.log(a[0][i]) + (1 - Y[0][i]) * np.log(1 - a[0][i]))
    dz[0][i] = a[0][i]*(1 - a[0][i])
    '''
    for j in range(n_x):        # Loop through all dw
        grads["dw" + str(j+1)] += (X[j][i]*dz[0][i])/m
    '''   
    dw1 += x1[0][i]*dz[0][i]    # Here we have only dw1 and dw2 so we are not using loop. Otherwise, we have to.
    dw2 += x2[0][i]*dz[0][i]
    db += dz[0][i]

J /= m
dw1 /= m
dw2 /= m
db /= m

#print("dw1: ", grads["dw1"])
#print("dw2: ", grads["dw2"])

print("dw1: ", dw1)
print("dw2: ", dw2)<jupyter_output>dw1:  0.090353319461824
dw2:  0.22588329865456<jupyter_text>Vector approach  Only for calculating weight derivatives.<jupyter_code># initializing all parameters.

J = dw1 = dw2 = db = 0
z = np.zeros((1, 3))
a = np.zeros((1, 3))
dz = np.zeros((1, 3))

dw = np.zeros((n_x, 1))


for i in range(X.shape[1]): #(iteration on training examples)
    z[0][i] = np.dot(w.T, X[:,i]) + b
    a[0][i] = 1 / (1 + np.exp(-z[0][i]))
    J += -(Y[0][i] * np.log(a[0][i]) + (1 - Y[0][i]) * np.log(1 - a[0][i]))
    dz[0][i] = a[0][i]*(1 - a[0][i])
    
    db += dz[0][i]

dw = np.dot(X, dz.T)

J /= m
dw /= m
db /= m

print("dw1: ", dw[0])
print("dw2: ", dw[1])<jupyter_output>dw1:  [0.09035332]
dw2:  [0.2258833]<jupyter_text>Fully vectorized implementation.<jupyter_code>Z = np.dot(w.T, X) + b
A = 1 / (1 + np.exp(-Z))
dz = A*(1 - A)
dw = np.zeros((n_x, 1))
dw = np.dot(X, dz.T)

dw /= m

print("A: ", A)
print("A: ", A.shape)
print("\ndz: ", dz)
print("dz: ", dz.shape)
print("\ndw: ", dw)
print("dw: ", dw.shape)
print("\ndw: ", dw)
print("dw: ", dw.shape)<jupyter_output>A:  [[0.95257413 0.95257413 0.95257413]]
A:  (1, 3)

dz:  [[0.04517666 0.04517666 0.04517666]]
dz:  (1, 3)

dw:  [[0.09035332]
 [0.2258833 ]]
dw:  (2, 1)

dw:  [[0.09035332]
 [0.2258833 ]]
dw:  (2, 1)
StarcoderdataJupyterStructuredCleanDedup