def compute_gradients(nn_params, input_layer_size, hidden_layer_size, num_labels, x, y, _lambda, yk=None, x_bias=None):
    m = x.shape[0]
    theta1, theta2 = unroll_thetas(nn_params, input_layer_size, hidden_layer_size, num_labels)
    a1, a2, a3, z2, z3 = feed_forward(theta1, theta2, x, x_bias)

    if yk is None:
        yk = recode_labels(y, num_labels)
        assert yk.shape == a3.shape, 'Error, shape of recoded y is different from a3'

    # Backward propagation to compute gradients
    sigma3 = a3 - yk
    sigma2 = theta2[:, 1:].T.dot(sigma3) * sigmoid_gradient(z2)

    theta1_grad = sigma2.dot(a1.T) / m
    theta2_grad = sigma3.dot(a2.T) / m
    theta1_grad[:, 1:] = theta1_grad[:, 1:] + (theta1[:, 1:] * _lambda / m)
    theta2_grad[:, 1:] = theta2_grad[:, 1:] + (theta2[:, 1:] * _lambda / m)

    return np.concatenate((theta1_grad.T.ravel(), theta2_grad.T.ravel()))
nn_params = np.concatenate((test_theta1.T.ravel(), test_theta2.T.ravel()))

_lambda = 0
j = compute_cost(nn_params, input_layer_size, hidden_layer_size, num_labels, X, y_test, _lambda)
print('\nCost without reg', j)
print('(this value should be about 0.287629) \n')

_lambda = 1
j = compute_cost(nn_params, input_layer_size, hidden_layer_size, num_labels, X, y_test, _lambda)
print('\nReal cost', j)
print('(this value should be about 0.383770) \n')

print('\nEvaluating sigmoid gradient...\n')

g = sigmoid_gradient(np.array([1, -0.5, 0, 0.5, 1]))
print('Sigmoid gradient evaluated at [1 -0.5 0 0.5 1]:\n  ')
print(g)
print('\n\n')

print('Check gradients')
check_nn_gradients()

print('\nChecking Backpropagation (w/ Regularization) ... \n')

#  Check gradients by running checkNNGradients
_lambda = 3
check_nn_gradients(_lambda)

# Also output the costFunction debugging values