sigmoid neuron class for optimization techniques
class SN: | |
#constructor | |
def __init__(self, w_init, b_init, algo): | |
self.w = w_init | |
self.b = b_init | |
self.w_h = [] | |
self.b_h = [] | |
self.e_h = [] | |
self.algo = algo | |
#logistic function | |
def sigmoid(self, x, w=None, b=None): | |
if w is None: | |
w = self.w | |
if b is None: | |
b = self.b | |
return 1. / (1. + np.exp(-(w*x + b))) | |
#loss function | |
def error(self, X, Y, w=None, b=None): | |
if w is None: | |
w = self.w | |
if b is None: | |
b = self.b | |
err = 0 | |
for x, y in zip(X, Y): | |
err += 0.5 * (self.sigmoid(x, w, b) - y) ** 2 | |
return err | |
def grad_w(self, x, y, w=None, b=None): | |
if w is None: | |
w = self.w | |
if b is None: | |
b = self.b | |
y_pred = self.sigmoid(x, w, b) | |
return (y_pred - y) * y_pred * (1 - y_pred) * x | |
def grad_b(self, x, y, w=None, b=None): | |
if w is None: | |
w = self.w | |
if b is None: | |
b = self.b | |
y_pred = self.sigmoid(x, w, b) | |
return (y_pred - y) * y_pred * (1 - y_pred) | |
def fit(self, X, Y, | |
epochs=100, eta=0.01, gamma=0.9, mini_batch_size=100, eps=1e-8, | |
beta=0.9, beta1=0.9, beta2=0.9 | |
): | |
self.w_h = [] | |
self.b_h = [] | |
self.e_h = [] | |
self.X = X | |
self.Y = Y | |
if self.algo == 'GD': | |
for i in range(epochs): | |
dw, db = 0, 0 | |
for x, y in zip(X, Y): | |
dw += self.grad_w(x, y) | |
db += self.grad_b(x, y) | |
self.w -= eta * dw / X.shape[0] | |
self.b -= eta * db / X.shape[0] | |
self.append_log() | |
elif self.algo == 'MiniBatch': | |
for i in range(epochs): | |
dw, db = 0, 0 | |
points_seen = 0 | |
for x, y in zip(X, Y): | |
dw += self.grad_w(x, y) | |
db += self.grad_b(x, y) | |
points_seen += 1 | |
if points_seen % mini_batch_size == 0: | |
self.w -= eta * dw / mini_batch_size | |
self.b -= eta * db / mini_batch_size | |
self.append_log() | |
dw, db = 0, 0 | |
elif self.algo == 'Momentum': | |
v_w, v_b = 0, 0 | |
for i in range(epochs): | |
dw, db = 0, 0 | |
for x, y in zip(X, Y): | |
dw += self.grad_w(x, y) | |
db += self.grad_b(x, y) | |
v_w = gamma * v_w + eta * dw | |
v_b = gamma * v_b + eta * db | |
self.w = self.w - v_w | |
self.b = self.b - v_b | |
self.append_log() | |
elif self.algo == 'NAG': | |
v_w, v_b = 0, 0 | |
for i in range(epochs): | |
dw, db = 0, 0 | |
v_w = gamma * v_w | |
v_b = gamma * v_b | |
for x, y in zip(X, Y): | |
dw += self.grad_w(x, y, self.w - v_w, self.b - v_b) | |
db += self.grad_b(x, y, self.w - v_w, self.b - v_b) | |
v_w = v_w + eta * dw | |
v_b = v_b + eta * db | |
self.w = self.w - v_w | |
self.b = self.b - v_b | |
self.append_log() | |
#logging | |
def append_log(self): | |
self.w_h.append(self.w) | |
self.b_h.append(self.b) | |
self.e_h.append(self.error(self.X, self.Y)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment