|
@@ -3,7 +3,22 @@
|
|
"""
|
|
"""
|
|
NeuraLiA 2020 - by psy (epsylon@riseup.net)
|
|
NeuraLiA 2020 - by psy (epsylon@riseup.net)
|
|
"""
|
|
"""
|
|
|
|
+import time
|
|
|
|
+import glob
|
|
|
|
+import os.path
|
|
import numpy as np
|
|
import numpy as np
|
|
|
|
+import matplotlib.pyplot as plt
|
|
|
|
+from PIL import Image
|
|
|
|
+from numpy import array
|
|
|
|
+from scipy.ndimage.interpolation import zoom
|
|
|
|
+from sklearn.cluster import KMeans
|
|
|
|
+from skimage import measure
|
|
|
|
+
|
|
|
|
+VERSION = "v:0.2beta"
|
|
|
|
+RELEASE = "21052020"
|
|
|
|
+SOURCE1 = "https://code.03c8.net/epsylon/neuralia"
|
|
|
|
+SOURCE2 = "https://github.com/epsylon/neuralia"
|
|
|
|
+CONTACT = "epsylon@riseup.net - (https://03c8.net)"
|
|
|
|
|
|
print(75*"=")
|
|
print(75*"=")
|
|
print(" _ _ ____ _ ___ _ ")
|
|
print(" _ _ ____ _ ___ _ ")
|
|
@@ -13,90 +28,198 @@ print("| |\ | __/ |_| | _ < (_| | |___ | | / ___ \ ")
|
|
print("|_| \_|\___|\__,_|_| \_\__,_|_____|___/_/ \_| by psy")
|
|
print("|_| \_|\___|\__,_|_| \_\__,_|_____|___/_/ \_| by psy")
|
|
print(" ")
|
|
print(" ")
|
|
print(75*"=","\n")
|
|
print(75*"=","\n")
|
|
-print('"Advanced -SYA (Sigmoid + YFactor_Algorithm)- Neural Network"\n')
|
|
|
|
-print(75*"=")
|
|
|
|
-
|
|
|
|
-########################### PoC ###################################
|
|
|
|
-dataset = np.array(([1, 1], [1, 2], [1, 3], [1, 4]), dtype=float) # training set
|
|
|
|
-y_factor = 0.000003141537462295 # in-time reply Y-factor
|
|
|
|
-y = np.array(([2], [3], [4]), dtype=float) # score results
|
|
|
|
-print("\n + Training Set:\n") # printing output
|
|
|
|
-print(" 1 + 1 = 2")
|
|
|
|
-print(" 1 + 2 = 3")
|
|
|
|
-print(" 1 + 3 = 4")
|
|
|
|
-print("\n + Question:\n")
|
|
|
|
-print(" 1 + 4 = ?")
|
|
|
|
-print("\n + Answer (expected):\n")
|
|
|
|
-print(" 5\n")
|
|
|
|
-print(75*"=")
|
|
|
|
-########################### PoC ###################################
|
|
|
|
|
|
+print('"Advanced Recognition {S.Y.A.} Neural Network"\n')
|
|
|
|
+print("\n"+"-"*15+"\n")
|
|
|
|
+print(" * VERSION: ")
|
|
|
|
+print(" + "+VERSION+" - (rev:"+RELEASE+")")
|
|
|
|
+print("\n * SOURCES:")
|
|
|
|
+print(" + "+SOURCE1)
|
|
|
|
+print(" + "+SOURCE2)
|
|
|
|
+print("\n * CONTACT: ")
|
|
|
|
+print(" + "+CONTACT+"\n")
|
|
|
|
+print("-"*15+"\n")
|
|
|
|
+print("="*50)
|
|
|
|
|
|
simulation = input("\nDo you wanna start? (Y/n): ")
|
|
simulation = input("\nDo you wanna start? (Y/n): ")
|
|
if simulation == "n" or simulation == "N":
|
|
if simulation == "n" or simulation == "N":
|
|
import sys
|
|
import sys
|
|
sys.exit()
|
|
sys.exit()
|
|
-dataset = dataset/np.amax(dataset, axis=0)
|
|
|
|
-y = y/100
|
|
|
|
-X = np.split(dataset, [3])[0]
|
|
|
|
-xPredicted = np.split(dataset, [3])[1]
|
|
|
|
|
|
+
|
|
|
|
+memo_path = "stored/memo.dat"
|
|
|
|
+input_neurons = 3
|
|
|
|
+hidden_neurons = 62
|
|
|
|
+output_neurons = 1
|
|
|
|
+
|
|
|
|
+class Questioning_Network(object):
|
|
|
|
+ def make_question(self, images_dataset):
|
|
|
|
+ concepts_dataset = {}
|
|
|
|
+ i = 0
|
|
|
|
+ for k, v in images_dataset.items():
|
|
|
|
+ i = i + 1
|
|
|
|
+ img = Image.fromarray(v, 'RGB')
|
|
|
|
+ img.show()
|
|
|
|
+ answer = input("\n[AI] -> Asking: 'What do you think is this? (ex: building)' -> inputs/"+str(k)+"\n")
|
|
|
|
+ print("\n[You]-> Replied: "+str(answer))
|
|
|
|
+ concepts_dataset[i] = str(answer)
|
|
|
|
+ with open(memo_path, 'w') as data:
|
|
|
|
+ data.write(str(concepts_dataset))
|
|
|
|
+ print("[AI] -> Memorizing ...")
|
|
|
|
+ time.sleep(1)
|
|
|
|
+ print("")
|
|
|
|
+
|
|
|
|
+class Conceptual_Network(object):
|
|
|
|
+ def extract_concepts(self):
|
|
|
|
+ concepts_dataset = {}
|
|
|
|
+ f = open(memo_path, "r")
|
|
|
|
+ concepts_dataset = f.read()
|
|
|
|
+ f.close()
|
|
|
|
+ return concepts_dataset
|
|
|
|
+
|
|
|
|
+class Visual_Network(object):
|
|
|
|
+ def __init__(self):
|
|
|
|
+ print("\n"+"="*75+"\n")
|
|
|
|
+ images = glob.glob("inputs/*")
|
|
|
|
+ for image in images:
|
|
|
|
+ image = image.replace("inputs/","")
|
|
|
|
+ if not os.path.isfile('outputs/'+image):
|
|
|
|
+ im = plt.imread("inputs/"+image)
|
|
|
|
+ print("[AI] -> Visualizing: "+str(image))
|
|
|
|
+ im_small = zoom(im, (1,0,1))
|
|
|
|
+ h,w = im.shape[:2]
|
|
|
|
+ im_small_long = im.reshape((h * w, 3))
|
|
|
|
+ im_small_wide = im.reshape((h,w,3))
|
|
|
|
+ km = KMeans(n_clusters=3)
|
|
|
|
+ km.fit(im_small_long)
|
|
|
|
+ cc = km.cluster_centers_.astype(np.uint8)
|
|
|
|
+ out = np.asarray([cc[i] for i in km.labels_]).reshape((h,w,3))
|
|
|
|
+ seg = np.asarray([(1 if i == 1 else 0)
|
|
|
|
+ for i in km.labels_]).reshape((h,w))
|
|
|
|
+ contours = measure.find_contours(seg, 0.4, fully_connected="high")
|
|
|
|
+ simplified_contours = [measure.approximate_polygon(c, tolerance=4) for c in contours]
|
|
|
|
+ plt.figure(figsize=(5,10))
|
|
|
|
+ for n, contour in enumerate(simplified_contours):
|
|
|
|
+ plt.plot(contour[:, 1], contour[:, 0], linewidth=2)
|
|
|
|
+ plt.ylim(h,0)
|
|
|
|
+ print("[AI] -> Analyzing: "+str(image))
|
|
|
|
+ plt.axis('off')
|
|
|
|
+ plt.savefig('outputs/'+image, bbox_inches='tight', transparent=True, pad_inches=0)
|
|
|
|
+ else:
|
|
|
|
+ print("[AI] -> Recognizing: "+str(image))
|
|
|
|
+
|
|
|
|
+ def extract_dataset(self):
|
|
|
|
+ images_dataset = {}
|
|
|
|
+ images = glob.glob("inputs/*")
|
|
|
|
+ for image in images:
|
|
|
|
+ image = image.replace("inputs/","")
|
|
|
|
+ print("[AI] -> Remembering: "+str(image))
|
|
|
|
+ img = Image.open('outputs/'+image)
|
|
|
|
+ dataset = np.array(img)
|
|
|
|
+ images_dataset[image] = dataset
|
|
|
|
+ return images_dataset
|
|
|
|
|
|
class Neural_Network(object):
|
|
class Neural_Network(object):
|
|
- def __init__(self):
|
|
|
|
- self.inputSize = 2
|
|
|
|
- self.hiddenSize = 3
|
|
|
|
- self.outputSize = 1
|
|
|
|
- self.W1 = np.random.randn(self.inputSize, self.hiddenSize)
|
|
|
|
- self.W2 = np.random.randn(self.hiddenSize, self.outputSize)
|
|
|
|
-
|
|
|
|
- def forward(self, X):
|
|
|
|
- self.z = np.dot(X, self.W1)
|
|
|
|
- self.z2 = self.sigmoid(self.z)
|
|
|
|
- self.z3 = np.dot(self.z2, self.W2)
|
|
|
|
- o = self.sigmoid(self.z3)
|
|
|
|
- return o
|
|
|
|
-
|
|
|
|
- def sigmoid(self, s):
|
|
|
|
- return 1/(1+np.exp(-s))
|
|
|
|
-
|
|
|
|
- def sigmoidPrime(self, s):
|
|
|
|
- return s*(1-s)
|
|
|
|
-
|
|
|
|
- def backward(self, X, y, o):
|
|
|
|
- self.o_error = y - o
|
|
|
|
- self.o_delta = self.o_error*self.sigmoidPrime(o)
|
|
|
|
- self.z2_error = self.o_delta.dot(self.W2.T)
|
|
|
|
- self.z2_delta = self.z2_error*self.sigmoidPrime(self.z2)
|
|
|
|
- self.W1 += X.T.dot(self.z2_delta)
|
|
|
|
- self.W2 += self.z2.T.dot(self.o_delta)
|
|
|
|
-
|
|
|
|
- def train(self, X, y):
|
|
|
|
- o = self.forward(X)
|
|
|
|
- self.backward(X, y, o)
|
|
|
|
-
|
|
|
|
- def predict(self):
|
|
|
|
- print("="*75)
|
|
|
|
- total_neurons = self.inputSize + self.hiddenSize + self.outputSize
|
|
|
|
- print("-> NEURONS: ["+str(total_neurons)+"] (Input: ["+str(self.inputSize)+"] | Hidden: ["+str(self.hiddenSize)+"] | Output: ["+str(self.outputSize)+"])")
|
|
|
|
- print("="*75)
|
|
|
|
- print("\n + Input (scaled): \n\n " + str(xPredicted))
|
|
|
|
- print("\n + Prediction (scaled): \n\n " + str(self.forward(xPredicted)))
|
|
|
|
- print("\n + Answer (predicted): \n\n " + str(round(int(self.forward(xPredicted)*100), 2)))
|
|
|
|
- print("\n"+"-"*50+"\n")
|
|
|
|
|
|
+ def __init__(self):
|
|
|
|
+ self.inputSize = input_neurons
|
|
|
|
+ self.hiddenSize = hidden_neurons
|
|
|
|
+ self.outputSize = output_neurons
|
|
|
|
+ self.W1 = np.random.randn(self.inputSize, self.hiddenSize)
|
|
|
|
+ self.W2 = np.random.randn(self.hiddenSize, self.outputSize)
|
|
|
|
|
|
|
|
+ def forward(self, X):
|
|
|
|
+ self.z = np.dot(X, self.W1)
|
|
|
|
+ self.z2 = self.sigmoid(self.z)
|
|
|
|
+ self.z3 = np.dot(self.z2, self.W2)
|
|
|
|
+ o = self.sigmoid(self.z3)
|
|
|
|
+ return o
|
|
|
|
+
|
|
|
|
+ def sigmoid(self, s):
|
|
|
|
+ return 1/(1+np.exp(-s))
|
|
|
|
+
|
|
|
|
+ def sigmoidPrime(self, s):
|
|
|
|
+ return s*(1-s)
|
|
|
|
+
|
|
|
|
+ def backward(self, X, y, o):
|
|
|
|
+ self.o_error = y - o
|
|
|
|
+ self.o_delta = self.o_error*self.sigmoidPrime(o)
|
|
|
|
+ self.z2_error = self.o_delta.dot(self.W2.T)
|
|
|
|
+ self.z2_delta = self.z2_error*self.sigmoidPrime(self.z2)
|
|
|
|
+ self.W1 += X.T.dot(self.z2_delta)
|
|
|
|
+ self.W2 += self.z2.T.dot(self.o_delta)
|
|
|
|
+
|
|
|
|
+ def train(self, X, y):
|
|
|
|
+ o = self.forward(X)
|
|
|
|
+ self.backward(X, y, o)
|
|
|
|
+
|
|
|
|
+ def predict(self, dataset, results):
|
|
|
|
+ score = self.forward(xPredicted)
|
|
|
|
+ self.final_reply(score, dataset, results)
|
|
|
|
+
|
|
|
|
+ def final_reply(self, score, image, results):
|
|
|
|
+ concepts_dataset = { line.split()[0] : line.split()[1] for line in open(memo_path) }
|
|
|
|
+ for k, v in concepts_dataset.items():
|
|
|
|
+ if "{" in k:
|
|
|
|
+ k = k.replace("{", "")
|
|
|
|
+ if ":" in k:
|
|
|
|
+ k = k.replace(":", "")
|
|
|
|
+ if int(k) == int(score[0]):
|
|
|
|
+ if "," in v:
|
|
|
|
+ v = v.replace(",", "")
|
|
|
|
+ results[str(image)] = str(v)
|
|
|
|
+ else:
|
|
|
|
+ results[str(image)] = "UNKNOWN ..."
|
|
|
|
+
|
|
|
|
+# procedural (high) sub-class
|
|
NN = Neural_Network()
|
|
NN = Neural_Network()
|
|
-t = 0
|
|
|
|
-while True:
|
|
|
|
- loss = np.mean(np.square(y - NN.forward(X)))
|
|
|
|
- if loss > y_factor:
|
|
|
|
- t = t + 1
|
|
|
|
- print("="*75)
|
|
|
|
- print("-> ROUNDS (Learning): "+str(t))
|
|
|
|
- print("="*75)
|
|
|
|
- print("\n + Input (scaled): \n\n " + str(X).replace(" ",""))
|
|
|
|
- print("\n + Actual Output: \n\n " + str(y))
|
|
|
|
- print("\n + Predicted Output: \n\n " + str(NN.forward(X)))
|
|
|
|
- print("\n + Loss: \n\n [" + str(loss)+"]\n")
|
|
|
|
- NN.train(X, y)
|
|
|
|
- else:
|
|
|
|
- break
|
|
|
|
-NN.predict()
|
|
|
|
|
|
+VN = Visual_Network()
|
|
|
|
+CN = Conceptual_Network()
|
|
|
|
+QN = Questioning_Network()
|
|
|
|
+
|
|
|
|
+# procedural (low) sub-class
|
|
|
|
+images_dataset = VN.extract_dataset()
|
|
|
|
+concepts_dataset = CN.extract_concepts()
|
|
|
|
+
|
|
|
|
+if not concepts_dataset:
|
|
|
|
+ QN.make_question(images_dataset)
|
|
|
|
+else:
|
|
|
|
+ t = 0
|
|
|
|
+ prev_loss = None
|
|
|
|
+ results = {}
|
|
|
|
+ for k, v in images_dataset.items():
|
|
|
|
+ dataset = v/np.amax(v, axis=0)
|
|
|
|
+ for data in dataset:
|
|
|
|
+ X = data
|
|
|
|
+ xPredicted = X
|
|
|
|
+ y_factor = 0.0001 # reply condition factor
|
|
|
|
+ i = 0
|
|
|
|
+ for concept in concepts_dataset:
|
|
|
|
+ i = i + 1
|
|
|
|
+ y = np.array([i], dtype=int)
|
|
|
|
+ while True:
|
|
|
|
+ loss = np.mean(np.square(y - NN.forward(X)))
|
|
|
|
+ if prev_loss == loss:
|
|
|
|
+ break
|
|
|
|
+ else:
|
|
|
|
+ if loss > y_factor:
|
|
|
|
+ t = t + 1
|
|
|
|
+ print("\n"+"="*75)
|
|
|
|
+ print("-> ROUNDS (Learning): "+str(t))
|
|
|
|
+ print("="*75)
|
|
|
|
+ print("\n + Question (image): inputs/" + str(k))
|
|
|
|
+ print(" + Current Answer: " + str(y))
|
|
|
|
+ print(" + Loss: [" + str(loss)+"]")
|
|
|
|
+ print(" + YFactor: ["+ str(y_factor)+"]")
|
|
|
|
+ NN.train(X, y)
|
|
|
|
+ prev_loss = loss
|
|
|
|
+ y_factor = y_factor + 0.0010
|
|
|
|
+ else:
|
|
|
|
+ break
|
|
|
|
+ NN.predict(k, results)
|
|
|
|
+ print("\n"+"="*75)
|
|
|
|
+ total_neurons = input_neurons + hidden_neurons + output_neurons
|
|
|
|
+ print("-> NEURONS: ["+str(total_neurons)+"] (Input: ["+str(input_neurons)+"] | Hidden: ["+str(hidden_neurons)+"] | Output: ["+str(output_neurons)+"])")
|
|
|
|
+ print("="*75)
|
|
|
|
+ print("\n"+"[AI] -> Replying ...\n")
|
|
|
|
+ for k, v in results.items():
|
|
|
|
+ print(" + Image: inputs/"+str(k)+" -> "+str(v))
|
|
|
|
+ print("\n"+"="*75)
|
|
|
|
+
|