Skip to content

Latest commit

 

History

History
81 lines (64 loc) · 3.57 KB

neuronetwork.org

File metadata and controls

81 lines (64 loc) · 3.57 KB

neuronetwork

В качестве практикума, попробую написать несколько простых нейронных сетей на Лиспе

Один нейрон

Простейшая модель нейрона представляет собой взвешенный сумматор, единственный выход которого определяется через его входы и матрицу весов следующим образом:

y = f(u) , где u = Σ(wn*xn)+(w0*x0) , где

x - сигналы на входе нейрона w - веса входа

Функция f(u) называется передаточной фукнцией, w0*x0 - смещением. Передаточная функция определяет зависимость сигнала на выходе нейрона от взвешенной суммы сигналов на его входах.

Основные типы передаточных функций:

  • линейная - f(x) = tx
  • пороговая (Хевисайда) f(x) = if (x >= T) then 1 else 0 , где T - смещение с отрицательным знаком
  • сигмоидальная
  • логистическая f(x) = 1 / (1+exp(tx)) , где t - параметр крутизны. У этой функции простая производная: (df(x) / dx) = tf(x)(1-f(x)) область значений лежит в [0;1]
  • гиперболический тангенс f(x) = (exp(x)-exp(-x)) / (exp(x)+exp(-x)) область значений лежит в [-1;1]
  • другие, которые пока рано рассматривать

Вот пример нейрона, который имеет порог 0.5, три входа с весами 0.7, -1.5, 0.2 на сумматоре и использует логистическую функцию в качестве передаточной:

(defun neuron (a b c)
  (/ 1 (+ 1 (exp (- (+ (*  0.7 a)
                       (* -1.5 b)
                       (*  0.2 c)
                       0.5))))))

(neuron 1 2 4)

Технически, мы можем расширить эту модель заменив сумматор на произвольную “функцию агрегации”. Таким образом, чтобы построить нейрон, мы должны передать “построителю”:

  • вектор весов
  • функцию агрегации
  • функцию активации
  • порог

Создадим макрос, который может строить нейроны:

(defmacro make-neuron (aggregator activator threshold &rest weights)
  (let ((ins (loop :for weight :in weights
                :for cnt :from 0
                :collect (cons (intern (format nil "IN-~A" cnt)) weight))))
    `(lambda ,(mapcar #'car ins)
       (funcall ,activator (funcall ,aggregator ,@(mapcar #'(lambda (x) `(* ,(cdr x) ,(car x))) ins) ,threshold)))))

(macroexpand-1 '
 (make-neuron #'+ #'(lambda (x) (/ 1 (+ 1 (exp (- x))))) 0.5 0.7 -1.5 0.2))

;; => (LAMBDA (IN-0 IN-1 IN-2)
;;      (FUNCALL #'(LAMBDA (X) (/ 1 (+ 1 (EXP (- X)))))
;;               (FUNCALL #'+ (* 0.7 IN-0) (* -1.5 IN-1) (* 0.2 IN-2) 0.5)))

(funcall (make-neuron #'+ #'(lambda (x) (/ 1 (+ 1 (exp (- x))))) 0.5 0.7 -1.5 0.2)
         1 2 4)