GD for logistic regression isn't stable. Why?
Your implementation seems not correct. For example:

(1) in your __gd_step() function, the line

grad[j] *= X[i, j]


which uses the index i, is outside your for loop: for i in range(self.m).

(2) in your __odds() function, the denominator exp(1 + b.dot(x)) seems incorrect. 1 should be outside of exp().