Top.Mail.Ru

Пишем нейросеть на Python. Часть 1.

Для того, чтобы создать на Python нейросеть, нам понадобиться numpy, которая содержит нужные нам математические функции. Для установки этой библиотеки через pip выполните команду python -m pip install numpy.

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

У нас будут три передаточных функции:

  • Как есть.
  • Сигмоидная.
  • Пороговая.

У каждой передаточной функции есть кое-что общее: все их надо вычислять. Но каждую будем вычислять по разному. Поэтому необходим создать абстрактный класс, от которого все классы передаточной функции будут наследовать общий метод compute. У абстрактного класса данный метод будет абстрактным, а в каждом дочернем классе он будет реализован по своему. Этот позволит навестить на нейрон любую передаточную функцию (не ограничиваясь теми, что мы разработаем, так как в будущем мы сможем их добавлять).

Правда, а Python-не, в отличии от таких ООП языков, как C# или Delphi, нет абстрактных классов. Но есть эмулятор абстрактных классов. Для того, чтобы его заюзать, надо лишь импортировать соответствующие библиотеки:

from abc import ABCMeta, abstractmethod

Для того, чтобы сделать класс абстрактным, необходимо установить у него метакласс равный ABCMeta, вот так:

__metaclass__=ABCMeta

А для того, чтобы метод сделать абстрактным, необходимо указать у него декоратор @abstractmethod. Декоратор — эта такая мощная шутка, которая позволяет неявно обернуть код в другой код. В данном случае декоратор @abstractmethod оборачивает объявление метода в код проверки, что абстрактный метод реализован.

Теперь мы знаем достаточно, чтобы реализовать класс нейрона:

import numpy as np
import random as rnd
from abc import ABCMeta, abstractmethod


#Абстрактный класс передаточной функции
class TransFunc():
    __metaclass__=ABCMeta

    @abstractmethod
    def compute(self,income):
        """Рассчитать передаточную функцию"""
    
    @abstractmethod
    def get_id():
        """ИД передаточной функции"""

    @abstractmethod
    def mutation(level):
        """Мутация передаточной функции"""        

#Передаточная функция "Как есть"
class AsIs(TransFunc):

    def compute(self,income):
        return income

    def get_id(self):
        return 1    
    
assert issubclass(AsIs, TransFunc)
assert isinstance(AsIs(), TransFunc)


#Передаточная функция "Сигмоида"
class SignFunc(TransFunc):
    def __init__(self):
        self.par=1
        
    def compute(self,income):
        return 1/(1+np.exp(-self.par*income))

    def get_id(self):
        return 2       
    
assert issubclass(SignFunc, TransFunc)
assert isinstance(SignFunc(), TransFunc)

#Передаточная функция "Пороговая"
class ThresholdFunc(TransFunc):
    def compute(self,income):
        if income>0:
            return 1
        else:
            return 0

    def get_id(self):
        return 3       
    
assert issubclass(ThresholdFunc, TransFunc)
assert isinstance(ThresholdFunc(), TransFunc)

#Класс нейрона
class Neuron:
    def __init__(self, count, trans):
        self.inputs=[0]*count 
        self.weights=[rnd.random()-0.5 for i in range(count+1)]
        self.trans=trans
        self.output=0

    #Рассчитать нейрон
    def compute(self):
        res=0
        i=1
        count=len(self.weights)
        while i<count:
            res = res+(self.weights[i] * self.inputs[i-1])
            i=i+1
        res=res+self.weights[0]
        self.output = self.trans.compute(res)

print('Нейрон с передаточной функцией "Абстрактная"');
neuron=Neuron(5, TransFunc())
neuron.inputs=[1,2,3,4,5]
print(neuron.inputs)
print(neuron.weights)
neuron.compute()
print(neuron.output)

print('Нейрон с передаточной функцией "Как есть"');
neuron=Neuron(5, AsIs())
neuron.inputs=[1,2,3,4,5]
print(neuron.inputs)
print(neuron.weights)
neuron.compute()
print(neuron.output)

print('Нейрон с передаточной функцией "Сигмоида"');
neuron=Neuron(5, SignFunc())
neuron.inputs=[1,2,3,4,5]
print(neuron.inputs)
print(neuron.weights)
neuron.compute()
print(neuron.output)

print('Нейрон с передаточной функцией "Пороговая"');
neuron=Neuron(5, ThresholdFunc())
neuron.inputs=[1,2,3,4,5]
print(neuron.inputs)
print(neuron.weights)
neuron.compute()
print(neuron.output)

В качестве абстрактного класса тут у нас класс передаточной функции. На его основе создаются конкретные передаточные функции, пока мы реализовали только пороговую, «как есть» и сигмоидную передаточную функции. Данный код содержит реализации этих функций, реализацию класса нейрона и тестовые примеры, при помощи которых можно проверить, как работает данный класс.

Где его можно применить? Если написать функцию обучения, то данный нейрон можно использовать как простейшую нейросеть типа «Адалин», которая решает простейшие линейно разделимые задачи классификации. Но мы этого делать не будем, а сразу начнем писать нормальную нейросеть, с несколькими слоями, которая будет обучаться через генетический алгоритм. но этим мы займемся на следующем уроке.

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar