InterviewPrepKit

Home / Coding / Machine Learning Coding / Numerical & Data / Sigmoid and Its Gradient

Sigmoid and Its Gradient

easy 00:00
Solving tips
  • The naive 1/(1+exp(-x)) overflows for large negative x; branch on the sign of x so exp() only ever sees a non-positive argument.
  • The derivative has a clean closed form in terms of the output itself: s * (1 - s). Reuse the value you already computed instead of recomputing exp.
  • Work elementwise with NumPy and np.where so a single code path handles a whole array of mixed signs.

Implement the logistic sigmoid and its gradient from scratch with NumPy, in a way that does not overflow for large-magnitude inputs. The sigmoid squashes any real number into (0, 1) and shows up everywhere in logistic regression and neural nets, so interviewers use it to check that you can write numerically stable vectorized code.

Definition

The sigmoid and its derivative are:

s(x)  = 1 / (1 + exp(-x))
s'(x) = s(x) * (1 - s(x))

The naive form 1 / (1 + exp(-x)) overflows when x is a large negative number, because exp(-x) blows up. The stable trick is to branch on the sign of x:

x >= 0:  s = 1 / (1 + exp(-x))          # exp arg is <= 0
x <  0:  s = exp(x) / (1 + exp(x))      # exp arg is <  0

Either branch only ever feeds a non-positive value to exp, so it stays in [0, 1] and never overflows.

Task

Complete sigmoid_and_grad(x) so it returns a tuple (s, grad) of NumPy arrays with the same shape as x, where s is the numerically stable sigmoid and grad is its elementwise derivative s * (1 - s). Do not call scipy, sklearn, or any built-in sigmoid/expit helper.

Example

x = np.array([-1000.0, -1.0, 0.0, 1.0, 1000.0])
s, grad = sigmoid_and_grad(x)
s      # -> array([0.        , 0.26894142, 0.5       , 0.73105858, 1.        ])
grad   # -> array([0.        , 0.19661193, 0.25      , 0.19661193, 0.        ])

At x = 0 the sigmoid is exactly 0.5 and its slope is maximal at 0.25. At the extremes the output saturates to 0 or 1 with no overflow warning, and the gradient vanishes.

Constraints

  • 1 <= n <= 10^6; use vectorized NumPy, not a Python loop.
  • x may contain values with magnitude up to 1e3 or more; the code must not raise an overflow warning or return nan/inf.
  • Values fit in float64.

Write your solution, then hit Run tests to check it — or get a mock grade from the AI coach.

The coach remembers this session — revise your code and ask again, and it grades your progress. It gives hints, not the answer.
Report a bug