|
|
(не показано 29 промежуточных версий 1 участника) |
Строка 1: |
Строка 1: |
| [[Категория:МиниБот]] | | [[Категория:МиниБот]] |
− | [[Изображение:1.GIF|thumb]]
| |
− | Здесь я постараюсь оформить свои давние мысли о применении памяти в элементах ИИ.<br />
| |
| | | |
− | Если подходить к памяти с точки зрения организации элементов ИИ, то для начала для начала несколько фактов:<br />
| + | [[Изображение:maket_SD-Card.jpg|thumb]] |
− | 1. Флеш-память нынче дешева как никогда и при этом постоянно цена еще падает чутли не ежемесячно. По состоянию на 5 июля 2008г. '''2Гб''' micro-SD в розницу стоила '''268р.''' при этом она умещается на ногте и имеет толщину меньше 1мм.<br />
| |
− | 2. Операция поиска у живых организмов происходит '''параллельно''', а не последовательно как принято у нас в программировании. А именно, из милллиона записей БД мы в программировании чтоб найти что либо должны перебрать почти весь список т.е. нам потребуется почти миллион тактов на поиск, у живых же организмов на это уходит несколько тактов при этом размер базы для них не имеет никакого значения. Мы конечно применяем разного рода ухищрения в виде предварительной сортировки и индексации, но это всё от безисходности. Факт остается фактом, чем больше БД тем больше времени уходит на поиск. При этом как такого тактования применяемого сейчас сплош и рядом в микропроцессорах у живых организмов нет. А оно собственно и не надо. Посмотрите как работает паралельная озушка, у нее никакого тактового нет. Но об этом чуть позже...<br />
| |
− | 3. флеш-память можно расматривать как скучкованную в одном месте гору микросхем отдельных памятей по 512 байт. В случае с вышеупомянутой 2ГБ карточкой это 3.967.488 микросхемок по 512б <br />
| |
| | | |
− | [[Изображение:Мгновенное голосование.GIF|thumb]]
| + | Писать собственно сильно нечего, всё предельно просто как валенок.<br /> |
− | Итак для примера рассмотрим самый простой пример, необходимо подсчитать общее количество единичек поступивших на вход, у нас есть три пути:<br />
| + | Легким движением руки паяем переходничек о шести проводках согласно схемы. <br /> |
− | --- С помощью микроконтроллера или микропроцессора написать соответсвующий '''последовательный''' код. Вывод чем больше у нас входов тем дольше мы будем подсчитывать.<br />
| + | На самом МиниБоте ничего перепаивать не надо. <br /> |
− | --- С помощью логики собрать схему приведенную на рисунке 11.12 Тут всё хорошо никакого тактования, подсчет происходит мгновенно. Одно плохо, если необходимо увеличить количество входов, то прийдется перепаивать схему.<br /> | + | Эксперементальным путем установлена работоспособность SD-карт при питании 4.1В (но это не говорит о том что и ваши SD-карты такие же не прихотливые ;-)).На крайний случай на период тестов запускайте МиниБот при разряженом до 3.6В акуумуляторе.<br /> |
− | --- Собрать схему на флешевой памяти. Входа в нашем случае это адресные линии, выход это шина данных. Ложка дегтя которая сразу бросается в глаза, такой вариант прийдется обучать. Но позвольте господа, именно так у живых существ и просиходит! И помоему мы как раз этого и добивались! :-) И обучать-то прийдется всего только один раз, при современных скоростях это займет доли секунд<br /> | + | Затем честно себе копируем код теста SD-карты. После этого разрешается править данный код на свое усмотрение... :-)))<br /> |
| + | Память так же как и сам Минибот и все остальные компоненты можно приобрести здесь http://www.MiniBot.ru <br /> |
| + | Удачи коллеги в создании искусственного интеллекта!... :-)))<br /> |
| | | |
− | И вот тут мы плавно и незаметно подошли к понятию '''ассоциативной''' памяти.<br />
| |
− | Схеме на базе памяти по большому счету всё равно что там у нее на входах, она четко запомнила, когда на входе то-то, то на выходе должно быть то-то. Я считаю что такому принципу работает любой нейрон, хоть сложения хоть вычитания с умножением, хоть распознования образов. Т.е. в процессе обучения устанавливается ассоциация входного сигнала с номером образа.<br />
| |
| | | |
| + | '''Исходники''' [[Медиа:test_SD-Card.rar]] |
| | | |
− | И сдается мне, что весь наш интеоект базируется на трех китах:<br />
| + | '''Чтение из SD-Card''' |
− | -- ПИД регулирования поставленной цели согласно приоритетов<br />
| + | <source lang="vb"> |
− | -- Ассоциативной памяти<br /> | |
− | -- И системы голосования распознаных образов<br />
| |
| | | |
| + | Sd_address = 0 ; Gosub Read_sd_data 'после чтения данные будут лежать в массиве Sd_data |
| | | |
| + | </source> |
| | | |
| + | '''запись в SD-Card''' |
| <source lang="vb"> | | <source lang="vb"> |
| | | |
− | $prog &HFF , &HE4 , &HD9 , &HFF ' generated. Take care that the chip supports all fuse bytes.
| + | Sd_address = 0 ; Gosub Clear_sd_buffer 'Очистить буфер для чтения/записи SD карты |
− | $regfile = "m128DEF.dat"
| |
− | $crystal = 8000000
| |
− | $baud = 4800
| |
| | | |
− | 'Нога отвечает за Вкл/Откл SD карты в SPI режиме
| + | Sd_data(1) = 10 |
− | Config Porte.2 = Output : Chip_select Alias Porte.2
| + | Sd_data(2) = 20 |
| + | Sd_data(3) = 30 |
| + | Sd_data(4) = 40 |
| + | Sd_data(5) = 50 |
| + | Sd_data(6) = 60 |
| + | Sd_data(7) = 70 |
| + | Sd_data(8) = 80 |
| + | Sd_data(9) = 90 |
| + | Sd_data(10) = 100 |
| + | ' и так можно до 512 |
| | | |
− | Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4
| + | Gosub Write_sd_data 'Записать данные в SD карту |
| | | |
− | Dim Флаг As Bit
| + | </source> |
− | Dim ФлагПроверкиЗаписи As Bit
| |
− | Dim ФлагДанныеЗаписаныВерно As Bit
| |
| | | |
− | Dim ПринятыйБайт As Byte
| + | [[Изображение:Распиновка SD-Card.GIF|thumb]] |
− | Dim Sd_command(6) As Byte
| + | [[Изображение:MiniBot - SD-Card.GIF|thumb]] |
− | 'Ответ максимум состоит из 10 байт
| + | [[Изображение:1.GIF|thumb]] |
− | Dim Size_answer As Byte
| + | [[Изображение:тест.GIF|thumb]] |
− | Dim Sd_answer(10) As Byte
| |
− | Dim Sd_data(512) As Byte
| |
| | | |
− | Dim Tmp_byt1 As Byte
| |
− | Dim Tmp_byt2 As Byte
| |
− | Dim Tmp_byt3 As Byte
| |
| | | |
− | Dim Count_wrd As Word
| |
| | | |
− | Dim Tmp_wrd1 As Word
| |
− | Dim Tmp_wrd2 As Word
| |
| | | |
− | Dim Sd_address As Long
| |
| | | |
− | Print "Старт программы"
| |
| | | |
− | Begin:
| |
− | Chip_select = 1 'Отключить SD карту
| |
− | 'Ответ максимум состоит из 1 байт
| |
− | Size_answer = 1
| |
− | ФлагПроверкиЗаписи = 0
| |
− | Sd_address = &H0
| |
| | | |
− | Spiinit 'Инициализация SPI у меги
| |
| | | |
− | Gosub Init_sd 'Инициализация SPI у SD карты
| |
| | | |
− | Do
| |
− | Gosub Clear_sd_buffer 'Очистить буфер для чтения/записи SD карты
| |
| | | |
− | Sd_data(1) = 10
| |
− | Sd_data(2) = 20
| |
− | Sd_data(3) = 30
| |
− | Sd_data(4) = 40
| |
− | Sd_data(5) = 50
| |
− | Sd_data(6) = 60
| |
− | Sd_data(7) = 70
| |
− | Sd_data(8) = 80
| |
− | Sd_data(9) = 90
| |
− | Sd_data(10) = 100
| |
| | | |
− | Gosub Write_sd_data 'Записать данные в SD карту
| |
| | | |
− | Gosub Read_sd_data 'Прочитать данные из SD карты
| |
| | | |
− | Sd_address = Sd_address + 512
| |
| | | |
− | Loop Until Sd_address = 2048
| |
− | End
| |
| | | |
− | '-------------------------------------------------------------------------------
| |
| | | |
− | Init_sd: 'Подпограмма инициализирует SPI у SD карты
| |
| | | |
− | Print "Инициализация SPI у SD карты"
| |
| | | |
− | 'Переводим SD карту в SPI режим
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
| | | |
− | Chip_select = 0 'Включить SD карту
| |
| | | |
− | Print "Ресет"
| |
− | 'Послать команду ресет SD карты
| |
− | Sd_command(1) = &H40
| |
− | Sd_command(2) = &H00
| |
− | Sd_command(3) = &H00
| |
− | Sd_command(4) = &H00
| |
− | Sd_command(5) = &H00
| |
− | Sd_command(6) = &H95
| |
− | Gosub Send_sd_command
| |
| | | |
− | Print "Инициализация"
| |
− | Do 'Послать команду инициализации SD карты
| |
− | Sd_command(1) = &H41
| |
− | Sd_command(2) = &H00
| |
− | Sd_command(3) = &H00
| |
− | Sd_command(4) = &H00
| |
− | Sd_command(5) = &H00
| |
− | Sd_command(6) = &H55
| |
− | Gosub Send_sd_command
| |
− | Waitms 100
| |
− | Loop Until Sd_answer(1) = 0
| |
| | | |
− | Chip_select = 1 'Отключить SD карту
| |
| | | |
− | Print "Инициализация SPI у SD карты окончена"
| |
− | Return
| |
| | | |
− | Send_sd_command: 'Подпограмма посылает команду SD карте
| |
| | | |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(sd_command(1))
| |
− | ПринятыйБайт = Spimove(sd_command(2))
| |
− | ПринятыйБайт = Spimove(sd_command(3))
| |
− | ПринятыйБайт = Spimove(sd_command(4))
| |
− | ПринятыйБайт = Spimove(sd_command(5))
| |
− | ПринятыйБайт = Spimove(sd_command(6))
| |
| | | |
− | Gosub Receive_sd_command 'Получить ответ от SD карты
| |
| | | |
− | ПринятыйБайт = Spimove(ПринятыйБайт)
| |
− | Return
| |
| | | |
− | Receive_sd_command: 'Подпограмма получает ответ от SD карты
| |
| | | |
− | Do
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | Loop Until ПринятыйБайт <> &HFF
| |
| | | |
− | Tmp_byt1 = 0
| |
− | Do
| |
− | Incr Tmp_byt1
| |
− | Sd_answer(tmp_byt1) = ПринятыйБайт
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | Loop Until ПринятыйБайт = &HFF Or Size_answer = Tmp_byt1
| |
| | | |
− | Print "Ответ SD карты"
| |
− | For Tmp_byt2 = 1 To Tmp_byt1
| |
− | Print "Байт №" ; Tmp_byt2 ; " = " ; Sd_answer(tmp_byt2)
| |
− | Next
| |
− | Return
| |
| | | |
− | Clear_sd_buffer: 'Подпограмма очищяет буфер для чтения/записи SD карты
| |
| | | |
− | For Count_wrd = 1 To 512
| |
− | Sd_data(count_wrd) = 0
| |
− | Next
| |
− | Return
| |
| | | |
− | Write_sd_data: 'Подпограмма записывает данные в SD карту по адресу Sd_address размером 512 байт
| + | <!-- |
− | 'данные берёт из Sd_data(512)
| + | Здесь я постараюсь оформить свои давние мысли о применении памяти в элементах ИИ.<br /> |
| | | |
− | Do
| + | Если подходить к памяти с точки зрения организации элементов ИИ, то для начала для начала несколько фактов:<br /> |
− | Tmp_byt3 = 0
| + | 1. Флеш-память нынче дешева как никогда и при этом постоянно цена еще падает чутли не ежемесячно. По состоянию на 5 июля 2008г. '''2Гб''' micro-SD в розницу стоила '''268р.''' при этом она умещается на ногте и имеет толщину меньше 1мм.<br /> |
− | Do
| + | 2. Операция поиска у живых организмов происходит '''параллельно''', а не последовательно как принято у нас в программировании. А именно, из милллиона записей БД мы в программировании чтоб найти что либо должны перебрать почти весь список т.е. нам потребуется почти миллион тактов на поиск, у живых же организмов на это уходит несколько тактов при этом размер базы для них не имеет никакого значения. Мы конечно применяем разного рода ухищрения в виде предварительной сортировки и индексации, но это всё от безисходности. Факт остается фактом, чем больше БД тем больше времени уходит на поиск. При этом как такого тактования применяемого сейчас сплош и рядом в микропроцессорах у живых организмов нет. А оно собственно и не надо. Посмотрите как работает паралельная озушка, у нее никакого тактового нет. Но об этом чуть позже...<br /> |
− | Флаг = 0
| + | 3. флеш-память можно расматривать как скучкованную в одном месте гору микросхем отдельных памятей по 512 байт. В случае с вышеупомянутой 2ГБ карточкой это 3.967.488 микросхемок по 512б <br /> |
− | Chip_select = 0 'Включить SD карту
| |
| | | |
− | Print "Запись"
| + | [[Изображение:Мгновенное голосование.GIF|thumb]] |
| + | Итак для примера рассмотрим самый простой пример, необходимо подсчитать общее количество единичек поступивших на вход, у нас есть три пути:<br /> |
| + | --- С помощью микроконтроллера или микропроцессора написать соответсвующий '''последовательный''' код. Вывод чем больше у нас входов тем дольше мы будем подсчитывать.<br /> |
| + | --- С помощью логики собрать схему приведенную на рисунке 11.12 Тут всё хорошо никакого тактования, подсчет происходит мгновенно. Одно плохо, если необходимо увеличить количество входов, то прийдется перепаивать схему.<br /> |
| + | --- Собрать схему на флешевой памяти. Входа в нашем случае это адресные линии, выход это шина данных. Ложка дегтя которая сразу бросается в глаза, такой вариант прийдется обучать. Но позвольте господа, именно так у живых существ и просиходит! И помоему мы как раз этого и добивались! :-) И обучать-то прийдется всего только один раз, при современных скоростях это займет доли секунд<br /> |
| | | |
− | Print "Записать блок данных (512 байт) по адресу " ; Hex(sd_address)
| + | И вот тут мы плавно и незаметно подошли к понятию '''ассоциативной''' памяти.<br /> |
| + | Схеме на базе памяти по большому счету всё равно что там у нее на входах, она четко запомнила, когда на входе то-то, то на выходе должно быть то-то. Я считаю что такому принципу работает любой нейрон, хоть сложения хоть вычитания с умножением, хоть распознования образов. Т.е. в процессе обучения устанавливается ассоциация входного сигнала с номером образа.<br /> |
| | | |
− | Do
| |
− | Incr Tmp_byt3
| |
− | Print "Попытка записать данные №" ; Tmp_byt3
| |
− | Sd_command(1) = &H58 'Послать команду записать блок данных по адресу (sd_address) в SD карту
| |
| | | |
− | Tmp_wrd1 = Highw(sd_address)
| + | И сдается мне, что весь наш интеоект базируется на трех китах:<br /> |
− | Tmp_wrd2 = Sd_address
| + | -- ПИД регулирования поставленной цели согласно приоритетов<br /> |
− | | + | -- Ассоциативной памяти<br /> |
− | Sd_command(2) = High(tmp_wrd1)
| + | -- И системы голосования распознаных образов<br /> --> |
− | Sd_command(3) = Low(tmp_wrd1)
| |
− | Sd_command(4) = High(tmp_wrd2)
| |
− | Sd_command(5) = Low(tmp_wrd2)
| |
− | Sd_command(6) = &H55
| |
− | Gosub Send_sd_command
| |
− | Loop Until Sd_answer(1) = 0 Or Tmp_byt3 = 5
| |
− | | |
− | If Sd_answer(1) <> 0 Then
| |
− | Флаг = 1 'Команда на запись не прошла
| |
− | Print "Пришёл неверный ответ от команды записи"
| |
− | Else
| |
− | Print "Послать данные"
| |
− | ПринятыйБайт = Spimove(&Hff) 'Послать данные
| |
− | ПринятыйБайт = Spimove(&Hfe) 'Послать стартовые байты
| |
− | 'Послать данные
| |
− | For Count_wrd = 1 To 512
| |
− | ПринятыйБайт = Spimove(sd_data(count_wrd))
| |
− | Next
| |
− | 'Послать CRC16
| |
− | ПринятыйБайт = &H55
| |
− | ПринятыйБайт = Spimove(ПринятыйБайт)
| |
− | ПринятыйБайт = &H55
| |
− | ПринятыйБайт = Spimove(ПринятыйБайт)
| |
− | | |
− | Gosub Receive_sd_command 'Получить ответ от SD карты
| |
− | | |
− | If Sd_answer(1) <> 229 Then
| |
− | Sd_answer(1) = 1 'Данные не записались
| |
− | If Tmp_byt3 = 5 Then
| |
− | Флаг = 1
| |
− | Print "Пришёл неверный ответ после записи данных"
| |
− | End If
| |
− | Else
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | | |
− | Chip_select = 1 'Отключить Sd карту
| |
− | | |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | | |
− | Chip_select = 0 'Включить SD карту
| |
− | | |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | | |
− | Print "Данные успешно записаны"
| |
− | Sd_answer(1) = 0
| |
− | End If
| |
− | End If
| |
− | | |
− | Chip_select = 1 'Отключить Sd карту
| |
− | Waitms 10 'Время, которое неоюходимо, для записи данных в SD карту
| |
− | | |
− | If Флаг = 1 Then
| |
− | Tmp_byt3 = 0 'Произошла ошибка при записи команды или данных
| |
− | Gosub Init_sd 'Инициализация SPI у SD карты
| |
− | End If
| |
− | Loop Until Флаг = 0 And Sd_answer(1) = 0
| |
− | ФлагПроверкиЗаписи = 1 'Проверить правильно ли записали
| |
− | Gosub Read_sd_data 'Прочитать данные из SD карты
| |
− | | |
− | If ФлагДанныеЗаписаныВерно = 1 Then
| |
− | Print "Верификация прошла успешно"
| |
− | Else
| |
− | Print "Верификация не прошла"
| |
− | End If
| |
− | Loop Until ФлагДанныеЗаписаныВерно = 1
| |
− | Return
| |
− | | |
− | Read_sd_data:
| |
− | 'Подпограмма читает данные из SD карты по адресу Sd_address размером 512 байт
| |
− | 'данные записывает в Sd_data(512)
| |
− | ФлагДанныеЗаписаныВерно = 1
| |
− | | |
− | Do
| |
− | Флаг = 0
| |
− | Chip_select = 0 'Включить SD карту
| |
− | | |
− | If ФлагПроверкиЗаписи = 1 Then
| |
− | Print "Верификация"
| |
− | Else
| |
− | Print "Чтение"
| |
− | End If
| |
− | | |
− | Print "Установить размер блока чтения данных - 512"
| |
− | 'Послать команду установить размер блока 512 в SD карту
| |
− | Sd_command(1) = &H50
| |
− | Sd_command(2) = &H00
| |
− | Sd_command(3) = &H00
| |
− | Sd_command(4) = &H02
| |
− | Sd_command(5) = &H00
| |
− | Sd_command(6) = &H55
| |
− | Gosub Send_sd_command
| |
− | | |
− | Print "Прочитать блок данных по адресу " ; Hex(sd_address)
| |
− | 'Послать команду прочитать блок данных по адресу (sd_address) в SD карту
| |
− | | |
− | Tmp_byt3 = 0
| |
− | Do
| |
− | Incr Tmp_byt3
| |
− | Print "Попытка прочитать данные №" ; Tmp_byt3
| |
− | Sd_command(1) = &H51
| |
− | | |
− | Tmp_wrd1 = Highw(sd_address)
| |
− | Tmp_wrd2 = Sd_address
| |
− | | |
− | Sd_command(2) = High(tmp_wrd1)
| |
− | Sd_command(3) = Low(tmp_wrd1)
| |
− | Sd_command(4) = High(tmp_wrd2)
| |
− | Sd_command(5) = Low(tmp_wrd2)
| |
− | Sd_command(6) = &H55
| |
− | Gosub Send_sd_command
| |
− | Loop Until Sd_answer(1) = 0 Or Tmp_byt3 = 5
| |
− | | |
− | If Sd_answer(1) <> 0 Then
| |
− | Флаг = 1 'Команда на чтение не прошла
| |
− | Print "Пришёл неверный ответ от команды чтения"
| |
− | Else
| |
− | 'Получение данных
| |
− | 'Поймать стартовый байт
| |
− | Do
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | Loop Until ПринятыйБайт = &HFE
| |
− | For Count_wrd = 1 To 512 'Получить 512 байт данных
| |
− | If ФлагПроверкиЗаписи = 1 Then
| |
− | ПринятыйБайт = Spimove(&Hff) 'Читаем и сравниваем с Sd_data(512)
| |
− | If ПринятыйБайт <> Sd_data(count_wrd) Then
| |
− | ФлагДанныеЗаписаныВерно = 0
| |
− | End If
| |
− | Else
| |
− | Sd_data(count_wrd) = Spimove(&Hff) 'Читаем и записываем в Sd_data(512)
| |
− | End If
| |
− | Next
| |
− | 'Получить КС
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | ПринятыйБайт = Spimove(&Hff)
| |
− | | |
− | Print "Данные успешно считаны"
| |
− | End If
| |
− | | |
− | Chip_select = 1 'Отключить Sd карту'
| |
− | | |
− | If Флаг = 1 Then
| |
− | 'Произошла ошибка при записи команды или данных
| |
− | | |
− | Gosub Init_sd 'Инициализация SPI у SD карты
| |
− | End If
| |
− | Loop Until Флаг = 0
| |
− | ФлагПроверкиЗаписи = 0
| |
− | Return
| |
− | | |
− | </source> | |