1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| import numpy as np
class ANN: def __init__(self, layers): self.W = [] self.b = [] for x_nodes, h_nodes in layers: self.add_layer(x_nodes, h_nodes) def add_layer(self, x_nodes, h_nodes): self.W.append(np.random.rand(x_nodes, h_nodes)) self.b.append(np.random.rand(h_nodes))
def feed_forward(self): delta = 1e-7 a = self.x for i, w in enumerate(self.W): b = self.b[i] z = np.dot(a, w) + b a = self.activate(z) y = a return -np.sum(self.t*np.log(y + delta) + (1-self.t) * np.log((1 - y) + delta)) def train(self, x, t, epochs=1, learning_rate=1e-2, activate=None, debug_step=None): self.x = x self.t = t self.activate = activate or ANN.sigmoid if not debug_step: debug_step = int(epochs * 0.1) f = lambda x: self.feed_forward() for step in range(epochs): for i in range(len(self.W)): self.W[i] -= learning_rate * ANN.derivative(f, self.W[i]) self.b[i] -= learning_rate * ANN.derivative(f, self.b[i]) if step % debug_step == 0: print('step = ', step, 'loss value = ', self.feed_forward())
def predict(self, input_data): a = input_data for i, w in enumerate(self.W): b = self.b[i] z = np.dot(a, w) + b a = self.activate(z) return a
@staticmethod def derivative(f, x, dx=1e-5): grad = np.zeros_like(x) it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite']) while not it.finished: idx = it.multi_index tmp_val = x[idx] x[idx] = tmp_val + dx fx1 = f(x) x[idx] = tmp_val - dx fx2 = f(x) grad[idx] = (fx1 - fx2) / (2 * dx) x[idx] = tmp_val it.iternext() return grad
@staticmethod def sigmoid(z): return 1 / (1+np.exp(z))
|