Автор Тема: Умни роботи  (Прочетена 18131 пъти)

Methuselah

  • Вече знае какво е робот!
  • *****
  • Публикации: 67
    • Профил
Умни роботи
« -: Септември 07, 2007, 11:49:43 pm »
Дойде време и аз да допринеса към форума с една статийка, дано щатните автори да нямат нищо против.

С развиването на технологията, роботите изискват все по-сложни програми. До голяма степен тези програми са подобни на изкуствения интелект използван в компютърни програми и игри (особено по-старите) и се свежда до проверка на входни данни и генерирането на изходни такива. Тоест if-else statements казано на "програмен език". Целта на тази статия е да представи една алтернатива на този вид програмиране. Ще започна с обяснение на една добре позната система - мозъка, и ще завърша с полуготов код за нашите роботчета. Темата я пускам в раздел "Компютри" защото по-голямата част от програмирането се извършва на компютъра и едва в най-крайния етап ще отиде в робота.

В много статии на сайта създаването на робот се сравнява със създаването на живот. След като сме създали живот е редно да му дадем и разум, тоест мозък! Но откъде да започнем? Какво е мозъка?

Човешкият мозък (както и всички други) представлява огромно количество неврони, които са свързани и комуникират с до 10000 други неврони. Ето сравнение между човешки мозък и компютър:
Мозък Компютър
Брой елементи: 10^8 синапса 10^8 транзистора
Скорост: 100 херца от порядъка на 10^9 херца
Тип изчисляване/мислене: Паралелен, разпределен Последователен, централизиран
Толериращ грешки: Да Не

За мен лично мозъка, със способността си да се "препрограмира" и да забелязва последователности (pattern recognition) за сега е по-добър от един компютър, въпреки бавната скорост на изчисление. Как постига това мозъка? За да разберем отговора трябва да видим най-простия елемент в мозъка - неврона. Няма да ви занимавам с обяснения как работи биологическия неврон, тъй като ще се отдалеча от темата и ще трябва да ровя за превод на научни термини, които няма да срещнем никъде другаде. Ако искате може да прочетете в Wikipedia. Ще ви покажа директно опростен модел на неврон, който ще използваме:



В случая неврона работи по следния начин:
1. Взема всеки "претеглен" елемент (тоест Вход [n] * Тежест [n])
2. Събира ги
3. Ако резултата е по-голям от определно число (праг на неврона) пуска определн сигнал като Изход

Събирайки няколко такива неврона и свързвайки ги, се получава малък мозък! :D Този мозък е до определена степен по-ефективен от нормална програма. Ето един пример за едно-слойна невронна мрежа (neural network):


Еднослойна защото на практика единия слой служи само за въвеждане на данни и се слага за яснота. Засега ще се занимаваме само с такива, защото многослойните мрежи са прекалено сложни и надхвърлят нуждите ни.
Ако ви изглежда сложно - спокойно. Нормално е.
Да обясним какво става:
Невронната мрежа взима 4 входа (inputs). Първия слой само ги предава, а втория всъщност ги обработва и дава 5 изхода. За какво може да се използва ли? Да разгледаме следния робот: Line tracer с 4 сензора, 2 мотора и светодиод (примера го измислих след като начертах и качих схемата). Мрежата взима входа от сензорите. Например 0 1 1 0 ако е в центъра на линията, 0 0 1 1 ако е леко в дясно на линията и т.н. Като изход очакваме да ни каже как да завъртим моторчетата (за всяко моторче ни трябват по 2 изхода, за да определим посока на въртене) и ако робота "вижда" линията ще светне светодиода. Например в първия случай (0 1 1 0) ще очакваме изход [1 0] [1 0] 1. Въртим и двата мотора напред и светодиода свети. Във втория пък ще очакваме да завием на ляво значи може да спрем левия мотор и получаваме [0 0] [1 0] 1.

За да определим как да се държи невронната мрежа, трябва да настроим тежестите. За това си има алгоритми. Ето един за еднослойни мрежи.
Ако имаме N входа, то те са част от вектора I и се бележат I1, I2, ... In
По подобен начин изхода е вектора O - O1, O2, ... Om
Тежестите ще са матрица W с размери M x N

За да научим мрежата да разпознава комбинацията 0 1 1 0 примерно и да реагира с 1 0 1 0 1 (горния пример) трябва да умножим вектора с входове по вектора с изходи и получената матрица да добавим към W. Единствената уловка е че алгоритъма работи не с 0 и 1, а с -1 и 1. Иначе се получават неточности. Ето и какво се получава

Тъй като това е първия ни пример, то това са и началните стойности на вектора ни с тежести W. Да добавим и следващия пример 0 0 1 1 - 0 0 1 0 1


Използвам 1 и 0 само за прегледност иначе ще стане мешавица. Събираме двете матрици (този път с -1 и 1) като събираме всеки елемент от едната със съответния от другата.

-1  1  1 -1    1  1 -1 -1    0  2  0 -2
 1 -1 -1  1    1  1 -1 -1    2  0 -2  0
-1  1  1 -1 + -1 -1  1  1 = -2  0  2  0
 1 -1 -1  1    1  1 -1 -1    2  0 -2  0
-1  1  1 -1   -1 -1  1  1   -2  0  2  0


И това са ни тежестите! На практика това ни е достатъчно. Стига ни програмата която отива в робота да знае тези тежести, за да сметне резултат. А това става по следния начин. Умножаваме всеки вход със съответната тежест към съответния изход. Ще разгледам отново примера 0 1 1 0 (помнете че нулите са -1):
Изход 1 (първи ред)
-1 * 0 = 0
1 * 2 = 2
1 * 0 = 0
-1 * -2 = 2
Общо 4. Ако си спомняте горе споменах праг на неврона. Ами това е най-просто нула. Тоест ако полученото число е > 0, значи неврона пуска към изхода 1 (в изключително редки случай ще срещате алгоритми които ще променят прага на невроните. това в случай че ще се ровите и след тази статия  :D ) Сега да продължим
Изход 2 (втори ред)
-1 * 2 = -2
1 * 0 = 0
1 * -2 = -2
-1 * 0 = 0
Общо -4 => Пускаме 0 към изхода
Изход 3
-1 * -2 = 2
1 * 0 = 0
1 * 2 = 2
-1 * 0 = 0
Общо 4 => 1
Изход 4
-1 * 2 = -2
1 * 0 = 0
1 * -2 = -2
-1 * 0 = 0
Общо -4 => 0
Изход 5
-1 * -2 = 2
1 * 0 = 0
1 * 2 = 2
-1 * 0 = 0
Общо 4 => 1

От петте изхода получихме 1 0 1 0 1. А именно това бяхме въвели и в началото! Целта на цялото упражнение бе следната - да имаме алгоритъм който се справя с произволно количество входни данни и изважда от тях произволно количество изходни данни. При наличие на достатъчно много примери, робота ще започне сам да решава какво да прави дори в ситуации, които не са били зададени като примери :D. По този начин вече само трябва да решим при какви условия какво да става и да въведем данните. Тоест ние казваме какво да стане, а компютъра измисля как да стане.

Добре, сега като разяснихме основите и първия (и основен) алгоритъм за учене ще покажа и как се пренася това в код. Ако сте чели внимателно и имате поне основни познания по езика С няма да имате проблеми с кода. Разбира се ще отговарям на въпроси и ще доразвивам темата ако видя че има интерес.

Ето го и кода:
#include <iostream>
using namespace std;

#define INPUTNUM 2   //Брой на входни данни (примерно сензори)
#define OUTPUTNUM 2  //Брой изходни данни (примерно мотори)

short num[2] = {-1,1}; //Алгоритъмът не работи с 0/1, а с -1/1. така се спестяват преобразувания
void learn(bool inputs[INPUTNUM], bool outputs[OUTPUTNUM], short weights[OUTPUTNUM][INPUTNUM]);//учещата функция - виж дефиницията долу
void test (bool inputs[INPUTNUM], bool outputs[OUTPUTNUM], short weights[OUTPUTNUM][INPUTNUM]);//тестова функция - виж дефиницията долу

int main()
{
bool inputs[INPUTNUM];   //масив за входните данни
bool outputs[OUTPUTNUM]; //масив за изходните данни
short weights[OUTPUTNUM][INPUTNUM]; //"тежестта" на връзките между невроните
for (int o=0;o<OUTPUTNUM;o++)       //
for (int i=0;i<INPUTNUM;i++)    //В началото всички тежести са 0
weights[o][i] = 0;          //

int examples;
//Започва обучението
cout << "Enter number of examples: ";
cin >> examples;
while (examples > 0)
{
cout << "Enter inputs:  ";
for (int i=0;i<INPUTNUM;i++) cin >> inputs[i]; //Входни данни
cout << "Enter outputs: ";
for (int o=0;o<OUTPUTNUM;o++) cin >> outputs[o]; //Очакван резултат при въведените входни данни
learn(inputs,outputs,weights); //Виж дефиницията долу
examples--;
}
for (int o=0;o<OUTPUTNUM;o++) //Печата пресметнатите тежести
{
cout << "Output " << o+1 << ": ";
for (int i=0;i<INPUTNUM;i++)
cout << weights[o][i] << " ";
cout << endl;
}

//С кода от тук до return 0; се проверяват резултатите от обучението
cout << "Enter number of test cases: ";
cin >> examples;
while (examples > 0)
{
cout << "Enter inputs: ";
for (int i=0;i<INPUTNUM;i++)
cin >> inputs[i];
test(inputs,outputs,weights); //Виж дефиницията долу
cout << "Outputs: ";
for (int o=0;o<OUTPUTNUM;o++)
cout << outputs[o] << " ";
cout << endl;
examples--;
}
return 0;
}

/* Учещата функция всъшност извършва едно просто действие - умножение на вектори,
при което се получава матрица, чиито стойности се ползват като тежести */
void learn(bool inputs[INPUTNUM], bool outputs[OUTPUTNUM], short weights[OUTPUTNUM][INPUTNUM])
{
for (int o=0;o<OUTPUTNUM;o++)
for (int i=0;i<INPUTNUM;i++)
weights[o][i] += num[inputs[i]] * num[outputs[o]];
}

/* Тестовата функция взима входни данни и пресмята резултата според тежестите.
Резултата се записва в масива outputs */
void test(bool inputs[INPUTNUM], bool outputs[OUTPUTNUM], short weights[OUTPUTNUM][INPUTNUM])
{
short total;
for (int o=0;o<OUTPUTNUM;o++)
{
total = 0;
for (int i=0;i<INPUTNUM;i++)
total += num[inputs[i]]*weights[o][i];
outputs[o] = (total > 0);
}
}


А ето и накратко какво прави:
Броя на входове и изходи се задава с двата define в началото на кода. Нататък може да покажа как става и динамични с вход от потребителя. След това пита за входове и изходи съответния брой пъти и ги добавя към тежестите чрез обяснения алгоритъм. След това изкарва сметнатите тежести за всеки изход. След това пита колко теста иска да направите. По време на теста вие въвеждате входни данни а функцията test смята резултата. На робота ще му трябва само тази функция, за да работи (освен ако не се обучава сам, но до там не сме стигнали).

Знам че стана адкси дълго но няма как. Областта е толкова обширна, че и 10 пъти по толкова няма да стигнат да се обясни добре. Следващия пост (ако го има) ще покаже как да пренесем получените тежести на робота. Нататък ще се опитам да разширявам темата с цялостно усложняване на материяла. Надявам се че съм бил от полза и ви е било поне интересно.


С това се занимавам от около половин година. Статията може да се нарече авторска защото не съм преписвал или превеждал нищо директно, но откъде съм го чел първия път не знам. Само таблицата в началото беше от този сайт.

INF1n1t

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 139
    • Профил
Умни роботи
« Отговор #1 -: Септември 08, 2007, 10:42:58 am »
Мерси много за статията, от това се интересувах :) ! Сега бегло прочетох статията и се изгубих някъде при матриците...трябва да ги поогледам малко по-детайлно.
Иван Занев - град София

Methuselah

  • Вече знае какво е робот!
  • *****
  • Публикации: 67
    • Профил
Умни роботи
« Отговор #2 -: Септември 08, 2007, 03:16:07 pm »
Искам да се извиня (особено на INF1n1t).
В опитите си да направя умножението на векторите възможно най-прегледно съм допуснал грешка.
При умножението съм използвал 0 вместо -1 и съм забравил че 0*0=0, но (-1)*(-1) = 1. Тоест все едно съм си ползвал 0 в алгоритъма. Това променя тежестите. В нашия случай, обаче сме използвали само 2 примера и това не се е усетило. В програмата тази грешка не е допусната и може да видите че тя изкарва правилните тежести. Сега ще поправя и статията.
Именно тази грешка може да ви е объркала. За щастие това само доказва колко гъвкави са невронните мрежи и как толерират грешки.

INF1n1t

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 139
    • Профил
Умни роботи
« Отговор #3 -: Септември 08, 2007, 07:30:50 pm »
Не бе аз така и не я изчетох, само и хвърлих бегъл поглед. Сега мисля да я изчета по-детайлно.

Мартине: една грешка - това не е С ами е C++ (все пак!).

 И още нещо: от тази статия аз разбрах за невроните, техните прагове, тежести. Но както на мене ми стана ясно, тук просто става въпрос за - ако си ми над прага, тогава трябва да пусна сигнал. Всичко хубаво, но не разбирам как го учиш да прави нещо. В смисъл, ти още с правенето на тия матрици с тежести, му правиш основния pattern, а после то просто взима някакви входни данни и изважда някакви изходни според тоя pattern. В това ли се крие "ученето" или има нещо, което аз не разбрах.
Иван Занев - град София

spookyboy

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 103
    • Профил
Умни роботи
« Отговор #4 -: Септември 08, 2007, 10:11:50 pm »
Ученето според мен е променянето на съдържанието на матрицата с тежестите, или греша :) След като направиш тест, може да 'научиш' нещо от резултата като промениш матрицата.
Станьо - 20г. - извън чужбина

INF1n1t

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 139
    • Профил
Умни роботи
« Отговор #5 -: Септември 08, 2007, 10:29:28 pm »
Да да да - прав си. Фактически ти му вкарваш входовете и изходите и то пресмята матрицата с тежестите. След това test е просто за да тестваш вече направените тежести.  Хитро :)

 П.С. Грешката е моя, тъй-като си помислих, че робота сам се учи, а не че ти го учиш...малко се пообърках, обаче сега ми стана ясно.
Иван Занев - град София

Methuselah

  • Вече знае какво е робот!
  • *****
  • Публикации: 67
    • Профил
Умни роботи
« Отговор #6 -: Септември 09, 2007, 12:39:17 am »
По принцип в случая мрежата само повтаря примерите които са и зададени. И заради това има нужда ние да й кажем изходите. Съществуват и мрежи които сами се учат, но ще трябват подходящи сензори, за да разбира какво се случва при съответни действия, както и да има някакво понятие какво се опитва да постигне, за да раздели действията с "добри", от действията с "лоши" последствия.

Един модел (този с който започнах да се занимавам) включва повече предсказване от страна на мрежата. При него мрежата се опитва да намери формула която да пасва на входните и изходните данни. Например ако зададем като примерни данни [(1;2),(2;4),(3;6),(4;8)] мрежата ще търси най-точната формула отговаяща на тези данни - тоест 2*x и когато се въведе някакъв вход, ще изкара резултата от тази формула. Този подход може би е добър при използване на аналогови сензори - например инфрачервени, за разстояние и робота няма да трябва да прави почти нищо при използването му, но реших първо да представя идеята зад този по-широко разпространен.
За да стане максимално точен алгоритъма от първия пост трябва да се добави и "предубеждение" (bias), което ще премахне съмненията на мрежата, но да си призная - забравил съм как точно се вписваше в алгоритъма и не мога да го намеря отнова. Ще помисля още малко, но нищо не обещавам.

Специялно за роботите - виждал съм проект за ориентиране на робот в среда с препятсвия, използвайки 3 инфрачервени сензори за полезрение и невронна мрежа. Мисля че ще е най-полезно да преведа въпросната статия.

yasko

  • Administrator
  • *****
  • Публикации: 484
    • Профил
Умни роботи
« Отговор #7 -: Септември 09, 2007, 11:03:30 am »
Поздравления за Мартин за интересните статии и тематиката, която е започнал :) Тя наистина е доста обширна и интересна. Преди време и аз се интересувах от невронни мрежи, даже изчетох една, две книжки и една малка програма написах, но всичко беше само на PC.
Това което ми харесе при НМ(невронни мрежи) е тяхната универсалност и спосбността им да решават най-различен кръг проблеми. В мойта програма се бях опитал да направя елементарно разпознаване на цифри от седемсегментен индикатор. Мрежата имаше 7 входа и 4 изхода, като информацията се представя в двоичен вид, т.е представям на входа кои  сегменти светят и след това очаквам да получа двоичния код на изхода (използвах цифри от 0-9). Първоначално мрежата не е обучена (теглата на връзките между отделните неврони не е нагласена) и затова се провежда обучение по метода обратно разпорастранение на грешката т.е на входа се поставя избражението на определена цифра, а на изхода се салага верния код и по определен алгоритъм се променят връзките между невроните и накрая мрежата се научава да разпознава цифрите дори и да има липсващи сегменти.
Разбира се подобна задача може да се реши и с конвенционален алгоритъм и обикновено ако има разработен алгоритъм за дадена задача той обикновено е по добър от НМ, но предимството е че е НМ може да реши проблем за който няма точен алгоритъм или разработването е много сложно и ще отнеме много време
Както писха в началото тематиката е интерсна и може да пробваме някое релано приложение в областта на роботиката :)
Давам линк към една хубава книга (на английски), тя по принцип е за цифрова обработка на сигнали, но глава 26 е за НМ и нещата са обяснени много добре:
http://www.dspguide.com/ch26.htm
Ясен Паунски,  гр.София, 39 г.

Lobotomist

  • Новодошъл
  • *****
  • Публикации: 1
    • Профил
Умни роботи
« Отговор #8 -: Февруари 25, 2009, 10:52:16 pm »
Здравейте всички!
Прави ми впечатление че неврона се разглежда като един доста опростен модел на някакво сметало,влиза сигнал/ли-пресмята се нещо-изход с някакъв сигнал.
Бих казал че това е крайно неточно.По скоро трябва да си представим неврона като един ,да го наречем,процесор.В него влизат множество сигнали,обработват се,част от обработеното по един или друг начин се съхранява/не е задължитено/,на изхода постъпва информация/забележете-информация,не сигнал/.Това което е на изхода/аксона/ се предава на множество други входове/дендрити/.
смея да твърдя ,че посоката в която се описва развитието на невронните мрежи не е съвсем верен,или това е лесния път.
Да тръгнем отдоло-нагоре.
Първичната информация е ДНК,от там нататък това в което ще се превърне съответната клетка е това за което е предназначена/ще кажете биология,нищо ново/.Така,мозъка е изграден от мрежа неврони,които от началното си изграждане имат една определена/от ДНК/структура на свързаност/основа за изграждане на мрежата/.
Като начало може да се подходи по съвсем друг начин.
Матрица от процесори/това също го има/,които са свързани помежду си/всеки от тях съдържа изходен код/ДНК=тук е сложната част :)/той "подсказва" на "клетката" какво да прави .
За сега спирам до тук.И така нещата вече изглеждат доста сложни.
Ако някой проявява интерес може да продължим да обсъждаме в тази посока,дано несам станал досаден :)
Ще направя малко допълнение.Като начало идеята ми е да изградя малка мрежа от контролери/по съществото си те за процесори/и да им задам начална програма за обмен на данни,основаващи се на група входящи сигнали.разработката ми е още в ранен стадий,дори е в зародиш,при определен етап на развитие ще добавя пост с това докаде съм го докарал.
Животът не се мери с броя на вдишванията, а с моментите, които спират дъха ни!
Боб Муурхед

hunter

  • Направо Робот! :)
  • *****
  • Публикации: 638
    • Профил
Умни роботи
« Отговор #9 -: Февруари 26, 2009, 05:56:50 pm »
Вобще даже не си досаден темата е интересна и за това е и форума да дескутираме да изложим знанията си опита и да отсееме мнение за по-нататъчен успех аз лично бих искал темата да се продължи :)
Цвятко Цветков/ Бургас

http://www.youtube.com/watch?v=I1y67hzRWQY&feature=related

zbytsam

  • Заклет Роботостроител
  • *****
  • Публикации: 256
    • Профил
    • http://genadi.masoko.net
Умни роботи
« Отговор #10 -: Февруари 26, 2009, 06:14:17 pm »
много интересно четиви , развийте още темата.Много е хубава.
гр. София

lekar

  • Новодошъл
  • *****
  • Публикации: 2
    • Профил
Умни роботи
« Отговор #11 -: Ноември 17, 2009, 12:54:41 pm »
Много интересна тема, но не разбирам защо никой нищо не пише по нея.

Според мен основната разлика оказва огромно влияние - (Компютърът  използва последователни инструкции, докато Мозъкът паралелни).

Има ли някъкъв вариант това да се симулира?

sv_shady

  • Administrator
  • *****
  • Публикации: 636
    • Профил
Умни роботи
« Отговор #12 -: Ноември 17, 2009, 04:16:12 pm »
Така след като вече съм присъствал на няколко лекции по изкуствен интелект, водени от първия киборг в света Кевин Уорик, мога да изкажа някакво мнение по темата :) Един от основните проблеми е именно, че компютърът мисли итеративно, а нашата нервна система работи паралелно. За тези цел се разработват различни методи за хардуерно симулиране на цяла неврнна мрежа, което ще позволи паралелното обработване. Тъй като обучението трябва да е възможно и на хардуерно ниво все още няма схеми, които да представят схема от неврони по модела на МакКълъх и Питс (неврона има n входа, функция на активация и изход). Но има сравнителен напредък с така наречените n-tuple невронни мрежи или на български n-списъчни неврнни мрежи. Всеки неврон може да се представи като най-обикновен рам памет чип. Именно с тази технология и подходящо обучение на невроните са постигнати най-добри резултати в разпознаването на изображения. Ако има интерес, мога да кача някоя и друга лекция на английски или да преведа ако има интерес. :)
Imagination is the only limit.......

Светлин Пенков
София / Рединг, Великобритания

lekar

  • Новодошъл
  • *****
  • Публикации: 2
    • Профил
Умни роботи
« Отговор #13 -: Ноември 17, 2009, 04:26:51 pm »
Интересът е голям. Според мен материалите може и на Английски (translate.google.com спасява).

Дали има софтуерно решение на паралелното обработване?

Всъщност кода на Methuselah е до някъде с паралелна обработка (входовете се изчисляват на 1 такт, или по-точно заедно).

Доколкото аз се опитах да поровя, трябва да има BIAS и hidden полета за да се изпълни т.н. не-линейна невронна мрежа. Въпросът е как би станало това с код :!:

sv_shady

  • Administrator
  • *****
  • Публикации: 636
    • Профил
Умни роботи
« Отговор #14 -: Ноември 17, 2009, 07:18:35 pm »
Няма как чрез код да кажеш на компютъра да изпълни две неща едновремнно, чисто концептуално не е възможно :) Може да е прекалено бързо, така, че да изглежда едновременно (кода на Methuselah), но всъщност е последователно.
Imagination is the only limit.......

Светлин Пенков
София / Рединг, Великобритания