123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-"
- """
- NeuraLiA 2020 - by psy (epsylon@riseup.net)
- """
- import time
- import glob
- import os.path
- 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(" _ _ ____ _ ___ _ ")
- print("| \ | | ___ _ _| _ \ __ _| | |_ _| / \ ")
- print("| \| |/ _ \ | | | |_) / _` | | | | / _ \ ")
- print("| |\ | __/ |_| | _ < (_| | |___ | | / ___ \ ")
- print("|_| \_|\___|\__,_|_| \_\__,_|_____|___/_/ \_| by psy")
- print(" ")
- print(75*"=","\n")
- 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): ")
- if simulation == "n" or simulation == "N":
- import sys
- sys.exit()
- 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):
- 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()
- 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():
- v = v.replace("}", "")
- print(" + Image: inputs/"+str(k)+" -> "+str(v))
- print("\n"+"="*75)
|