PROGRAMUL DE STUDIU CALCULATOARE FORMA DE ÎNVĂȚĂMÂNT IF Proiect de diplomă COORDONATOR ȘTIINȚIFIC Șef lucr.dr.ing. Otto Poszet ABSOLVENT… [306966]

UNIVERSITATEA DIN ORADEA

FACULTATEA DE INGINERIE ELECTRICĂ ȘI TEHNOLOGIA INFORMAȚIEI

PROGRAMUL DE STUDIU CALCULATOARE

FORMA DE ÎNVĂȚĂMÂNT IF

Proiect de diplomă

COORDONATOR ȘTIINȚIFIC

Șef lucr.dr.ing. Otto Poszet

ABSOLVENT: [anonimizat]-Dumitru BERE

ORADEA

2017

UNIVERSITATEA DIN ORADEA

FACULTATEA DE INGINERIE ELECTRICĂ ȘI TEHNOLOGIA INFORMAȚIEI

PROGRAMUL DE STUDIU CALCULATOARE

FORMA DE ÎNVĂȚĂMÂNT IF

Asistent personal

„Sistem de Cunoștințe Inteligent”

(SKY)

COORDONATOR ȘTIINȚIFIC

Șef lucr.dr.ing. Otto Poszet

ABSOLVENT: [anonimizat]-Dumitru BERE

ORADEA

2017

UNIVERSITATEA DIN ORADEA

FACULTATEA DE INGINERIE ELECTRICĂ ȘI TEHNOLOGIA INFORMAȚIEI

DEPARTAMENTUL DE CALCULATOARE ȘI TEHNOLOGIA INFORMATIEI

TEMA_____________

Lucrare de Finalizare a studiilor a student: [anonimizat]: Alexandru-Dumitru BERE

1). Tema lucrării de finalizare a studiilor: Asistent personal „Sistem de Cunoștințe Inteligent”(SKY)

2). Termenul pentru predarea lucrării: 05.07.2017

3). Elemente inițiale pentru elaborarea lucrării de finalizare a studiilor: Computer Desktop: Procesor Intel(R) Core(TM) i3-2120 CPU 3.3 GHz, 16 [anonimizat] 960 SO-Windows 10, A4Tech PK-635, Smartphone Samsung Galaxy S6, Handsfree bluetooth/cablu, [anonimizat](WAN și LAN), Boxe, Server, cunoștințe de programare.

4). Conținutul lucrării de finalizare a studiilor: Introducere, Capitolul I. Hardware, Capitolul II. Software, Capitolul III. [anonimizat]. Concluzii, Bibliografie.

5).Material grafic: Prezentare PowerPoint.

6). Locul de documentare pentru elaborarea lucrării: [anonimizat] ,,Gheorghe Șincai” Oradea, Internet.

7). Data emiterii temei: 01.10.2016.

Coordonator științific

Șef lucr.dr.ing. Otto Poszet

Introducere

Lucrarea pusă în discuție intitulată Sistem de Cunoștințe Inteligent(SKY) [anonimizat].

[anonimizat], el să poată să raspundă cu promtitudine în funcție de parametrii furnizați de asemenea tot prin limbaj natural cât mai uman. Totodată prin modulul de recunoaștere facială să se poată stabili persoana cu care interacționează.

[anonimizat] a fost inventată de John McCarthy [1] [anonimizat] o definiție concisă și formală până în prezent. O definiție reprezentativă este pivotată în jurul comparării inteligenței mașinilor computerizate cu ființele umane [2]. O altă definiție se referă la performanța mașinilor care ,,au fost considerate istorie în domeniul inteligenței” [3], [4].

Niciuna dintre aceste definiții sau altele asemenea nu a [anonimizat] ,,inteligență”, care în prezent este o cantitate abstractă și incomensurabilă. O definiție mai bună a AI, [anonimizat] ,,inteligență”. Psihologii și teoreticienii cognitivi sunt de părere că inteligența ajută la identificarea celei mai potrivite elemente de cunoștințe în cazurile de luare a deciziilor adecvate [5], [6]. Expresia ,,AI” poate fi astfel impusă ca simulare a inteligenței umane printr-o mașină, pentru a face mașina eficientă să identifice și să utilizeze piesa potrivită a ,,cunoștințelor”,
la un anumit pas de rezolvare a unei probleme. Un sistem capabil să planifice și să execute sarcina corectă la momentul potrivit este, în general, numit rațional [7]. Astfel, AI poate fi declarat alternativ ca subiect care se ocupă de modele computaționale care pot gândi și acționa rațional [8] , [9], [10] , [11]. O întrebare obișnuită apare în mod firesc: gândirea rațională și acțiunea includ toate caracteristicile posibile ale unui sistem inteligent? Dacă da, cum reprezintă o inteligență comportamentală, cum ar fi învățarea mașinilor, percepția
și planificarea? O mică gândire, totuși, arată că un sistem care poate raționa bine trebuie să fie un planificator de succes, deoarece planificarea în multe circumstanțe face parte dintr-un proces de raționament. Mai mult, un sistem poate acționa rațional doar după ce a dobândit cunoștințe

adecvate din lumea reală.

Așadar, percepția care reprezintă crearea de cunoștințe din informațiile din lumea reală este o condiție prealabilă pentru acțiunile raționale.

Un pas mai departe de gândire prevede că o mașină fără capacitatea de învățare nu poate avea percepție. Acțiunea rațională a unui agent (actor), prin urmare, solicită posesia tuturor caracteristicilor elementare ale inteligenței. Relaționarea AI cu modelele computaționale capabile să gândească și să acționeze rațional, prin urmare, are o semnificație pragmatică.

Perioada modernă începe din a două jumătate a anilor 1970 până în prezent. Această perioadă este dedicată rezolvării problemelor mai complexe de interes practic. Experimentele MYCIN de la Universitatea Stanford [12], [13] au dus la un sistem expert care ar putea diagnostica și prescrie medicamente pentru bolile bacteriologice infecțioase. Sistemul MECHO pentru rezolvarea problemelor mașinilor newtoniene este un alt sistem expert care se ocupă de problemele din viața reală. Trebuie adăugat că, pe lângă rezolvarea problemelor din lumea reală, cercetătorii sunt implicați și în cercetarea teoretică privind AI, inclusiv căutarea euristică, modelarea incertitudinii și raționamentul nemonotonic și spațio-temporal. Pentru a rezuma, această perioadă, ea include cercetarea atât a teoriilor, cât și a aspectelor practice ale AI.

Ținând cont de explozia performanțelor componentelor electronice și a calculatoarelor în general, este evident că termenul de Inteligență Artificială va căpăta noi valențe în anii următori.

Iată o scurtă enumerare a domeniilor în care este și va fi folosită Inteligența Artificială:

Rețele neuronale : sunt sisteme care simulează inteligența prin reproducerea tipurilor de conexiuni fizice care se găsesc în creierul biologic. Din cauza limitărilor tehnologice, numărul acestor conexiuni este foarte mic, comparativ cu cele câteva zeci de miliarde de conexiuni din creierul uman;

Sisteme expert: Sistemul expert este format dîntr-un grup de programe și o colecție de informații specifice, cu ajutorul cărora se poate purta un dialog om-computer, în vederea rezolvării problemelor. Informațiile recepționate de la calculator sunt asemănătoare cu cele date de un expert uman în domeniul respectiv. Sistemele expert multiplică inteligența formalizată a unor specialiști punând-o la dispoziția acelor persoane al căror acces la respectivii specialiști este imposibilă;

Agenții: sunt entități computerizate care acționează în locul operatorilor umani, adunând știri de pe Internet, trimițând mesaje de e-mail sau filtrându-le pe cele primite. Deși lucrează pe baza unor ,,cuvinte cheie” și se află încă în cercetare, agenții vor deveni foarte utili, ajutându-și utilizatorul să găsească, spre exemplu, numai știrile sau articolele care îl interesează, scutindu-l de ore întregi de navigare inutilă pe Internet;

Roboți: Noile modele de roboți au în componență computere programate să ,,audă”, să ,,vadă” și să reacționeze la diferiți stimuli externi. Există deja roboți care pășesc asemenea unei ființe vii, disting o voce din mai multe, răspunzând numai la comanda acesteia, se orientează în spațiu, recunoscând obiectele înconjurătoare, aleg drumul cel mai scurt între două puncte și ocolesc obstacolele.

Înțelegerea limbajului natural: acesta reprezintă programarea computerelor astfel încât acestea să înțeleagă și să interacționeze cu utilizatorii în limbajul natural al acestora. La baza înțelegerii limbajului natural se află recunoașterea vocală care transformă un dialog în text, folosind un dispozitiv special;

Un computer actual poate realiza 10 la puterea 17 operații pe secundă (o operație în timpul în care lumina ar străbate un atom de hidrogen). E clar că viteza aparține mașinii. Ce atu are omul ? Cel mai important pare a fi elementul surpriză, omul este imprevizibil, gândirea sa nu respectă întotdeauna un algoritm, așa cum îl știe mașina. Subiectul AI a fost îmbogățit cu o disciplină largă de cunoștințe din filosofie, psihologie, științe cognitive, stiința calculatoarelor, matematică și inginerie [14] (figura nr.1).

Capitolul I. Hardware

I.1. Componente hardware

Pentru utilizarea și implementarea Sistemului de Cunostințe Inteligent este nevoie de următoarele componente hardware:

Computer Desktop: Procesor Intel(R) Core(TM) i3-2120 CPU 3.3 GHz, 16 GB RAM, placa video NVIDIA GeForce GTX 960 sau laptop: Procesor Intel(R) Core(TM) i5-5250U CPU 1.6 GHz, 4 GB RAM, SO-Windows 10;

Cameră web încorporată(laptop) sau A4Tech PK-635;

Smartphone Samsung Galaxy S6;

Handsfree bluetooth/cablu;

Router Wireless;

Legatură stabilă la internet(WAN și LAN);

Boxe;

Server (opțional).

Componentele menționate mai sus reprezintă specificațiile recomandate și totodată componentele cu care a fost implementată și testată lucrarea pusă în discuție.

Aplicația este destinată implementării în căminul propriu, de aceea componentele pot varia în ceea ce privește performanța și calitatea acestora.

Pentru o mai bună acuratețe în detectarea comenzilor vocale se recomandă folosirea unui set handsfree de o calitate superioară atât și o legatură stabilă la internet în cadrul rețelei de internet. În ceea ce privește detectarea facială se recomandă de asemenea o cameră web care să permită o captură video cât mai precisă.

I.2. Schema bloc hardware

În figura nr. 1.1 este descrisă schema bloc a componentelor hardware, prin care se dorește o descriere cât mai clară a comunicațiilor dintre componentele ce compun arhitectura proiectului pus în discuție.

Putem observa în schema prezentată atât datele de intrare și ieșire cât și fluxul datelor.

Pentru ca smartphone-ul să poată comunica cu engine-ul SKY aflat pe laptop sau pe computerul desktop trebuie ca cele două să fie conectate la aceeași rețea locală(LAN).

Interogarea datelor care nu se află stocate local, se face prin conexinea la un server, care nu trebuie să fie neapărat local, unde este configurată o bază de date. Se recomandă ca majoritatea datelor să fie stocate pe un server, atât din punct de vedere al securității dar și din motive de portabilitate.

Capitolul II. Software

Pentru o mai bună gestionare a implementării aplicației am adoptat un stil de lucru modularizat.

Aplicația în discuție este un cumul a 5 module mari:

Modulul de preluare și interpretare a comenzilor;

Modulul de captură și recunoaștere facială;

Modulul de conversie voce-text;

Modulul aflat pe server-ul web împreună cu bazele de date;

Modul de antrenare-web.

În subcapitolele ce urmează vom parcurge în detaliu modulele prezentate mai sus.

II.1. Modulul de preluare și interpretare a comenzilor

Acest modul reprezintă oarecum inima aplicației deoarece aici se petrec majoritatea operațiilor. Acesta poate să poceseze informațiile local și să raspundă dacă are posibilitatea sau să interogheze serverul în funcție de parametrii furnizați de către utilizator.

În general, limbajele relaționale, cum ar fi PROLOG [15] sau limbajele funcționale precum LISP, sunt preferate pentru calculul simbolic în AI. Cu toate acestea, în cazul în care programul necesită un calcul aritmetic mult (adică, în scopul gestionării incertitudinilor), atunci poate fi folosit un limbaj procedural. Există o dilemă între alegerea limbajelor de programare pentru rezolvarea problemelor cu AI până în prezent. Un limbaj procedural care oferă un apel pentru o funcție relațională sau un limbaj relațional care permite interfața cu una procedurală este probabil cea mai bună alegere. În prezent, sunt disponibile un număr de shell-uri (pentru ES), în care utilizatorul trebuie să prezinte numai cunoștințe și shell-ul oferă simultan implementarea atât a procesării numerice, cât și a celei simbolice.

Pentru acest modul a fost folosit mediul de programare Visual Studio Communiy 2015 împreună cu limbajul de programare C#, deoarece am dorit să aduc o notă personalizată acestei aplicații și deoarece este unul dintre limbajele de programare cunoscut.

C# (pronunțat ,,C sharp”) este un limbaj de programare care este conceput pentru a construi o varietate de aplicații care rulează pe .NET Framework. C# este simplu, puternic, sigur și orientat spre obiect. Multe inovații din C# permit dezvoltarea rapidă a aplicațiilor, păstrând în același timp expresivitatea și eleganța limbajelor în stilul C [16].

Mediul de dezvoltare integrat Visual Studio (IDE) este o colecție de instrumente de dezvoltare expuse printr-o interfață de utilizare comună. Unele instrumente sunt partajate cu alte limbi Visual Studio, iar altele, cum ar fi compilatorul C#, sunt unice pentru Visual C#. Acest subiect oferă legături către cele mai importante instrumente Visual C# [17].

Modulul de preluare și interpretare a comenzilor împreună cu modulul de recunoaștere facială se regăsesc în aplicația care este instalată în computer(figura nr. 1.1 și 2.1).

Pentru realizarea interfeței aplicației, am implementat un formular cu ajutorul Windows Forms Application folosintd uneltele puse la dispoziție de mediul de programare.

Figura nr. 2.1– Interfața utilizator –preluarea și interpretarea comenzilor

În acest subcapitol vom descrie implementarea și funcționalitatea punctelor 1 și 2 din (figura nr . 2.1) care reprezintă partea de intrare/ieșire a datelor.

Punctul 1 din (figura nr. 2.1) reprezintă partea de intrare a datelor(comenzilor) implementată cu ajutorul unui ,,textBox” furnizat de Visual Studio Community 2015.

Comenzile introduse cu ajutorul modului 3, cel ce ne permite convertirea vocii în text sunt apoi preluate de către aplicație și sunt prelucrate ca și parametri.

Pentru aceasta am creat un eveniment pe acest ,,textbox” pentru preluarea comenzilor:

private void textBox3_TextChanged(object sender, EventArgs e){}

După preluarea comenzii într-o variabilă, aici ea este prelucrată atât local(după caz) sau trimisă la server.

InputText = textBox3.Text;

Pentru prelucrare datelor local și emiterea unui răspuns a fost nevoie de o bază de date locală formată și stocată în string-uri și fișiere.

//=====SKY Resurse=================================================

string Numeinfo = File.ReadAllText(Application.StartupPath + "/Resurse/Nume.txt");

string[] Nume = Numeinfo.Split('%');

string Rasp_cfinfo = File.ReadAllText(Application.StartupPath + "/Resurse/Rasp_cf.txt");

string[] Rasp_cf = Rasp_cfinfo.Split('%');

string[,] stateSky = new string[2, 3]{/*bad */{ "imi pare rau", "incearca să te linistesti", "intindete putin"},/*good*/{ "ma bucur", "dragut", "ma bucur să aud asta" } };

//=====User Inputs==================================================

string[] cm_te_num = new string[] { " cum te numesti", " cine esti", " cum te cheama", " cine ești" };

string[] cf = new string[] { "ce faci", "cum esti" };

string[] h = new string[] { " cât e ceasul", "cat este ceasul", " cât e ceasul" };

string[] salut = new string[]{"buna dimineata"," buna ziua", "buna seara", " salut" };

string[,] state = new string[2, 3]{/*bad */{"imi este rau", "nu ma simt bine","ma doare capul"},/*good*/{"bine","citesc","vorbesc cu tine"}};

Acest stil de lucru cu string-uri și fișiere a stat la baza primilor pași în crearea aplicației, ca mai apoi să fie extinsă pe o bază de date pe server.

Datele sunt stocate în fișier sub forma:

%alex%mihai%gabi

Datele sunt extrase din fișier și introduse într-un string prin metoda .Split('%');

Pentru transmiterea parametrilor potrivit comenzii către server, datele au fost codate base64 astfel:

public static string Base64Encode(string plainText)

{

var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);

string b64=System.Convert.ToBase64String(plainTextBytes);

b64 = b64.Replace('+', '-');

b64 = b64.Replace('/', '_');

b64 = b64.Replace('=', ',');

return b64;

}

Base64 reprezintă date binare într-un format ASCII. Fiecare digit din base64 reprezintă exact 6 biti de date.

După codarea datelor, ele se transmit către server în format JSON:

public string aduhtml(string link,string var)

{

string url = link+"?"+var;

WebRequest myReq = WebRequest.Create(url);

WebResponse wr = myReq.GetResponse();

Stream receiveStream = wr.GetResponseStream();

StreamReader reader = new StreamReader(receiveStream,Encoding.UTF8);

string content = reader.ReadToEnd();

return content;}

private void intrebare(object sender, EventArgs e)

{

distruge_bucla();

if (InputVerif.Length >= 3 && InputVerif == InputText)

{

string b64=Base64Encode(InputText);

string rasp=aduhtml("http://sky.5b.ro/admin/caut_answ_c.php","q="+

b64+ "&qt=audio" + "&qu=" + id_user);

//string rasp=aduhtml("http://sky.5b.ro/admin/caut_answ_c.php","q="+ b64 +"&qt=text"+"&qu="+id_user);

string xxx=json2string(rasp,"a");

creaza_file_mp3(xxx);

var playlist = wmp.newPlaylist("test", "");

playlist.appendItem(wmp.newMedia(fis_mp3));

wmp.currentPlaylist = playlist;

wmp.Ctlcontrols.play();

textBox3.Text = "";

if (File.Exists(fis_mp3)) { File.Delete(fis_mp3); }

InputVerif = "";

textBox3.Text = "";

InputText = "";}else{bucla(1000);InputVerif = InputText;}}

JSON (JavaScript Object Notation) este un format de schimb de date ușor. Este ușor pentru oameni să citească și să scrie. Este ușor pentru mașini să analizeze și să genereze. Se bazează pe un subset al limbajului de programare JavaScript, ECMA-262 ediția a treia – decembrie 1999. JSON este un format text care este complet independent de limbaje de programare, dar utilizează convenții care sunt familiare programatorilor în C, inclusiv C , C ++, C #, Java, JavaScript, Perl, Python și multe altele. Aceste proprietăți fac din JSON un limbaj ideal de schimb de date.

JSON este construit pe două structuri :

O colecție de perechi de nume / valoare. În diferite limbaje, acest lucru este realizat ca un obiect, record, struct, dicționar, tabelul hash, lista cu chei sau matricea asociativă.

O listă ordonată de valori. În majoritatea limbajelor, acest lucru este realizat ca o matrice, vector, listă sau secvență.

Acestea sunt structuri de date universale. Practic, toate limbajele de programare moderne le susțin într-o formă sau alta. Un format de date care este interschimbabil cu limbajele de programare se bazează, de asemenea, pe aceste structuri [18].

Răspunsul primit de la server se face parametrizat prin intermediul următoarei linii de cod.

string rasp = aduhtml("https://sky.5b.ro/admin/caut_answ_c.php", "q=" + b64 + "&qt=audio" + "&qu=" + id_user); -returnează audio

string rasp = aduhtml("https://sky.5b.ro/admin/caut_answ_c.php", "q="+ b64 +"&qt=text"+"&qu="+id_user); -returnează text

Deasemenea răspunsul de la server revine codat și el și pentru aceasta avem nevoie de un decoder.

public static string Base64Decode(string base64EncodedData){

string b64 = base64EncodedData;

b64 = b64.Replace('-', '+');

b64 = b64.Replace('_', '/');

b64 = b64.Replace(',', '=');

var base64EncodedBytes = System.Convert.FromBase64String(b64);

return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);}

După decodarea răspunsului pentru a putea fii redat vocal de către Sistemul de Cunoștințe Inteliget am avut nevoie de implementarea unui Windows Media Player din cadrul uneltelor puse la dispoziție de Visual Studio Community 2015(figura nr 2.1; pct.2).

Redarea făcută pentru procesarea local a comenzilor

foreach (string t în cf){

if (InputText == t){

distruge_bucla();old = 1;

int NumRes = Rasp_cf.Length;

Random randval = new Random();

int randnum = randval.Next(0, NumRes);

var rasp = Rasp_cf[randnum].Split(delimSpace);

var playlist = wmp.newPlaylist("Ce faci", "");

foreach (string a în rasp) {

playlist.appendItem(wmp.newMedia(path + a + ext)); }

playlist.appendItem(wmp.newMedia(path + "gol" + ext));

wmp.currentPlaylist = playlist;wmp.Ctlcontrols.play();

textBox3.Text ="";//golire continut textBox După redare răspuns

return;}}

Algoritmul este simplu, dacă comanda introdusă se află memorată în string-ul ,,cf” atunci programul returnează un răspuns aleator din răspunsurile memorate în stringul ,,Rasp_cf”.

Acest răspuns este despărțit în cuvinte în string+ul ,,rasp”, apoi fiecare cuvânt din acest string este adăugat în Playlistul ,,Ce faci”.

După parcurgerea întregului șir de cuvinte, răspunsul este redat audio cu ajutorul sintagmei:

wmp.Ctlcontrols.play();

Fișierele audio cu extensia .wav, asociate fiecarui cuvânt, sunt stocate în dosarul ,,voce”, de unde sunt extrase și formate propoziții în funcție de comenzile și răspunsurile cerute.

Fișiere audio din cadrul bibliotecii locale de voce au fost create cu ajutorul unei aplicații mobile de inregistrare audio regăsită pe smarphone împreună cu programul de editare audio-video Sony Vegas PRO 13.0. Fiecare cuvânt a fost preluat din înregistrare, prelucrat și salvat cu denumirea cuvântului plus extensia .wav.

Exemplu:

Propoziție înregistrată: este frumos afara.

Cuvinte salvate în baza locală de cuvinte: este.wav,frumos.wav, afara.wav.

La redarea răspunsului se compune propoziția din cuvintele învățate.

Redarea făcută pentru procesarea pe server a comenzilor

Datele sosite de la server pot fi, după cum am putut vedea puțin mai sus, de tip text sau audio.

Datele de tip text sunt redate la fel ca cele procesate local, în schimb cele audio trebuie formatate astfel:

private void creaza_file_mp3(string mp3_b64){

string tmp_path = Path.GetTempPath();

string unixTimestamp = ((Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds).ToString();

string file_path = tmp_path +"tmp_"+ unixTimestamp+".mp3"; fis_mp3 = file_path;

try{ if (File.Exists(file_path)) {

File.Delete(file_path);}

using (FileStream fs = File.Create(file_path)){

Byte[] info =Base64Decode_hex(mp3_b64);

fs.Write(info, 0, info.Length);

fs.Close();

}

}

catch (Exception ex)

{textBox1.Text = "aa";}}

În secvența de cod de mai sus este creat fișierul temporar .mp3 cu denumirea asociată unixTimestamp .

După procedura urmată mai sus, fișierul este redat în același fel ca în cazul procesării locale.

var playlist = wmp.newPlaylist("serv", "");

playlist.appendItem(wmp.newMedia(fis_mp3));

wmp.currentPlaylist = playlist;

wmp.Ctlcontrols.play();

textBox3.Text ="";//golire conținut textBox după redare răspuns

II.2. Modulul de recunoaștere facială

Acest modul reprezintă partea în care Sistemul de Cunoștințe Inteligent poate învăța amprenta facială a persoanei cu care poartă discuția.

Figura nr. 2.2 – Interfața utilizator – recunoaștere facială

După cum se poate vedea în figura nr. 3 modulul de recunoaștere facială este prezent în interfața utilizator prin 3 elemente:

Expunere facială preluată de la camera web;

Captura facială;

Rezultat captură.

Pentru realizarea modului de captură și recunoaștere facială a fost nevoie de unele librării speciale, de aceea am apelat la un cross platform .Net wrapper de procesare a imaginilor din biblioteca OpenCV, numit Emgu CV. Acesta permite funcțiilor să fie apelate de către limbajele de programare compatibile .NET(C#,VB,etc). Împachetarea poate fi compilată de Visual Studio, Xamarin Studio și Unity, poate funcționa pe Windows, Linux, Mac OS X, iOS, Android și Windows Phone [19].

Principiul care stă la baza, este cel al recunoașterii obiectelor PCA(Principle Components Analysis).Clasa serializabilă public class EigenObjectRecognizerA împreună cu metodele pe care le vom discuta aici vor facilita funcționarea modului de recunoaștere facială.

Eigen reprezintă o biblioteca C++ de sabloane pentru algebra liniară(matrice, vectori). Această bibliotecă este una versatilă deoarece suportă matrici de diferite mărimi, de la matrici mici fixe la matrici largi și dense. Totodată șabloanele de expresie permit eliminarea inteligentă a temporarilor și permite evaluarea mai lentă, atunci când este oportună, mărimile matriciale fixe sunt pe deplin optimizate: alocarea dinamică a memoriei este evitată și buclele sunt derulate atunci când acest lucru are sens, toate acestea facilitând viteza de execuție.

Eigen nu are alte dependințe decât biblioteca standard C++. Folosim sistemul de construcție CMake, dar numai pentru a construi documentația și testele de unitate și pentru a automatiza instalarea. Dacă doriți doar să utilizați Eigen, puteți utiliza fișierele antet imediat. Nu există o bibliotecă binară la care să se lege și nici un fișier antet configurat. Eigen este o bibliotecă șablon pur definită în anteturi [20].

În interiorul clasei menționate mai sus se regăsesc metodele aferente.

Obțineți vectorii eigen care formează spațiul eigen.

public Image<Gray, Single>[] EigenImages

Obțineți sau setați etichetele pentru imaginea de antrenament corespunzătoare.

public String[] Labels

Obțineți sau setați pragul de distanță propriu-zis. Cu cât este mai mic numărul, cu atât este mai probabil ca o imagine examinată să fie tratată ca obiect nerecunoscut.

Setatat la un număr imens (de exemplu, 5000) și recunoașterea va trata întotdeauna imaginea examinată ca fiind unul dintre obiectele cunoscute.

public double EigenDistanceThreshold

Obțineți imaginea medie.

public Image<Gray, Single> AverageImage

Obțineți valorile proprii ale fiecărei imagini de antrenament

public Matrix<float>[] EigenValues

Creați un identificator de obiecte utilizând datele specifice și parametrii de antrenament, acesta va întoarce întotdeauna cel mai asemănător obiect.

Parametrul „images” – Imaginile folosite pentru antrenament, fiecare dintre ele ar trebui să aibă aceeași dimensiune. Se recomandă ca imaginile să fie normalizate cu histogramă.

Parametrul „termCrit” – Criteriile de formare a recunoașterii.

Parametrul „eigenDistanceThreshold” -Pragul de distanță propriu-zis, (0, ~ 1000]. Cu cât este mai mic numărul, cu atât este mai probabil ca o imagine examinată să fie tratată ca obiect nerecunoscut, dacă pragul este < 0, recunoașterea va trata întotdeauna imaginea examinată ca fiind unul dintre obiectele cunoscute.

Crearea unui recunoscător de obiecte utilizând datele specifice și parametrii de învățare.

public EigenObjectRecognizerA(Image<Gray, Byte>[] images,ref MCvTermCriteria termCrit):this(images,GenerateLabels(images.Length)

,ref termCrit)

private static String[] GenerateLabels(int size)

public EigenObjectRecognizerA(Image<Gray, Byte>[] images, String[] labels, double eigenDistanceThreshold, ref MCvTermCriteria termCrit)

Calcularea imaginilor eigen pentru imaginea de învățare specifică.

Parametrul „trainingImages” – Imaginea folosită pentru antrenament.

Parametrul „eigenImages” – Imaginea eigen rezultată.

Parametrul „avg” – Imaginea medie rezultată..

public static void CalcEigenObjects(Image<Gray, Byte>[] trainingImages, ref MCvTermCriteria termCrit, out Image<Gray, Single>[] eigenImages, out Image<Gray, Single> avg)

Descompune imaginea ca valori eigen, folosind vectorii specifici eigen și va returna valoare eigen a imaginii descompuse.

Parametrul „src”- Imaginea ce urmează să fie descompusă.

public static float[] EigenDecomposite(Image<Gray, Byte> src, Image<Gray, Single>[] eigenImages, Image<Gray, Single> avg)

Având în vedere valoarea eigen, reconstruim imaginea proiectată și se va returna imaginea proiectată.

Parametrul „eigenValue”- Imaginea ce urmează să fie descompusă.

public Image<Gray, Byte> EigenProjection(float[] eigenValue)

Obținem distanța eigen euclidiană dintre „image” (imaginea care trebuie comparată cu imaginile de antrenament) și fiecare imagine din baza de date antrenată până acum, returnând un array de distanțe eigen de la fiecare imagine din imaginile de antrenament.

public float[] GetEigenDistances(Image<Gray, Byte> image)

Fiind dată imaginea pentru a fi examinată, se caută în baza de date cel mai similar obiect, returnând index-ul și distanța eigen împreună cu eticheta specifică imaginii.

public void FindMostSimilarObject(Image<Gray, Byte> image, out int index, out float eigenDistance, out String label)

Se incearcă recunoașterea imaginii și se returnează eticheta sa. Poate să returneze String.Empty dacă imaginea nu este recunoscută.

public String Recognize(Image<Gray, Byte> image)

În continuare vom vorbi despre partea de implementare care se regăsește în formularul principal.

Se începe cu declararea tuturor variabilelor, vectorilor și haarcascades. După această etapă, la punerea aplicației în funcțiune, camera se pornește (figura nr. 2.2; pct. 1) , se încearcă haarcascades pentru detectarea facială împreună cu imaginile și etichetele deja antrenate.

face = new HaarCascade("haarcascade_frontalface_default.xml");

grabber = new Capture();

grabber.QueryFrame();

Detectarea obiectului folosind clasificatorii de cascadă Haar este o metodă eficientă de detectare a obiectelor propusă de Paul Viola și Michael Jones în lucrarea ,,Detectarea rapidă a obiectelor folosind o cascadă de caracteristici simple” din 2001. Este o abordare bazată pe mașină, Funcția cascadă este instruită dintr-o mulțime de imagini pozitive și negative. Apoi este folosit pentru a detecta obiecte în alte imagini [21].

În momentul în care se rostește comanda „numele meu este alex” pe langă faptul că sistemul va răspunde specific dar și va face o captură facială. Obținem un cadru gri din dispozitivul de captare redimenzionând imaginea. Imaginea împreună cu numele sunt salvate în baza de date antrenată cu același index.

trainingImages.ToArray()[i – 1].Save(Application.StartupPath + "/TrainedFaces/face" + i + ".bmp");

File.AppendAllText(Application.StartupPath+"/TrainedFaces/TrainedLabels.txt",labels.ToArray()[i – 1] + "%");

Pentru antrenare manuală fără a da o comandă vocală, există și posibilitatea antrenării prin scrierea numelui și apoi apăsând butonul „Adaugă fața”. Acest lucru poate duce la o mai bună acuratețe a detectării faciale (figura nr. 2.2; pct. 2).

Funcția void FrameGrabber recunoaște și redă numărul de persoane aflate în cadru împreună cu numele persoanelor care se află în cadru (figura nr. 2.2; pct. 3).

Obținem forma capturii curente.

currentFrame = grabber.QueryFrame().Resize(320, 240, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);

Convertim în alb-negru.

gray = currentFrame.Convert<Gray, Byte>();

Detectorul facial.

MCvAvgComp[][]facesDetected=gray.DetectHaarCascade(face,1.2,10,HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,new Size(20, 20));

Acțiune asupra fiecărui element detectat

foreach (MCvAvgComp f în facesDetected[0])

– desenare pătrat roșu în jurul feței detectate, aplicarea detectării eigen, afișarea numelui persoanei aflate în cadru cu verde deasupra pătratului roșu, numărul de persoane din cadru împreună cu numele asociat cu albastru(figura nr. 2.2; pct. 1 și 3).

În cazul în care nu există nici măcar o singură recunoaștere facială, atunci nu se va afișa numărul de persoane și numele asociate, doar patratul roșu asociat detectării faciale încă neantrenate.

II.3. Modulul de convertire voce-text

Pentru realizarea acestui modul a fost nevoie de un serviciu client-server care să poată facilita convertirea comezilor vocale în text.

De aceea pe dispozitivul smartphone trebuie să fie instalată o aplicație mobilă care să aibă posibilitatea de a transmite către aplicația noastră textul corespunzător comenzii.

Folosind un dispozitiv care folosește sistemul de operare Android , a fost nevoie să gasesc o aplicație care să funcționeze cu acest sistem de operare. Cu ajutorul bibliotecii vaste de aplicații gratuite sau cu costuri suplimentare de pe portalul Play Store, am ales aplicația gratuită „Intel Remote Keyboard” [22] care are implementată și opțiunea speak-to-text furnizată de Google Cloud Speach API.

Google Cloud Speech API [23] permite dezvoltatorilor să convertească audio în text prin aplicarea unor modele de rețele neuronale puternice într-un API ușor de utilizat. API-ul recunoaște peste 80 de limbi și variante, pentru a susține baza de utilizatori globală. Permite comanda și controlul prin voce sau transcrie fișiere audio, printre multe alte cazuri de utilizare.

După instalarea aplicației „Intel Remote Keyboard” pe smartphone este nevoie ca pe computerul pe care rulează Sistemul de Cunoștințe Inteligent să fie instalat un server asociat aplicației mobile furnizat deasemenea de către cei de la Intel.

Pentru ca aplicația mobilă cu cea de pe computerul unde rulează Sistemul de Cunoștințe Inteligent să funcționeze, este nevoie ca cele două să se afle în aceeași rețea locală prescurtat LAN(figura nr.2.3).

Figura nr. 2.3 – Schema modul voce-text

Sincronizarea celor două și menținerea conexiunii active depind de stabilitatea rețelei de internet.

Deoarece aplicația mobilă folosește Google Cloud Speach API și momentan librăria în limba română nu este disponibilă și offline este nevoie de o conexiune la internet, preferabil ca smartphone-ul să fie legat la rețeaua locală și mai apoi la internet prin Wireless.

Pentru o mai buna calitate a serviciilor speach-to-text se recomandă achiziționarea unei aplicații cu profilul de mai sus sau crearea uneia dedicate.

Din dorința de a creea o aplicație care să fie gestionată vocal în limba română, am întâlnit nenumarate dificultăți în descoperirea unor modalități de a transforma comenzile vocale transmise în limba română, în text . Majoritatea aplicațiilor cu profilul celei puse în discuție în lucrarea de față , operează doar în limba engleză sau în număr mai mic în alte limbi de circulație internațională.

II.4. Modulul aflat pe server-ul web împreună cu bazele de date

Pentru a demonstra faptul ca dimensiunile pe care Sistemul de Cunoștințe Inteligent pot crește pe parcursul timpului a fost nevoie de crearea unei baze de date în cazul de fața MySQL, împreună cu o legatură la aplicația instalată pe computer. Pentru această legătură și gestionarea interogărilor făcute de către aplicația noastră, am implemetat împreună cu limbajul de programare PHP un backend care să faciliteze acest lucru.

Toate acestea se regăsesc pe un server configurat pentru sistemul de operare Linux.

MySQL este un sistem de gestiune a bazelor de date relaționale, produs de compania suedeza MySQL AB și distribuit sub Licența Publică Generală GNU. Este cel mai popular SGBD open-source la ora actuală, fiind o componentă cheie a stivei LAMP (Linux, Apache, MySQL, PHP). Deși este folosit foarte des împreună cu limbajul de programare PHP, cu MySQL se pot construi aplicații în orice limbaj major. Există multe scheme API disponibile pentru MySQL ce permit scrierea aplicațiilor în numeroase limbaje de programare pentru accesarea bazelor de date MySQL, cum ar fi: C, C++, C#, Java, Perl, PHP, Python, FreeBasic, etc., fiecare dintre acestea folosind un tip specific API. O interfață de tip ODBC denumită MyODBC permite altor limbaje de programare ce folosesc această interfață, să interacționeze cu bazele de date MySQL cum ar fi ASP sau Visual Basic. În sprijinul acestor limbaje de programare, unele companii produc componente de tip COM/COM+ sau .NET (pentru Windows) prin intermediul cărora respectivele limbaje să poată folosi acest SGBD mult mai ușor decât prin intermediul sistemului ODBC. Aceste componente pot fi gratuite (ca de exemplu MyVBQL) sau comerciale [24],[25].

Crearea bazelor de date și gestionarea lor a fost făcută cu ajutorul software-ului phpMyAdmin.

PhpMyAdmin este un instrument software gratuit, scris în PHP, conceput pentru a gestiona administrarea MySQL pe Web. PhpMyAdmin suportă o gamă largă de operații pe MySQL și MariaDB. Operațiile utilizate frecvent (administrarea bazelor de date, a tabelelor, a coloanelor, a relațiilor, a indexurilor, a utilizatorilor, a permisiunilor etc.) pot fi realizate prin interfața cu utilizatorul, în timp ce încă aveți capacitatea de a executa direct orice instrucțiune SQL[26].

Diagrama ilustrată în figura nr. 2.4 reprezintă structura bazei de date aflate pe server. Baza de date cuprinde 8 tabele care sunt interogate în funcție de parametri furnizați de către aplicația SKY sau de modulul de antrenare web.

În cele ce urmează este este descrisă arhitectura tabelelor existente în baza de date:

„answ” conține o cheie primară „id_answ”(bigint), conține întrebarea sau comanda transmisă către aplicație „answ”(mediumtext) și id-ul operatorului „id_oper”(tinyint).

„answ2rasp” conține cheia primară „id_a2r”(bigint), prin „id_answ” se memorează id-ul întrebării sau comenzii din tabela „answ” și prin „id_rasp”(bigint) se recunoaște răspunsul asociat acelei comenzi în tabela „rasp”.

„cuv” conține o cheie primară „id_cuvânt”(bigint), rangul atribuit acelui cuvânt în funcție de importanța acelui cuvânt „id_rang”(int), cuvântul propriu-zis sub forma de caractere „cuvânt”(varchar) și lungimea cuvântului(numărul de caractere ce formează cuvântul) „lung”(int).

„cuv2rasp” conține cheia primară „id_c2a”(bigint), prin „id_cuvânt” se memorează id-ul cuvântului din tabela „cuv” și prin „id_rasp”(bigint) se recunoaște răspunsul asociat acelui cuvânt în tabela „rasp”.

„rasp” conține cheia primară „id_rasp”(bigint) împreună cu răspunsul antrenat în format text și fișierul .mp3 asociat răspunsului în format mediumtext encoded base64 preluat de Google text-to-speach.

„arh_rasp” conține o cheie primară „id_arh”(bigint), „id_rasp”(bigint) este creat pentru a reține id-ul ultimului răspuns împreună cu „data_arh”(datetime) pentru reținerea datei când a fost redat și „id_user”(bigint) care reprezintă id-ul aplicației de pe care a fost dată comanda(dacă sunt mai multe aplicații SKY instalate pe diferite computere).

„cuv_rec” având cheia primară „id_cuv”(bigint), cuvântul memorat „cuv”(varchar) și „rec”(tinyint) care memorează dacă a fost sau nu înregistrat cuvântul în baza de date locală aflată în aplicație.

„utilizatori_web” având cheia primară „id”(int), tipul grupului din care face parte utilizatorul(admin sau user) „id_grup”(int), datele utilizatorului „nume”(varchar), „prenume”(varchar), este important să știm și vârsta de aceea am creat „data_nasteri”(date),”username”(varchar), „password”(varchar), stare(varchar), grad_acces(mediumtext) și obs(tinytext).

După adresarea comenzii sau întrebării din cadru aplicație SKY regăsite pe computer, se parcurg tabele aflate la punctele 1, 2, 5 și 6 de mai sus, Dacă comanda trimisă se regăsește memorată în tabela de la punctul 1, se redă răspunsul asociat.

Pe de altă parte dacă comanda nu este memorată, se parcurg tabelele aflate la punctele 3, 4, 5 și 6 pentru a încerca găsirea cel puțin a unui cuvânt din comanda transmisă ca apoi să poată fi redirecționat spre un posibil răspuns în funcție de importanța cuvintelor, în cazul în care nu este găsit nici un răspuns se va reda unul dintre răspunsurile prestabilite în cazul acesta.

Conectarea la baza de date, inserari, ștergeri, modificări și alte operații au fost facute în interiorul codurilor sursă scrise cu ajutorul limbajului de programare PHP prezentate în secțiunea ce urmează.

Limbajul de programare PHP (Hypertext Preprocessor) a fost folosit inițial pentru a produce pagini web dinamice, este folosit pe scară largă în dezvoltarea paginilor și aplicațiilor web. Se folosește în principal încorporat în codul HTML, dar începând de la versiunea 4.3 se poate folosi și în mod „linie de comandă” (CLI), permițând crearea de aplicații independente. Este unul din cele mai importante limbaje de programare web open-source și server-side, existând versiuni disponibile pentru majoritatea web serverelor și pentru toate sistemele de operare. Conform statisticilor este instalat pe 20 de milioane de site-uri web și pe 1 milion de servere web. Este disponibil sub Licenṭa PHP ṣi FSF (Free Software Foundation) îl consideră a fi un software open source[27].

Mediul de dezvoltare folosit pentru limbajele de programare PHP, CSS, JavaScript, jQuery este PhpStorm. PhpStorm este perfect pentru lucrul cu Symfony, Drupal, WordPress, Zend Framework, Laravel, Magento, Joomla, CakePHP, Yii și alte cadre. Editorul de fapt "primește" codul și înțelege profund structura sa, susținând toate caracteristicile limbajului PHP pentru proiecte moderne și vechi. Acesta oferă cea mai bună execuție a codului, refactoring, prevenirea erorilor pe loc și multe altele.

Compatibil cu tehnologiile de ultimă oră, precum HTML5, CSS, Sass, Less, Stylus, CoffeeScript, TypeScript, Emmet și JavaScript, cu refactorizări, depanare și testarea unităților disponibile. Vedem modificările instantaneu în browser datorită aplicației Live Edit. Efectuează multe activități de rutină chiar de la IDE, datorită integrării sistemelor de control al versiunii, suport pentru implementare la distanță, baze de date / SQL, instrumente de linie de comandă, vagabon, compozitor, client REST și multe alte instrumente. PhpStorm este renumit pentru aplicația Debugger Visual cu configurație zero, oferind o perspectivă extraordinară asupra a ceea ce se întâmplă în aplicație la fiecare pas. Funcționează cu Xdebug și Zend Debugger și poate fi folosit atât la nivel local, cât și la distanță. Unitatea de testare cu PHPUnit, BDD cu integrarea Behat și profiler sunt de asemenea disponibile[28].

Înainte de a putea obține conținut din baza de date MySQL, trebuie să stabilim o conexiune la MySQL din interiorul unui script PHP. Pentru a efectua interogări de bază din MySQL este foarte ușor. Primul lucru de făcut este conectarea la baza de date. Funcția de conectare la MySQL se numește „mysqli_connect”. Această funcție returnează o resursă care este un pointer la conexiunea bazei de date, se mai numește și database handle [29].

<?php

// Informatii baza de date

$AdresaBazaDate = "localhost";

$UtilizatorBazaDate = "user-db";

$ParolaBazaDate = "pass-db";

$NumeBazaDate = "nume-db";

$con_db=mysqli_connect($AdresaBazaDate,$UtilizatorBazaDate,$ParolaBazaDate,

$NumeBazaDate)or die("Eroare C0! ".mysqli_error($conex_db));

function db($sqlq){ # $sqlq = query-ul;

global $con_db;

if( !$sql=mysqli_query($con_db,$sqlq) )

{

if($_SERVER['SERVER_NAME']=='localhost')

die ("Eroare:".mysqli_errno($sql).":".mysqli_error($sql).

"</br>Query:".$sqlq); }

else {return $sql;}}

?>

Această conectare se face într-un fișier conectare.php, ca apoi să fie inclus unde este nevoie de interogarea bazelor de date.

Tot în acest mod se crează un fișier functii.php unde vor fi implementate funcțiile necesare implementării aplicației.

Pe lângă biblioteca locală de voce realizată manual am apelat în paralel și serviciul furnizat de Google în redarea răspunsurilor prin transformarea textului în voce.

Cu ajutorul Wget am apelat serviciu google pentru a realiza transformarea. GNU Wget este un pachet software gratuit pentru recuperarea fișierelor utilizând HTTP, HTTPS și FTP, cele mai utilizate protocoale Internet. Este un instrument non-interactiv pentru linia de comandă, deci poate fi ușor apelat de la scripturi, sarcini cron, terminale fără suport pentru X-Windows etc. [30]

function wget2speek($txt,$nume_fis)

{

$link='wget-q-UMozillaO'.$dest_path.

'"http://translate.google.com/translate_tts?ie=UTF-8';

$link.="&total=1";

$link.="&idx=0";

$link.="&textlen=32";

$link.="&key=API-Key";

$link.="&client=tw-ob";

$link.="&q=".$txt;

$link.="&tl=Ro-ro\"";

exec($link);

$content = base64_url_encode(file_get_contents($dest_path));

return $content;

}

Pentru comenzi și întrebări care așteaptă un răspuns de tip definiție (Ex. Ce este masina), se interoghează cu ajutorul comenzilor curl următoarele API-uri: dexonline, wikipedia opensearch, wikipedia query.

Curl este utilizat în linii de comandă sau scripturi pentru a transfera date. De asemenea, este utilizat în mașini, televizoare, routere, imprimante, echipamente audio, telefoane mobile, tablete, playere media și este coloana vertebrală a transferului de internet pentru mii de aplicații software care afectează zilnic miliarde de oameni. Curl este software gratuit și open source și există datorită mii de colaboratori [31].

Funcțiile care fac acest procedeu sunt:

function cauta_internet2($txt) – dexonline

function cauta_internet($txt) – wikipedia query

Exemplu:

function cauta_internet0($txt) – wikipedia opensearch{

if ($txt=='') return '';

$link="https://ro.wikipedia.org/w/api.php?action=opensearch";

$link.="&search=".rawurlencode($txt);

$link.="&format=json";

$header[] =""; //echo $link."<hr>";;

$ch=curl_init($link);

curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla');

curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

curl_setopt($ch, CURLOPT_REFERER, '-');

curl_setopt($ch, CURLOPT_ENCODING, 'deflate,gzip');

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_HEADER, 0);

curl_setopt($ch, CURLOPT_NOBODY, 0);

$original= curl_exec($ch); // ii deja base64 din wget2speek

curl_close($ch); unset($ch,$header);

$arr_wiki=json_decode($original,true);

$rasp='';

if (isset($arr_wiki[1])){

if (count($arr_wiki[1])>0){

$fraza='';

foreach($arr_wiki[1] as $key => $val)

{

if ($arr_wiki[2][$key]!='' and $val!='')

{

$fraza=$arr_wiki[2][$key];

break;

}

}

$fraza=str_replace(array('(',')'),array('<aaa>','</aaa>'),$fraza);

$fraza=caut_5($fraza, '<aaa>');

$fraza=caut_1($fraza); //echo $fraza."<hr>";

$fraza=caut_2($fraza,'.');

if (strlen($fraza)>150) $fraza=caut_2($fraza,",");

if (strlen($fraza)>150) $fraza=caut_2($fraza,".");

$rasp=strip_tags($fraza);

}

}

return $rasp;}

Pentru a formata răspunsurile recepționate de la API-uri am creat niște funcții ajutătoare pentru a înlătura datele care nu sunt necesare.

function caut_1($txt) – elimi parantezele drepte [[ txt1| txt2]] și lasa doar txt2

function caut_2($txt) – scurtam fraza la ultima virgulă

function caut_3($txt) – elim parantezele acoladă {{ txt1| txt2}} și le șterge{

$ok = 0;

do {

$pos1 = strpos($txt, "{{", 0);

if ($pos1 !== false) {

$pos2 = strpos($txt, "}}", $pos1);

$șir = substr($txt, $pos1, ($pos2 – $pos1 + 2));

$txt = str_replace($șir, '', $txt);}

else $ok = 1;

} while ($ok == 0);

return $txt;

}

function caut_4($txt) – scoatem cuvintele prescurtate de gen s. f. n.

function caut_5($txt) – scoatem <abbr…..</abbr>

function caut_5($txt) – scoatem <b>…</b>

Pentru trimiterea și primirea datelor encode/decoded base64 am creat funcțiile:

function base64_url_encode($input)

function base64_url_decode($input)

Aceste funcții prezentate mai sus ne vor ajuta în procesare și transmiterea răspunsului înapoi către aplicația SKY.

După primirea parametrilor în format JSON encode base64 se aplică o metodă de securitate pentru evitarea atacurilor de tip SQL Injection în fișierul caut_answ_c.php. Se verifică tipul de date ce trebuie returnat (text sau audio), înlăturarea spațiilor de la începutul și sfârșitul textului.

$tip_răspuns=$_GET['qt'];

$intrebare=base64_url_decode($_GET['q']); if (isset($_GET['test'])) {$intrebare=$_GET['q'];};

$id_user=$_GET['qu'];

if ($tip_răspuns!='audio' and $tip_răspuns!='text') {echo "Eroare CA_c001"; exit();}

$intrebare=strtoupper(trim($intrebare));

$intrebare=str_replace(array(" ",'?',"%",'\\','SELECT ','CONNECT ')," ",$intrebare);

$intrebare=html2diac(diac5($intrebare)); $intrebare=strtoupper(trim($intrebare));

$rasp='';

După ce parametrul primit a fost formatat, se încep căutările în baza de date pentru a transmite un răspuns.

$q0="select c.*

from answ a, answ2rasp b, rasp c

where answ='".$intrebare."' and a.id_answ=b.id_answ

and b.id_rasp=c.id_rasp";

$q=db($q0);

$nr_bd=mysqli_num_rows($q);

Se incearcă căutarea răspunsului direct:

if ($nr_bd>0){

$arr_mp3=array();

while ($r=mysqli_fetch_assoc($q)){

if ($tip_răspuns=='audio'){

$arr_mp3[]=array('mp3'=>$r['mp3'],'id_rasp'=>$r['id_rasp']);}

elseif ($tip_răspuns=='text') {

$arr_mp3[]=array('mp3'=>html2diac(diac5($r['rasp'])),'id_rasp'=>$r['id_rasp']);}

}

$rand0= rand(0,($nr_bd-1));-Dacă sunt mai multe se alege aleator

$rasp=$arr_mp3[$rand0]['mp3'];-se prea fișierul audio

$id_rasp=$arr_mp3[$rand0]['id_rasp'];

}

În cazul în care răspunsul nu se află în tabelele apelate se încercă căutarea după cuvânt:

else{

unset($q0,$q,$r);

$cale=str_replace('caut_answ.php','',pag_curenta('1'));

$arr_cuv=explode(" ",$intrebare); $șir_cuv=''; $arr_a2cuv=array();

foreach($arr_cuv as $key =>$val) {

if ($val!='' and strlen($val)>2){

$șir_cuv.='"'.$val.'",';}}

unset($arr_cuv,$key,$val);

//……………………………….

if ($șir_cuv!=''){

$qc0="select * from

(select b.id_rasp, CAST(concat(count(b.id_rasp),sum(a.id_rang)) AS SIGNED INTEGER) as rank,rasp, GROUP_CONCAT(distinct concat(cuvânt,'^',a.id_cuvânt) SEPARATOR '|') as gr_cuv,mp3 from cuv a, cuv2rasp b , rasp c

where cuvânt în (".substr($șir_cuv,0,-1).")

and id_rang>=2 and a.id_cuvânt=b.id_cuvânt and b.id_rasp=c.id_rasp

GROUP BY b.id_rasp) x

order by rank desc";

$qc=db($qc0); $nr_bd=mysqli_num_rows($qc);

if ($nr_bd>0){

$rank=0; $arr_mp3=array();

while ($rc=mysqli_fetch_assoc($qc)){

if ($rank==0) $rank=$rc['rank'];

if ($rank==$rc['rank']){

if ($tip_răspuns=='audio') {

$arr_mp3[]=array('mp3'=>$rc['mp3'],'id_rasp'=>$rc['id_rasp']);}

elseif ($tip_răspuns=='text'){

$arr_mp3[]=array('mp3'=>html2diac(diac5($rc['rasp'])),'id_rasp'=>$rc['id_rasp']);}

}

}

$rand0= rand(0,($nr_bd-1)); //echo $rand0;

$rasp=$arr_mp3[$rand0]['mp3'];

$id_rasp=$arr_mp3[$rand0]['id_rasp'];

}

} unset($q0,$q,$r);

}

Dacă cerere este de tip definiție se cauta în acest fel și se memorează răspunsul, în acest fel aplicația noastră învață singură.:

$aux_intrebare=$intrebare;

$xintrebare=strtolower(trim($intrebare));

if ($rasp=='' and (substr($xintrebare,0,7)=='ce este' or substr($xintrebare,0,7)=='ce sunt')){

$intrebare=str_replace(array("ce este",'ce sunt'),"",strtolower($intrebare));

$rasp_internet=-1;

$rasp_internet=cauta_internet2($intrebare);//wiki cuv 2

do { sleep(0.5);} while ($rasp_internet==-1) ;

if ($rasp_internet=='')

$rasp_internet=cauta_internet($intrebare);//dex

do { sleep(0.5);} while ($rasp_internet==-1) ;

if ($rasp_internet=='')

$rasp_internet=cauta_internet0($intrebare);//wiki search 0

if ($rasp_internet!='') {

$este_inclusa=1;

$intrebare=$aux_intrebare;

$răspuns=$rasp_internet;

require('intro_rasp.php'); //$id_rasp vine din intro_rasp.php

if ($mp3!='') $rasp=$mp3;

if ($tip_răspuns=='audio' and $mp3!='') $rasp=$mp3;

elseif ($tip_răspuns=='text') $rasp=html2diac(diac5($răspuns));

unset($răspuns);

}

}

La apelarea intro_rasp.php se verifică dacă întrebarea mai există în sistem.

$id_answ=0; $exista_intreb=0;

$q0="select a.* from answ a where answ='".$intrebare."'";

$q=db($q0);

if (mysqli_num_rows($q)>0){

$r=mysqli_fetch_assoc($q);

$id_answ=$r['id_answ'];

$exista_intreb=1;}

else{

db("insert into answ (answ) values ('".$intrebare."')");

$id_answ=mysqli_insert_id($con_db);}

unset($q0,$q,$r);

Se verifică dacă răspunsul mai există în sistem.

$id_rasp=0; $exista_rasp=0;

$q0="select a.* from rasp a where rasp='".$răspuns."'";

$q=db($q0);

if (mysqli_num_rows($q)>0){

$r=mysqli_fetch_assoc($q);

$id_rasp=$r['id_rasp'];

$exista_rasp=1;}

else{

db("insert into rasp (rasp) values ('".$răspuns."')");

$id_rasp=mysqli_insert_id($con_db);

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')

$mp3=win2speek($răspuns,'r'.$id_rasp);

elseif (strtoupper(substr(PHP_OS, 0, 3)) === 'LIN')

$mp3=wget2speek($răspuns,'r'.$id_rasp);

sleep(1);

db("update rasp set mp3='".$mp3."' where id_rasp=".$id_rasp);}

unset($q0,$q,$r);

Dacă nu exista se introduce în baza de date:

if ($exista_rasp==0 or $exista_intreb==0){

db("insert into answ2rasp (id_answ,id_rasp) values

('".$id_answ."','".$id_rasp."')");}

Asociem cuvintele din întrebarea nouă cu răspunsul vechi sau din întrebarea veche cu răspunsul nou și memorăm cuvintele din răspunsul nou.

if ($exista_intreb==0 or $exista_intreb==0){

$șir_cuv=''; $arr_a2cuv=array();

foreach($arr_acuv as $key =>$val) {

if ($val!='') {

$șir_cuv.='"'.$val.'",';

$arr_a2cuv[$val]=0;}}

unset($arr_acuv,$key,$val);

$q=db("select id_cuvânt,cuvânt from cuv where cuvânt în (".substr($șir_cuv,0,-1).")");

if (mysqli_num_rows($q)>0){

while($r=mysqli_fetch_assoc($q)){

if(isset($arr_a2cuv[$r['cuvânt']])) $arr_a2cuv[$r['cuvânt']]=$r['id_cuvânt'];}}

unset($q,$r,$șir_cuv);

foreach($arr_a2cuv as $cuvânt => $id_cuvânt){

if ($exista_rasp==0 and $id_cuvânt>0){

db("insert into cuv2rasp (id_cuvânt,id_rasp) values ('".$id_cuvânt."','".$id_rasp."')"); }

if ($id_cuvânt==0){

db("insert into cuv (id_rang,cuvânt,lung) values ('2','".$cuvânt."','".strlen($cuvânt)."')");

$id_cuvânt=mysqli_insert_id($con_db);

db("insert into cuv2rasp (id_cuvânt,id_rasp) values ('".$id_cuvânt."','".$id_rasp."')"); }}

db("update cuv set id_rang=1 where lung<3 and id_rang=2");} unset($arr_a2cuv,$cuvânt,$id_cuvânt,$șir_cuv);

În cazul în care nu este gasit nici un răspuns se apeleaza arh_rasp_prestabilit.php din caut_answ_c.php pentru a da unul din răspunsurile aferente acestei situații.

if ($rasp=='')

{

$rasp='nu stiu';

require("arh_rasp_prestabilite.php");

$rand0=rand(0,(count($nu_stiu)-1));

$răspuns=array();

if ($tip_răspuns=='audio') {$răspuns['a'][]=$nu_stiu['b'][$rand0]; $răspuns['v'][3]='base64';}

elseif ($tip_răspuns=='text') {$răspuns['a'][]=$nu_stiu['t'][$rand0]; $răspuns['v'][3]='text';}

}

Datele sunt reținute în arh_rasp_prestabilit.php în 2 moduri: text și base64-audio:

$nu_stiu=array();

$nu_stiu['t'][0]='nu stiu';

$nu_stiu['b'][0]="__NAxAAS4N……base64Encode

Dacă de la aplicația SKY vine comanda „repeta” sau „nu inteleg”, se va reda încă o dată ultimul răspuns. Pentru acest lucru avem nevoie de fișierul repeta.php care va fi inclus în caut_answ_c.php – require('repeta.php'). în cazul în care timp de 10 minute nu primește această comandă va transmite răspunsul „care intrebare” sau „repeta întrebarea” răspunsuri gasite în cele prestabilite discutate mai sus.

$sec_valabila_ultima=60*10; // 60*10=10min

$care_intrebare=0;

if (in_array($intrebare,$arr_repeta)){

$roq0="select * from rasp a,

(select id_rasp as max_rasp, data_arh from arh_rasp a where id_user=".$id_user." order by id_arh desc limit 0,1) b

where a.id_rasp=b.max_rasp and UNIX_TIMESTAMP(b.data_arh)>".(time()-$sec_valabila_ultima)."";

$row0=db($roq0);

if (mysqli_num_rows($row0)>0){

$row=mysqli_fetch_assoc($row0);

$răspuns=array();

if ($tip_răspuns=='audio') {$răspuns['a'][]=$row['mp3']; $răspuns['v'][3]='base64';}

elseif ($tip_răspuns=='text') {$răspuns['a'][]=html2diac(diac5($row['rasp'])); $răspuns['v'][3]='text';}

echo json_encode($răspuns,JSON_FORCE_OBJECT);

db("INSERT INTO arh_rasp (id_rasp, data_arh, id_user) VALUES ('".$row['id_rasp']."', '".date('Y-m-d H:i:s')."', '".$id_user."')");

exit();}

else{

$rasp='care intrebare';

require("arh_rasp_prestabilite.php");

$rand0=rand(0,(count($repeta)-1));

$răspuns=array();

if ($tip_răspuns=='audio') {$răspuns['a'][]=$repeta['b'][$rand0]; $răspuns['v'][3]='base64';}

elseif ($tip_răspuns=='text') {$răspuns['a'][]=$repeta['t'][$rand0]; $răspuns['v'][3]='text';}

echo json_encode($răspuns,JSON_FORCE_OBJECT);

exit();}}

II.5. Modulul de antrenare – web

Acest modul are rolul de a antrena Sistemul de Cunoștințe Inteligent pentru a acoperii din ce în ce mai multe posibile întrebări sau comenzi primite de la utilizatori.

Interfața este una simplu de utilizat care pune la dispoziție antrenorilor bazei de cunoștințe uneltele necesare antrenării.

II.5.1. Autentificare modul antrenare web

Pagina web www.sky.5b.ro (figura nr. 2.5) destinată antrenării bazei de cunoștințe a sistemului pus în discuție pune la dispoziție antrenorului inserarea de posibile întrebări, împreună cu răspunsurile posibile a acestor intebări și totodată ștergerea unor răspunsuri în caz că nu ni le mai dorim să facă parte din vocabularul sistemului.

În cazul în care întrebările introduse returnează răspunsuri posibile fară ca înainte să se fi introdus vreunul, atunci înseamnă că sistemul a găsit cuvintele din întrebarea dvs. și în altele puse anterior care posedă un răspuns. Acestea sunt redate în ordinea rangurilor cuvintelor.

Se poate modifica rangul cuvintelor în funcție de importanța lor.

După cum se poate observa în (figura nr. 2.5) este folosit protocolul de transfer HTTPS din motive de securitate a datelor.

Secure Hyper Text Transfer Protocol (HyperText Transfer Protocol/Secure, HTTPS) este un protocol de comunicație destinat transferului de informație criptată prin intermediul World Wide Web. A fost dezvoltat din necesitatea de a proteja de intruși transferul datelor prin HTTP – un protocol ,,clear-text”, prin care datele de pe server-ul web sunt transmise browser-ului client în clar, posibilitățile de a intercepta acest transfer constituind tot atâtea posibilități de a accesa și utiliza fără restricții informațiile respective. HTTPS nu este altceva decât HTTP ,,încapsulat” cu ajutorul unui flux SSL/TLS – datele sunt criptate la server înainte de a fi trimise clientului, astfel încât simpla interceptare a acestora pe traseu să nu mai fie suficientă pentru a avea acces la informații. HTTPS este în același timp o metodă de autentificare a server-ului web care îl folosește, prin intermediul așa-numitelor ,,certificate digitale” – o colecție de date pe care un browser o solicită server-ului pentru a putea începe transferul criptat; dacă certificatul este emis de o autoritate cunoscută (de exemplu VeriSign, Comodo), browser-ul poate fi sigur că server-ul cu care comunică este ceea ce pretinde a fi.[32]

Pentru ca acest lucru să fie realizat a fost nevoie să achiziționez un certificat digital SSL de la o autoritate în domeniu, Comodo. Certificatele Secure Sockets Layer (SSL), uneori numite certificate digitale, sunt folosite pentru a stabili o conexiune criptată între un browser sau computerul unui utilizator și un server sau un site Web. Conexiunea SSL protejează datele sensibile, cum ar fi informațiile despre cărțile de credit, schimbate în timpul fiecărei vizite, numită sesiune, de a fi interceptate de părți neautorizate.

Invizibil pentru utilizatorul final, un proces numit ,,handshake SSL” creează o conexiune securizată între un server web și un browser. Trei chei sunt folosite pentru a crea o cheie de sesiune simetrică, care este apoi utilizată pentru a cripta toate datele în tranzit (figura nr. 2.6).

Serverul trimite o copie a cheii publice asimetrice în browser.

Browserul creează o cheie de sesiune simetrică și o criptează cu cheia publică asimetrică a serverului, apoi o trimite pe server.
Serverul decriptează cheia de sesiune criptată utilizând cheia privată asimetrică pentru a obține cheia de sesiune simetrică.

Serverul și browserul criptează acum și decodifică toate datele transmise prin cheia de sesiune simetrică. Acest lucru permite un canal securizat deoarece numai browserul și serverul cunosc cheia de sesiune simetrică, iar cheia de sesiune este utilizată numai pentru acea sesiune specifică. Dacă browserul urma să se conecteze la același server a două zi, s-ar crea o nouă cheie de sesiune[33],[34].

La apelarea în browser a pagini https://sky.5b.ro se apelează prima data fișierul „index.php” care returnează pagina de autentificare(figura nr. 2.7). Această pagină returnează pe lângă obișnuitele input-uri Utilizator, Parolă, butonul de Login și un input ascuns (hidden) care conține un cod de autentificare unic pentru sesiunea de lucru proaspăt deschisă de browser, acest cod este generat cu ajutorul funcțiiei PHP: function cod_acces($str,$nr=0) unde $str este id-ul sesiunii PHP deschis de server (PHPSESSID), iar $nr este id-ul unic de identificare a utilizatorului. La apăsarea butonului de „Login”, aplicația prin intermediul jquery apelează funcția :$( ".container_parole #intra0" ).click(function() {} care încarcă obiectul de tip matrice (array): var matrice = {}; cu valorile din input-urile utilizator, parolă și cod, aceste fiind verificate mai întâi să nu fie goale:

if(len<4){$(this).css({"background-color":"#FFCCCC","color":"#F00 "});err=1;}, dacă au lungimea mai mică de 4 caractere variabila err este încărcată cu 1, iar la input-ul respectiv fundalul se colorează în roșu, și operația se oprește.

Daca err nu este 1, adică nu sunt erori, parola este transformată în sistem de criptare md5 matrice[id] = base64_encode($.md5(val)); care este ireversibil (nu poate fi refăcut ca să se citească parola în clar), apoi aceasta este translatată într-o reprezentare de bază 64. Am folosit aceste transformări pentru a securiza și mai mult tranferul de informații de la client la server APACHE [35].

Algoritmul MD5 este o funcție criptografică unică, care acceptă un mesaj de orice lungime ca intrare și returnează ca ieșire și o valoare cu lungime fixă care trebuie utilizată pentru autentificarea mesajului original [36],[37].

Variabila matrice este convertită într-un string de tip JSON:

var json = JSON.stringify(matrice); pentru a putea fi trimisă către server cu o cerere de tip HTTP POST cu jquery.

$.post("sistem/init_acces.php", { id: base64_encode(json) },

function (data)

{

ascund_load_bar();

$('.container1').html(data);

});

Pe server cererea este procesată de către fișierul init_acces.php, unde prima dată este verificată existența variabilelor de tip $_POST ['id'], dacă nu există execuția se oprește și trimite către browser un răspuns de eroare, în caz contrar variabila $_POST ['id'] se decodează din JSON în matrice php (array) care conține:

$arr= Array(

[cod] => 357231132

[user0] => berealex

[parola0] => YTc5MmZjMDNlYmJiNTBkZTAzNTMyODBiNmZkOGFiOGU=

//base64_encode(md5(parola))

)

Se verifica dacă $arr['cod']!=cod_acces(session_id()), să nu fie cererea de la alt server sau din altă parte decât din pagina de autentificare SKY.

Se caută în tabela utilizatori_web, dacă există utilizatori cu datele de autentificare introduse:

"SELECT * FROM utilizatori_web WHERE username='".htmlentities($arr['user0'], ENT_QUOTES)."' AND password='".base64_decode($arr['parola0'])."'"

Dacă interogarea bazei de date returnează un articol if(mysqli_num_rows($row0)>0) atunci încărcăm într-o matrice (array) datele returnate $row = mysqli_fetch_assoc($row0) și:

se răspunde browserului că autentificarea a reușit cu succes;

încărcăm o variabila de sesiune PHP cu:

$_SESSION[$ce_appl]["timp"] = time(); // secunda în format UNIX de autentificare

$_SESSION[$ce_appl]["cod_acces"] = cod_acces(session_id(), $row['id']);

$_SESSION[$ce_appl]["id_user"] = $row['id']; // id-ul unic de utilizator

$_SESSION[$ce_appl]["admin"] = $row['id_grup']; // drepturile acestui utilizator

se redirecționează automat

setTimeout(function () { location.href = "admin/index.php" }, 2500); către pagina de antrenare SKY;

Pentru a prevenii accesarea paginilor SKY, fără a trece prin pagina de autentificare, în toate acestea se include un fișier verif_acces.php. În acest fișier se verifică existența variabilei de sesiune PHP $_SESSION[$ce_appl] cu toate cheile corespunzătoare și valide, de exemplu dacă diferența dintre time() (secunda UNIX de acum) și $_SESSION[$ce_appl]["timp"] este mai mica decât $timp_viata_link (definit în fișierul de configurare config0.php). Tot în acest fișier se verifică existența utilizatorului în baza de date ca fiind activ. În caz de eroare orice operație se oprește și se redirecționează către pagina de autentificare index.php.

II.5.2. Explicarea containerelor html

Portalul de învațare se afla în fișierul index.php, care conținte, pe langă altele, următoarele principale două containerele html care au urmatoarele clasele css:

class='tab_i', care este „<table>” și conține la rândul ei cele două input-uri:

întrebare cu id = 'answ', aici operatorul va putea scrie întrebarea cu care SKY va fi învățat ;

răspuns cu id = 'rasp', aici operatorul va putea scrie răspunsul la 'answ' și care va fi învățat de către SKY.

class=' div_r', care este „<div>” și unde se vor încărca raspunsurile deja existente în baza de date la întrebările puse în input-ul 'answ';

În dreapta input-ului 'answ' am pus o iconiță 'b_lupa', ,care este declanșatorul operației de căutare în baza de date a întrebării care se găsește în 'answ'.

În dreapta input-ului 'rasp' am pus o iconiță 'b_plus', ,care este declanșatorul operației de introducere în baza de date a întrebării ('answ') și răspunsului care se gasește în 'rasp'.

Pentru prevenirea ca operatorul să introducă de la tastatură caractere care pot bloca aplicația, în cele două input-uri , întrebare ('answ') și răspuns ('rasp'), am limitat posibilitatea intoducerii, doar a caracterelor alfanumerice și a caracterelor punct și spațiu, cu jquery: $('.tab_i').on("keypress", '#rasp, #answ', function (e) { return filterInput(3, e, false, ". "); });. Iar pentru prevenirea de lipire (paste) am folosit funcția următoare: $(document).on('copy paste dragstart selectstart', function (e) { if ($(".local").length <= 0) { e.preventDefault(); return false; } });

Există două tipuri de răspunsuri la întrebările scrise de operator în ('answ'), care se vor memora în baza de date:

Scris în 'rasp' direct de operator și care va aștepta intoducerea în baza de date apăsarea (click) pe 'b_plus', vezi capitolul II.5.3.

La apăsarea (click) pe 'b_lupa', se va căuta automat pe internet și dacă se primește un răspuns valid, acesta va fi memorat automat, vezi capitolul II.5.4

II.5.3. Răspunsuri date de operator

La apăsarerea (click) pe 'b_plus' se execută funcția jquery

$('.tab_q .b_plus').on('click',function(data) {… });

Obligatoriu cele două input-uri , întrebare ('answ') și răspuns ('rasp'), trebuie să nu fie nule

if ($.trim($('#answ').val()).length<=0) return false;

if ($.trim($('#rasp').val()).length<=0) return false;

Prin funția arat_load_bar(); se ascund toate containerele în afara de div-ul 'brain', la care se modifică opacitatea de la 0,4 la 1: $(".brain").animate({ opacity: '0.4' }, 'slow'); creând efectul de iluminare mai puternică a imaginii de fundal, a creierului virtual, totodată arătând că aplicația procesează informațiile.

Se trimite către serverul Apache un „request” cu valorile din întrebare ('answ') și răspuns ('rasp'), în mod POST, apelându-se pagina intro_rasp.php,

$.post("intro_rasp.php", {a:$('#answ').val(),r:$('#rasp').val()} ,function(data) {..});Datorită faptului că operatorii pot scrie în cele două input-uri cu caractere mici dar și mari, pe server în fișierul intro_rasp.php, pentru uniformizare, se transformă textul primit din întrebare și raspuns în text cu litere mici.

Se iau cele două texte si se sparg în cuvinte, acestea fiind memorate în matrice (array) :

$arr_rcuv = explode(" ", $raspuns); //matrice pentru cuvintele din răspuns;

$arr_acuv = explode(" ", $intrebare); //matrice pentru cuvintele din întrebare;

Se verifică în tabela answ dacă mai există întrebarea cerută

$q0 = "select a.* from answ a where answ='" .$intrebare. "'";

Dacă mai există if (mysqli_num_rows($q) > 0) atunci în variabila $id_answ = $r['id_answ']; încărcăm id-ul unic al întrebării din tabelă, dacă nu există, inserăm un nou articol în tabela answ și memorăm în variabila $id_answ = mysqli_insert_id($con_db); id-ul unic al întrebării nou introduse în tabelă.

Identic se verifică în tabela rasp dacă mai există răspunsul cerut $q0="select a.* from rasp a where rasp='".$raspuns."'"; atunci în variabila $id_rasp = $r['id_rasp']; încărcăm id-ul unic al răspunsului din tabelă, dacă nu există, inserăm un nou articol în tabela rasp și memorăm în variabila $id_rasp =mysqli_insert_id($con_db); id-ul unic al răspunsului nou introdus în tabelă. Dar suplimentar pentru răspuns, trebuie memorat în tabela rasp și răspunsul în format audio. Transformarea în format audio este realizat cu funcțiile $mp3 = win2speek($raspuns, 'r'.$id_rasp); dacă serverul web este pe un sistem de operare Windows sau $mp3 = wget2speek($raspuns, 'r'.$id_rasp); dacă serverul web este pe un sistem de operare Linux. Aceste funcții sunt explicate în capitolul II.4.

Dacă întrebarea și/sau răspunsul sunt nou introduse în baza de date id-urile lor sunt introduse in tabela answ2rasp care face legătura între întrebări și răspunsuri db("insert into answ2rasp (id_answ,id_rasp) values ('".$id_answ."','".$id_rasp."')");

Următorul pas este asocierea cuvintelor din întrebare cu răspunsul, acest pas se execută doar în cazul în care întrebarea și/sau răspunsul sunt nou introduse în baza de date, altfel se consideră că aceastea au mai fost asociate odată.

Toate cuvintele din întrebare fiind deja într-o matrice(array) $arr_acuv sunt introduse într-o nouă matrice $arr_a2cuv unde cheia matricei este cuvîntul iar valoarea este setată la 0,

Tabela cuv , conține toate cuvintele din toate întrebările aplicației, fiecare cuvânt având un id propriu (id_cuvant). Se verifică în tabela cuv dacă cuvintele din întrebare există deja $arr_a2cuv $q=db("select id_cuvant,cuvant from cuv where cuvant in (".substr($sir_cuv,0,-1).")"); dacă exista în matricea $arr_a2cuv, în loc de 0 la cheia cu cuvântul gasit se modifică id_ul cuvântului, astfel încât în matrice ($arr_a2cuv) toate cheile cu cuvintele negasite în tabela cuv vor avea valoarea 0. Se parcurge matricea ($arr_a2cuv) foreach($arr_a2cuv as $cuvant => $id_cuvant) și se disting două cazuri:

Cazul 1. Răspunsul este nou și cuvântul este în bază if ($exista_rasp==0 and $id_cuvant>0) atunci se introduce id-ul de cuvânt și id-ul de răspuns doar în tabela cuv2rasp, db("insert into cuv2rasp (id_cuvant,id_rasp) values ('".$id_cuvant."','".$id_rasp."')");, tabelă care este legătura între id_urile cuvintelor din întrebări și id-urile răspunsurilor aferente.

Cazul 2. Cuvântul nu a mai fost memorat if ($id_cuvant == 0), adică valoarea lui din matrice este 0. Trebuie mai întâi introdus în tabela cuv , apoi să îi memorăm id-ul de cuvânt pentru introducere și în tabela cuv2rasp ca și la cazul 1.

În tabela cuv, există un câmp numit id_rang care definește importanța fiecărui cuvănt, cu cât crește rangul cu atăt este mai important cuvântul. La introducere toate cuvintele au rangul 2 cu excepția celor care au lungime mai mica de trei caractere la care se schimba rangul în 1,

db("update cuv set id_rang=1 where lung<3 and id_rang=2");considerându-se că nu sunt importante. Acest rang se poate schimba prin aplicația web, vezi capitolul II.5.5.

II.5.4. Răspunsuri căutate pe internet.

La apăsarerea (click) pe 'b_lupa' se execută funcția jquery

$('.tab_a .b_lupa').on('click',function(data)

Obligatoriu input-ul, întrebare ('answ') trebuie să nu fie nul

if ($.trim($('#answ').val()).length<=0) return false;

Prin funcția arat_load_bar(); se ascund toate containerele în afară de div-ul 'brain' la care se modifică opacitatea de la 0,4 la 1: $(".brain").animate({ opacity: '0.4' }, 'slow'); creând efectul de iluminare mai puternică a imaginii de fundal, a creierului virtual, totodată arătând că aplicația procesează informațiile.

Se trimite către serverul apache un „request” cu valorile din întrebare ('answ'), în mod POST, apelându-se pagina caut_answ.php, $.post("caut_answ.php", {id:$('#answ').val()} ,function(data) {..});

Această pagină poate returna trei tipuri de răspuns:

Primele 6 caractere din răspuns sunt „Eroare”, funcția jquery myalert() pune pe ecran eroarea myalert(data, 'Aten&#355;ie');

Primele 4 caractere din răspuns sunt „memo”, s-a găsit pe internet un răspuns la întrebare ('answ'), nu există memorat în baza de date. Răspunsul este decodat din baza 64 var rasp_de_caut = base64_url_decode(d['1']); și este introdus în input-ul răspuns ('rasp') $('#rasp').val(rasp_de_caut);, se pornește un timer care la final declanșează memorarea răspunsului la întrebare ca și cum ar fi scris de operator, explicat în capitolul II.5.3.

Când nu sunt condițiile de pa pct.1 și nici pct.2. , răspunsul a fost găsit în baza de date și este introdus în containerul ('div_r') :

$('.principal .div_r').html(data);.

Pe server în fișierul intro_rasp.php, pentru uniformizare, se transformă textul primit din întrebare în text cu litere mici :

$intrebare = strtolower(trim($_POST['id'])); și se înlocuiesc caracterele și/sau textele care pot fi folosite pentru atacuri de tip SQLInjection $intrebare=str_replace(array(" ",'?',"%",'\\','select ','connect ')," ",$intrebare);.

Se caută în baza de date întrebarea :

$q0="select c.* from answ a, answ2rasp b, rasp c where answ='".$intrebare."' and a.id_answ=b.id_answ and b.id_rasp=c.id_rasp";

Funcție ce returnează interogarea bazei de date de mai sus, exista patru posibilități:

Dacă interogarea bazei de date returnează un articol, se trimite către browser un tabel „<table>” formatat pentru vizualizarea în text a răspunsului la întrebare, un modul de ascultare audio <audio controls="controls"><source src="'.$cale.'to_mp3.php?id='.$r['id_rasp'].'" type="audio/mpeg" /></audio> precum un buton de ștergere a răspunsului <div title="Stegere raspuns" aux="'.$r['id_rasp'].'" class="tab_ico b_del"></div> .

În cazul în care interogarea bazei de date nu returnează nici un articol, se caută ce răspunsuri sunt legate de fiecare cuvânt din întrebare: $qc0="select * from (select b.id_rasp, CAST(concat(count(b.id_rasp),sum(a.id_rang)) AS SIGNED INTEGER) as rank,rasp, GROUP_CONCAT(distinct concat(cuvant,'^',a.id_cuvant) SEPARATOR '|') as gr_cuv from cuv a, cuv2rasp b , rasp c where cuvant in (".substr($sir_cuv,0,-1).") and id_rang>=2 and a.id_cuvant=b.id_cuvant and b.id_rasp=c.id_raspGROUP BY b.id_rasp) x order by rank desc";

Se observă că dacă un cuvânt din întrebare este folosit la mai multe întrebări anterioare count(b.id_rasp), acesta este cu atât mai important, cu cât are id_rang mai mare sum(a.id_rang)) importanța cuvântului crește, și răspunsul aferent (prin tabela cuv2rasp) este în față. Ca și în cazul precedent se trimite către browser un tabel la fel formatat, dar cuprinzând unul sau mai multe răspunsuri, cele mai importante (rank mai mare) fiind primele.

Dacă interogarea bazei de date nu returnează nici un articol dar întrebarea conține textul „ce este” sau „ce sunt”, cu ajutorul funțiilor :

$rasp_internet = cauta_internet2($intrebare);

$rasp_internet = cauta_internet($intrebare);

$rasp_internet = cauta_internet0($intrebare) (vezi cap.II.4.)

Răspunsul este căutat pe internet, și este trimis către browser un text care conține sintagma „memo|” la care este concatenat răspunsul efectiv, transformat în baza64 $rasp='memo|'.base64_url_encode($rasp_internet);.

Există și posibilitatea ca și după cele trei cazuri anterioare raspunsul să rămână nul, se trimite la browser un răspuns simplu „nu stiu” if ($rasp=='') $rasp='nu stiu';.

II.5.5. Gestionarea importanței cuvintelor din întrebări.

Pentru a putea modifica rangul unui cuvănt din întrebare se face click pe cuvântul dorit din paranteză, colorat cu galben. Tag-ul respectiv este de tip </span> și a fost creat în pagina caut_answ.php, conține un atribut „aux” care este de fapt câmpul id_cuvant din tabela cuv și reprezintă identificatorul unic al cuvântului.

La apăsarea (click) pe cuvănt se declanșează funcția $('.div_r').on('click','td>span', function(data) { … }); care ia atributul „aux” și îl trimite cu POST către pagina clasare_cuv.php, care afișează pe ecran formularul din fig. următoare.

La apăsarea (click) pe butonul echo "<input class='buton b_ok' style='' readonly='' value='Memoreaz&#259;' onclick='memo_rang(\"".$id_cuv."\")'>";

se execută funcția javascript memo_rang() care retrimite către clasare_cuv.php, cu variabilele POST: $_POST['id'] care este identificatorul unic al cuvântului, și $_POST['r'] care este valoarea modificată a „slider-ului” (rang-ului). Cu ajutorul acestor variabile se face modificarea și în tabela cuv $db("update cuv set id_rang='".$id_rang."' where id_cuvant=".$id_cuv);.

Mai jos este reprezentată schema bloc a tuturor modulelor Sistemului de Cunostințe Inteligent împreună cu interconexiunile dintre acestea.

Capitolul III. Manual de utilizare

III.1. Utilizare aplicație SKY

Considerând că sistemul este conform descrierilor hardware menționate și aplicația este instalată pe computerul dvs., utilizarea aplicației SKY se face în 7 pași simpli.

Pasul 1: Pornire aplicație SKY(figura nr. 2.1).

Pasul 2:Instalare aplicație Intel Remote Keyboard atât pe smartphone cât și pe computerul dumneavostră.

Pasul 3: Asigurati-vă că aveți o conexiune bună la internet și cele două device-uri se află în aceeași rețea locală.

Pasul 4: Sincronizați aplicația de pe smartphone cu cea de pe computer.

Pasul 5: Poziționați cursorul în aplicația SKY (figura nr.2.1; pct. 1)

Pasul 6: Setați aplicația de pe smartphone pe keyboard speach to text(figura nr. 3.1).

Pasul 7: Incepeți să transmiteți comezi sau întebări vocale Sistemului de Cunoștințe Inteligent.

Exemplu:

User(voce): data de azi

SKY(voce): 22 iunie 2017

User(voce): numele meu este alex

SKY(voce): incantat de cunostinta alex -(si recunoaștere facială cu numele alex)

User(voce): cine sunt eu

SKY(voce): alex(cunoscut) -nu stiu(necunoscut)

User(voce): ce este inteligenta

SKY(voce): inteligența este facultatea de a descoperi proprietățile obiectelor și fenomenelor înconjurătoare, cât și a relațiilor dintre acestea

III.2. Utilizare interfața utilizator web pentru antrenare

Pentru a accesa modulul de antrenare web este nevoie să tastați în bara de search a unui browser web: sky.5b.ro.

Pentru a vă loga la acest modul este nevoie să fiți desemnat de un administrator ca antrenor pentru aplicația SKY. Acesta procedură a fost introdusă din motive de securitate și pentru a selecta cu grijă antrenorii. Pentru a a deveni antrenor este nevoie să trimiteți un CV împreună cu motivația dorinței de a face parte din echipă, la adresa de mail a unui administrator.

Mesajul de acceptare a contului dumneavostră de către aplicația SKY(figura nr. 3.3).

În cele ce urmează vom vorbi despre utilizarea aplicației din punctul de vedere a unui administrator pentru a vedea toate funcționalitățile disponibile.

După autentificare va aparea o pagină (figura nr. 3.4) în care vom putea introduce întrebări, răspunsuri și șterge răspunsuri împreună cu meniul de „Setări” unde vom putea introduce, șterge și modifica antrenori(doar administratorii au acces aici), butonul de Ieșire și numele utilizatorului se află de asememenea în meniu.

Înainte de a prezenta utilizarea modului de învățare propriu zis în figurile nr. 3.5, 3.6, 3.7, 3.8 se pot observa funcționalitățile meniului „Setări”.

În cazul nesatisfacerii cerințelor din formularul de ,,Înregistrare utilizator nou” vor aparea atenționări(figura nr 3.6).

După alegerea utilizatorului va apărea din nou un formular de tipul celui din figura nr. 3.6, dar completat cu datele utilizatorului care vor fi modificate.

Se alege utilizatorul și se confirmă ștergerea lui.

Pentru a începe antrenarea sistemului trebuie introdusă întrebarea la care dorim răspuns și accesarea cu un click icoana reprezentată de lupa (figura nr. 3.9).

După procesarea comenzii se pot returna două tipuri de afisaj, cel în care sistem a găsit răspunsuri(figura nr. 3.10) și cel în care nu a găsit răspunsuri(figura nr. 3.11)

În întrebărilor de tip definiție: ce este …, întotdeauna va gasi un răspuns.

Pentru introducerea unui răspuns la o anumită întrebare se completează în cadrul formularului campul ,,Răpuns nou’’ (figura nr. 3.10) și se apasă click pe icoana în formă de plus, verde. După aceea la introducerea din nou a întrebării, acel răspuns va fi în lista de răspunsuri aferente.

Dacă se dorește ștergerea unui răspuns se apasă click pe icoana în formă de x roșie de la finalul răspunsului (figura nr. 3.10).

Se poate reda cu ajutorul media player-ului răspunsul audio, setarea volumului și download fișier audio (figura nr. 3.10).

În cazul în care întrebarea introdusă nu are un răspuns asociat dar în conținutul întrebării există cuvinte care se regăsesc în alte întrebări sistemul redă răspunsurile asociate acelor întrebări pe baza rangului fiecărui cuvânt găsit (figura nr. 3.12).

Pentru a modifica rangul cuvintelor asociate cu culoare galbenă se apasă click pe unul dintre cuvinte(figura nr. 3.13)

Cu cât rangul este mai mare cu atât cuvântul este mai important și răspunsul devine automat unul dintre cele preferate.

Pentru ieșirea din aplicație se apasă click pe Ieșire din meniul stânga sus (figura nr. 3.4).

Capitolul IV. Concluzii

Sistemul de Cunoștințe Inteligent până în punctul acesta este capabil să înțeleagă și să preceseze informațiile redate verbal de către un utilizator. După procesarea informațiilor primite returnează un răspuns audio pe baza cunoștințelor antrenate și a bazei de date audio.

Cu ajutorul modulelor de învățare atât facial cât și informațional, sistemul asimilează diferite scenarii întrebare-răspuns și în cazul în care nu posedă răspunsul încercă pe baza cunoștințelor deja asimilate să dea un răspuns, iar în cazul întrebărilor de tip definiție sistemul caută pe diferite site-uri răspunsul memorându-l.

Aplicația pusă în discuție reprezintă un pionerat în domeniul inteligenței artificiale și dorește extinderea spre cât mai multe domenii și aplicații care să faciliteze crearea unei mașini de sine stătătoare raționale. Cu cât baza de date a Sistemului de Cunoștințe Inteligent este mai mare și se poate extinde cu atât cresc șansele de acoperire a diferitelor domenii.

Aplicația dorește să își marească baza de date a cuvintelor înregistrate audio pentru renunțarea la interogarea serviciilor Google Cloud Speech API.

Totodată se dorește crearea unei aplicații android și iOS dedicate pentru smarphone atât pentru recunoașterea facială prin dispozitivul mobil cât și pentru transformarea voice-to-text.

Extinderea cautării autonome pe internet a diferitelor răspunsuri renuntând poate la antrenarea manuală și totodată accesarea rețelelor de socializare, e-mail, s.a.

Minimizarea software-ului astfel încat să fie capabil să ruleze pe un Raspberry Pi, Arduino sau smartphone.

După dezvolatarea și minimizarea aplicației și introducerea nivelului de atomatizare mecanică se dorește implementarea unui corp robotic ghidat de sistemul SKY.

SKY dorește pe viitor să facă parte din casa dumneavoastră nu doar ca partener de discuție și furnizor de informații cât și în automatizarea diferitelor aparate electrocaznice ușurând unele activități de zi cu zi.

Bibliografie

[1] Bender, Edward A., Mathematical Methods în Artificial Intelligence,

IEEE Computer Society Press, Los Alamitos, CA, chapter 1, pp. 26,

1996.

[2] Haugeland, J., Ed., Artificial Intelligence: The Very Idea, MIT Press,

Cambridge, 1985.

[3] Kurzweil, R., The Age of Intelligent Machines, MIT Press, Cambridge,

1990.

[4] Rich, E. and Knight, K., Artificial Intelligence, McGraw-Hill, New

York, 1996.

[5] Newell, A .and Simon, H.A., Human Problem Solving, Prentice-Hall,

Englewood Cliffs, NJ, 1972.

[6] Konar A., Uncertainty Management în Expert Systems using Fuzzy Petri

Nets, Ph.D. thesis, Jadavpur University, Calcutta, 1994.

[7] Russel, S. and Norvig, P., Artificial Intelligence: A Modern Approach,

Prentice-Hall, Englewood Cliffs, NJ, 1995.

[8] Luger, G. F. and Stubblefield, W. A., Artificial Intelligence: Structures

and Strategies for Complex Problem Solving, Benjamin/Cummings,

Menlo Park, CA, 1993.

[9] Winston, P. H., Artificial Intelligence, Addison-Wesley, 2nd ed.,

Reading, MA, 1994.

[10] Schalkoff, J., Culberson, J., Treloar, N. and Knight, B., ,,A world

championship caliber checkers program,” Artificial Intelligence, vol. 53,

no. 2-3, pp. 273-289, 1992.

[11] Charniak, E. and McDermott, D., Introduction to Artificial Intelligence,

Addison-Wesley, Reading, MA, 1985.

[12] Buchanan, B. G. and Shortliffe, E. H., Eds., Rule-Based Expert

Systems, Addison-Wesley, Reading, MA, 1984.

[13] Shortliffe, E. H., Computer-based Medical Consultations: MYCIN,

Elsevier, New York, 1976.

[14] http://www.catia.ro/articole/ai/ai.htm- Consultat la 20.01.2017.

[15] Shobam, Y., Artificial Intelligence Techniques în PROLOG, Morgan

Kaufmann, San Mateo, CA, 1994.

[16] https://docs.microsoft.com/en-us/dotnet/csharp/csharp – Consultat la 24.01.2017.

[17] https://docs.microsoft.com/en-us/visualstudio/csharp-ide/using-the-visual-studio-development-environment-for-csharp – Consultat la 24.01.2017.

[18] http://www.json.org – Consultat la 03.02.2017.

[19] http://www.emgu.com/wiki/index.php/Main_Page – Consultat la 04.02.2017.

[20] http://eigen.tuxfamily.org/index.php?title=Main_Page – Consultat la 04.02.2017.

[21] http://docs.opencv.org/trunk/d7/d8b/tutorial_py_face_detection.html-Consultat la 05.02.2017.

[22] https://downloadcenter.intel.com/download/24967/Intel-Remote-Keyboard-Host-App- Consultat la 10.03.2017.

[23] https://cloud.google.com/speech/-Consultat la 11.03.2017.

[24] https://ro.wikipedia.org/wiki/MySQL- Consultat la 11.03.2017.

[25] https://dev.mysql.com/doc/refman/5.7/en/-Consultat la 13.03.2017.

[26] https://www.phpmyadmin.net/-Consultat la 14.03.2017.

[27] https://ro.wikipedia.org/wiki/PHP- Consultat la 14.03.2017.

[28] https://www.jetbrains.com/phpstorm/-Consultat la 15.03.2017.

[29] https://www.w3schools.com/php/php_mysql_connect.asp-Consultat la 14.03.2017.

[30] https://www.gnu.org/software/wget/- Consultat la 20.03.2017.

[31] https://curl.haxx.se/ -Consultat la 01.04.2017.

[32] https://en.wikipedia.org/wiki/HTTPS -Consultat la 09.04.2017.

[33] https://www.digicert.com/ssl-certificate/-Consultat la 13.04.2017.

[34] https://www.comodo.com/-Consultat la 15.04.2017.

[35] https://httpd.apache.org/-Consultat la 16.04.2017.

[36] http://searchsecurity.techtarget.com/definition/MD5/-Consultat la 17.04.2017.

[37] http://php.net/manual/ro/function.md5.php/-Consultat la 17.04.2017.

[38] Prof.dr.ing. Doina Zmaranda, Curs-Programarea Calculatoarelor și Limbaje de Programare III,2014.

[39] Conf.dr.ing. Mirela Pater, Curs-Elemente de Grafica pe Calculator, 2014.

[40] Prof.dr.ing. Cornelia Gyorodi, Curs-Sisteme Expert, 2016.

[41] Șef lucr.dr.inf. Octavia Bolojan, Curs-Structuri de Date, 2015.

[42] Prof.dr.ing. Ștefan Vari Kakas, Curs-Proiectare cu Microprocesoare I, 2015.

[43] Prof.dr.ing. Cornelia Gyorodi, Curs-Baze de Date I, 2015.

[44] Prof.dr.ing. Cornelia Gyorodi, Curs-Baze de Date II, 2015.

[45] Prof.dr.ing. Doina Zmaranda, Curs-Programare Orientată pe Obiecte, 2015.

[46] Prof.dr.ing. Daniela Elena Popescu, Curs- Arhitectura Sistemelor de Calcul I, 2015.

[47] Prof.dr.ing. Robert Gyorodi, Curs-Proiectarea Aplicațiilor pentru Dispozitive Mobile și Web, 2016.

[48] Șef lucr.dr.ing. Daniela Maștei, Curs-Sisteme de Intrare-Ieșire și Transmiterea Datelor, 2016.

[49] Prof.dr.ing. Ioan Mang, Curs-Tehnici de Securitate a Datelor, 2016.

[50] Șef lucr.dr.ing. Florin Vancea, Curs-Rețele de Calculatoare, 2016.

[51] Șef lucr.dr.ing. Otto Poszet, Curs-Sisteme de Achiziție și Prelucrare a Datelor, 2017.

[52] Prof.dr.ing. Robert Gyorodi, Curs-Sisteme de Recunoaștere a Formelor, 2017.

[53] Conf.dr.ing. Gianina Gabor, Curs- Proiectarea Interfețelor Utilizator, 2015.

[54] Conf.dr.ing. Gianina Gabor, Curs- Comunicații Multimedia, 2015.

ANEXE

Anexa 1. Schema bloc SKY-schiță

Anexa 2. Interfața aplicație mobile Intel Remote Keyboard

Anexa 3. Logo SKY

DECLARAȚIE DE AUTENTICITATE A

LUCRĂRII DE FINALIZARE A STUDIILOR

Titlul lucrării: Asistent personal „Sistem de Cunoștințe Inteligent” (SKY).

Autorul lucrării: Alexandru-Dumitru BERE

Lucrarea de finalizare a studiilor este elaborată în vederea susținerii examenului de finalizare a studiilor organizat de către Facultatea Inginerie Electrică și Tehnologia Informației din cadrul Universității din Oradea, sesiunea iulie a anului universitar 2016-2017.

Prin prezenta, subsemnatul Alexandru-Dumitru BERE, CNP 1931009055056, declar pe proprie răspundere că această lucrare a fost scrisă de către mine, fără nici un ajutor neautorizat și că nici o parte a lucrării nu conține aplicații sau studii de caz publicate de alți autori.

Declar, de asemenea, că în lucrare nu există idei, tabele, grafice, hărți sau alte surse folosite fără respectarea legii române și a convențiilor internaționale privind drepturile de autor.

Oradea,

Data Semnătura

Raport de Originalitate

Raport de Originalitate (Raport de Detectare a Plagiatului) pentru Proiect-de-Diploma-AlexandruDumitruBERE-AsistentPersonal-SistemDeCunostinteInteligent-SKY.docx – 3% plagiat.

Acest test a fost realizat cu ajutorul programului de detactare a plagiatului www.DetectarePlagiat.ro.

Similar Posts