nflow v0.2.0

топ 100 блогов love5an30.01.2011 Полностью переработал модель распространения данных в neural-flow 
Не без помощи nflow v0.2.0 [info]dmitry_vk  в [email protected], надо сказать.

Библиотека стала больше походить на cells. Но, её интерфейс и dataflow-модель - намного проще и удобнее в использовании.

Теперь зависимости между нейронами вычисляются автоматически, динамически, и, кроме того, один нейрон может зависеть от нескольких других одновременно.

Что значит "автоматически"? Это значит, что, в отличие от предыдущей версии, теперь не нужно руками делать add-connection и remove-connection. Нейрон сам вычислит, с кем он связан и соответствующим образом распространяет поток данных.

Что значит "динамически"? Это значит, что связи между нейронами создаются и изменяются во время выполнения программы, на основе взаимодействия нейронов, а не на основе каких-либо статически заданных формул. Короче, как и у настоящих нейронов.
А связи между настоящими нейронами зависят от множества факторов - от расположения нейрона, от количества алкоголя в крови, да и даже от фазы луны.

Кстати, о фазе луны. Вот сразу  пример :)

(defparameter *input* (neuron ()
nil))

(defparameter *first* (neuron ()
(neuron-value *input*)
:first))

(defparameter *second* (neuron ()
(neuron-value *input*)
:second))

(defparameter *output* (neuron ()
(if (evenp (floor (get-universal-time) ;;количество секунд с 1 января 1900 года
(* 60 60 24 29.5 1/2))) ;;количество секунд в лунном полуцикле
(neuron-value *second*)
(neuron-value *first*))))

(defun query-lunar-phase ()
(update-neuron *input*)
(neuron-value *output*))

В первую половину лунного цикла нейрон *output* будет узнавать значение лунной фазы из нейрона *first*, а во вторую половину - из *second*. Ну, довольно очевидно, что на сегодняшний день он будет хранить значение :second :)

Макрос neuron это просто удобная форма записи (make-instance 'neuron ...)
Выглядит он так:

(defmacro neuron ((&optional (neuron-class 'neuron) (value-var (gensym)) &rest args)
&body body)
(check-type value-var symbol)
`(make-instance ',neuron-class
:function (lambda (,value-var) (declare (ignorable ,value-var)) ,@body)
,@args))
Таким образом, что каждый нейрон представляет собой функтор, являющийся звеном в некоторой цепочке вычислений.

Как видно, в функции query-lunar-phase мы не указываем явно, что нам нужно обновить именно нейрон *output*, который собственно и вычисляет фазу луны. Напротив, мы обновляем только нейрон *input*. И тем не менее, поток данных проходит весь путь от *input* к *output*.

Как это достигается? Очень просто - вызов функции neuron-value записывает нейрон, из которого мы эту функцию вызываем, в список зависимостей нейрона, к которому мы обращаемся.

(defun neuron-value (neuron)
(declare (type neuron neuron))
(when *current-neuron*
(pushnew *current-neuron* (slot-value neuron '%dependents) :test #'eq))
(slot-value neuron '%value))
Сама же функция-обработчик-данных нейрона, вызывается, среди прочего, при его создании.

Таким образом, связи между нейронами зависят исключительно от того, куда нейрон дотягивается "дендритами" во время выполнения программы. Для вышеописанного примера, на сегодняшнее число, связи будут выглядеть так:
нейроны
Прослеживается аналогия с монадами - нейрон, как и монада, это некое звено в цепочке вычислений. Отличие в том, что функция нейрона выполняет роли как bind, так и return; впрочем, я думаю позже ввести "синапсы"  - обобщенные функции, которые бы обрабатывали значение, полученное из нейрона, и значение, возвращаемое самим функтором. 

Важное отличие от традиционного FRP(functional reactive programming) состоит в том, что в моей библиотеке используется data-driven(push-based, eager) модель, в противоположность demand-driven(pull-based, lazy) моделям, которые обычно используются в FRP-фреймворках.

На практике это означает то, что поток данных инициируется каким-либо событием, например, изменением слота, хранящего текущее значение нейрона, или вызовом update-neuron, в противоположность традиционному FRP, где вычисления начинаются при попытке узнать значение слота.

Напоследок, еще один пример:

;;В объектах классов, являющихся экземплярами метакласса dataflow-class
;; все слоты являются нейронами
;; При этом, мы можем продолжать с ними работать как с обычными слотами.
(defclass textbox (dataflow-object)
((text :initform "" :accessor textbox-text))
(:metaclass dataflow-class))

(defclass checkbox (dataflow-object)
((checked :initform nil :accessor checkbox-checked))
(:metaclass dataflow-class))

(defun event-example ()
(let* ((textbox (make-instance 'textbox))
(checkbox (make-instance 'checkbox)))
;;bindf это обобщенная функция, устанавливающая нейрону или слоту(как здесь)
;; новую функцию-обработчик, или же устанавливающая слоту новый нейрон.
(bindf (lambda (old-value)
(declare (ignore old-value))
(if (checkbox-checked checkbox)
"Checked"
"Unchecked"))
textbox
:slot 'text)
;;просто некий нейрон, который будет нас оповещать об изменениях
;; слота text у textbox'а
(let ((observer (neuron ()
(format t "Text changed. New value: ~s"
(textbox-text textbox)))))
(declare (ignorable observer))
checkbox)))


;;При изменении слота checked, слот textbox'a также будет изменяться -
;; устанавливаться в "Checked" или "Unchecked" соответственно.
;; А при изменении самого слота text, этим, или
;; другим способом(например через (setf slot-value)),
;; об изменении нас будет оповещать нейрон observer

Оставить комментарий

Архив записей в блогах:
Янукович и Медведев во время возложения венков к могиле неизвестного солдата в Киеве.прислал ...
"Президенту России Владимиру Путину доложили о том, что афганское движение «Талибан» (организация признана в РФ террористической, деятельность запрещена) можно исключить из списка запрещенных в стране." Вот и ладненько, вот и хорошо. Это всë скрепы и традиционные ценности: "Разворот на ...
Хоть жаль, что нашей юности пора От нас ушла, казалось, безвозвратно, Не будем возвращать её обратно, Ведь в нас ещё достаточно тепла! Ведь в нас ещё желания горят, А в ...
Шарон ден Адель (Sharon den Adel) – нидерландская певица и композитор, известная своим участием в группе Within Temptation. Адель родилась 12 июля 1974 года в городе Ваддинксвен, в Южной Голландии. Семья много путешествовала – Шарон пришлось жить в десяти странах. Выступала с ...
А я то, думал, откуда нашествие в мою уютную такого количества свидомого говна.... А оказывается какое то смешное чучело из министерства стеца высралось приведя в пример мою фразу про пиздёнышей.... Ну да... Только сейчас узнал, но уже ответил недавно одному из визитёров. Да, впроче ...