In [71]:
import copy, numpy as np
In [72]:
np.random.seed(0)
def sigmoid(x):
return 1/(1+np.exp(-x))
def sigmoid_dev(y):
return y*(1-y)
def softplus(x):
return np.log(1+np.exp(x))
def softplus_dev(y):
return 1/(1+np.exp(-y))
In [73]:
int2bin = {}
bin_dim = 8
N = pow(2, bin_dim)
binary = np.unpackbits(
np.array([range(N)], dtype=np.uint8).T,
axis=1
)
print(binary)
In [74]:
alpha = 0.1
input_dim = 3
hidden_dim = 8
output_dim = 2
s_0 = 2 * np.random.random((input_dim, hidden_dim)) - 1
s_1 = 2 * np.random.random((hidden_dim, output_dim)) - 1
In [77]:
u_0 = np.zeros_like(s_0)
u_1 = np.zeros_like(s_1)
for i in range(60001):
a_int = np.random.randint(N // 2)
a = binary[a_int]
b_int = np.random.randint(N // 2)
b = binary[b_int]
c_int = a_int + b_int
c = binary[c_int]
d = np.zeros_like(c)
overallErr = 0
layer_1_val = list()
layer_2_val = list()
h_val = list()
layer_1_val.append(np.zeros(hidden_dim))
layer_2_val.append(np.zeros(output_dim))
h_val.append(0)
for p in range(bin_dim):
X = np.array([a[-1 - p], b[-1 - p], h_val[-1]])
Y = np.array([c[-1 - p]])
layer_1 = sigmoid(np.dot(X, s_0))
layer_2 = sigmoid(np.dot(layer_1, s_1))
#print(layer_1, layer_2)
layer_1_val.append(copy.deepcopy(layer_1))
layer_2_val.append(copy.deepcopy(layer_2))
d[-1 - p] = np.round(layer_2[0])
overallErr += np.abs(c[-1 - p] - layer_2[0])
h_val.append(layer_2[1])
layer_2_det = list()
future_h_val = 0
future_h_d = 0
for p in range(bin_dim):
X = np.array([a[p], b[p], h_val[-2 - p]])
layer_1 = layer_1_val[-1 - p]
layer_2 = layer_2_val[-1 - p]
d_d = (c[p] - layer_2[0]) * sigmoid_dev(layer_2[0])
if p == 0:
h_d = (future_h_val - layer_2[1]) * sigmoid_dev(layer_2[1])
else:
h_d = future_h_d
layer_2_d = np.array([d_d, h_d])
layer_1_d = (layer_2_d.dot(s_1.T)) * sigmoid_dev(layer_1)
x_d = (layer_1_d.dot(s_0.T)) * sigmoid_dev(X)
future_h_d = x_d[2]
#print(layer_1.shape, layer_2_d.shape)
u_1 += np.tensordot(layer_1, layer_2_d, axes=0)
#print(np.tensordot(prev_layer_1, layer_1_d, axes=0))
u_0 += np.tensordot(X, layer_1_d, axes=0)
s_0 += u_0 * alpha
s_1 += u_1 * alpha
u_0 *= 0
u_1 *= 0
if i % 5000 == 0:
print("Error:", overallErr)
print("Pred:", d)
print("True:", c)
#print(s_0, s_1)
In [76]:
def pred(a_int, b_int):
a = binary[a_int]
b = binary[b_int]
d = np.zeros_like(c)
h = 0
for p in range(bin_dim):
X = np.array([a[-1 - p], b[-1 - p], h])
layer_1 = sigmoid(np.dot(X, s_0))
layer_2 = sigmoid(np.dot(layer_1, s_1))
d[-1 - p] = np.round(layer_2[0])
h = layer_2[1]
d_int = 0
for p in range(bin_dim):
d_int *= 2
if d[p] == 1:
d_int += 1
return d_int
count = 0
for i in range(N // 2):
for j in range(N // 2):
if pred(i, j) != i + j:
count += 1
print(i, j)
print("DONE", count)