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

В этом блоге я покажу вам пример использования линейной регрессии в Python (код на https://github.com/anaypant/LinearRegression/tree/master)

Чтобы узнать больше о нейронных сетях, посмотрите это видео от 3Blue1Brown, чтобы узнать больше:

В машинном обучении есть много разных типов алгоритмов, которые используются для разных задач. Сегодня я покажу вам то, что известно как линейная регрессия. В линейной регрессии ожидаемые входные данные - это числа, а также выходы.

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

Перво-наперво, как мы будем использовать веса (синапсы) нашей модели, чтобы найти приблизительный результат? Мы сделаем это, используя простую формулу:

Это простая, но эффективная формула. Для тех, кто не знал, в этом уравнении выход (y) равен входу (x), умноженному на наклон (m) + смещение или точку пересечения по оси y (b).

Для дальнейшего понимания посетите этот веб-сайт: http://www.math.com/school/subject2/lessons/S2U4L2GL.html#:~:text=The%20equation%20of%20any%20straight,line%20crosses % 20the% 20y% 20axis.

Для нашей модели линейной регрессии мы точно настроим два параметра в этом уравнении: наклон и смещение.

Кодирование модели линейной регрессии

Теперь мы увидим нашу модель линейной регрессии в Python!

- - Примечание редактора: - -

Вам НЕ потребуются какие-либо внешние библиотеки / пакеты для этой модели. Однако это очень упрощенная версия, поэтому не стесняйтесь добавлять свои собственные изменения в код.

Начнем с кода:

lass linearregression():
    def __init__(self, x, y, iteration):
       self.x = x
       self.y = y
       self.epoch = iteration
       self.m = 1
       self.b = 0
       self.learn = 0.01

Это первая часть нашего кода. Здесь мы инициализируем класс на Python. Чтобы описать, класс похож на «тип» в Python. Из этого класса его можно использовать для создания нескольких «объектов».

Для получения более подробной информации о классах посетите это видео от CS Dojo:

В этом классе мы получаем от пользователя 3 ввода: значение X, значение Y и итерации.

Если бы мы воспринимали это с координатной плоскости, значение x было бы значениями x, а значения y были бы соответствующими координатами y на плоскости. Каждый вход представляет собой список элементов, каждая соответствующая пара элементов создает координату (как в геометрии!)

Итерации в данном случае - это количество циклов, которые мы хотим, чтобы наша модель обучалась. Я установил 1000, но вы можете изменить это число.

Здесь мы также устанавливаем некоторые начальные значения в функции __init__. Наши самые важные ценности - это значения m и b. Эти два значения являются настраиваемыми (они будут меняться в зависимости от поправки, которую мы им даем).

Переходим к следующей части нашей модели!

def feedforward(self):
   self.output = []
   for i in range(len(self.x)):
      self.output.append(self.x[i] * self.m + self.b)

В этом коде мы создаем функцию прямой связи. Feedforward означает «опробовать» вашу модель, даже если она не обучена. «Выходы» здесь хранятся в соответствии со списком. (Также обратите внимание, что наше уравнение используется здесь!)

Feedforward устанавливает значения и необходимые шаги, чтобы узнать, что думает наша модель. Тогда мы увидим, насколько мы ошибаемся, и извлечем уроки из этого.

Переходим к следующей части нашего кода!

def calculate_error(self):
   self.totalError = 0
   for i in range(len(self.x)):
      self.totalError += (self.y[i] - self.output[i]) ** 2 
   self.error **= 1/2
   self.error = float(self.totalError / float(len(self.x)))
   return self.totalError / float(len(self.x))

В этом коде мы вычисляем ошибку нашей модели!

Мы инициализируем полную ошибку в этой функции. Эта переменная будет содержать ошибку нашего кода. как нам это сделать? Итак, мы берем среднее значение всех ошибок!

В терминах Python мы выполняем итерацию с помощью цикла «for». На каждой итерации мы добавляем ошибку истинного значения (y) за вычетом прогнозируемого значения нашей модели (выходных данных). Теперь у нас есть ошибка нашей модели.

## ПРИМЕЧАНИЕ:

## В этой функции вы можете заметить, что мы возводим в квадрат значение ошибки каждой итерации! Почему? В функции мы хотим, чтобы все значения ошибок были положительными (отрицательные * отрицательные = положительные).

Более того, мы ищем не столько «ценность» ошибки, сколько «величину». В квадрате величина ошибки увеличивается ».

Теперь перейдем к самому сложному фрагменту кода:

Стохастический градиентный спуск !!

def gradient_descent(self):
   self.b_grad = 0
   self.m_grad = 0
   N = float(len(self.x))
for i in range(len(self.x)):
   self.b_grad += -(2/N) * (self.y[i] - ((self.m * self.x[i]) + self.b))
   self.m_grad += -(2/N) * self.x[i] * (self.y[i] - ((self.m * self.x[i]) + self.b))
self.m -= self.learn * self.m_grad
self.b -= self.learn * self.b_grad

Теперь я знаю, что это выглядит сложно (это не когда к этому привыкаешь!)

Давайте делать это шаг за шагом.

Стохастический градиентный спуск - это функция, которая выполняет итерацию по значению и быстро минимизирует ошибку. Как? По сути, он создает миниатюрную ванну, которой затем манипулирует наша модель. Мы пробуем несколько разных способов их оптимизации, а затем находим самый быстрый.

Вот изображение формулы, используемой в стохастическом градиентном спуске:

Сначала я заблудился в этой теме, поэтому обратился за помощью к Википедии и другим веб-сайтам:

(Https://en.wikipedia.org/wiki/Stochastic_gradient_descent#Iterative_method)

Сначала мы инициализируем два основных фактора: m_grad (градиент для наклона) и b_grad (градиент для b). Это будут минимальные значения, вычисленные нашей функцией здесь.

Чтобы сделать его не таким ошеломляющим, как на картинке выше, я постараюсь сделать его проще.

ДЛЯ СКОРОСТИ (B): У нас есть уравнение y = m * x + b, также известное как наши результаты. Затем мы находим простую ошибку y минус результат и умножаем ее на предустановленную производную, найденную гениями мира (-2 / N, где N - количество элементов в нашем списке).

ДЛЯ НАКЛОНА (M): это буквально то же самое, что формула для смещения, но мы умножаем выход на входы [x]. Мы перебираем КАЖДЫЙ ввод для обоих, поэтому добавляем к каждому из них (вот почему мы НЕ используем переменную ошибки из более раннего прямо сейчас, поскольку она имеет только положительные значения).

И это стохастический градиентный спуск! (Вид… )

Если вы все еще невежественны (и я вас не виню), посмотрите это видео от 3blue1brown.

Следующая часть кода!

def backprop(self):
self.error = self.calculate_error()
self.gradient_descent()

Это довольно простой код; мы просто вызываем наши предыдущие функции и группируем их в эту функцию обратного распространения.

Обратное распространение - это общий термин для поиска ошибки вашей модели и последующего внесения необходимых изменений для извлечения уроков из нее.

Теперь… ИТОГ ПОЛНЫЙ (также доступен на моей странице github в начале)

import matplotlib.pyplot as plt
class linearregression():
def __init__(self, x, y, iteration):
# Initializing some variables
self.x = x
self.y = y
self.epoch = iteration
# These are the tuned parameters to make our model better
self.m = 1
self.b = 0
# This is how fast we want out model to grow
self.learn = 0.01
def feedforward(self):
self.output = []
for i in range(len(self.x)):
self.output.append(self.x[i] * self.m + self.b)
def calculate_error(self):
self.totalError = 0
self.trueError = 0
for i in range(len(self.x)):
self.totalError += (self.y[i] - self.output[i]) ** 2 # The reason we square is for all error values to be positive.
self.error = float(self.totalError / float(len(self.x)))
return self.totalError / float(len(self.x))
def gradient_descent(self):
self.b_grad = 0
self.m_grad = 0
N = float(len(self.x))
for i in range(len(self.x)):
self.b_grad += -(2/N) * (self.y[i] - ((self.m * self.x[i]) + self.b))
self.m_grad += -(2/N) * self.x[i] * (self.y[i] - ((self.m * self.x[i]) + self.b))
self.m -= self.learn * self.m_grad
self.b -= self.learn * self.b_grad
def backprop(self):
self.error = self.calculate_error()
self.gradient_descent()
def predict(self):
while True: # This can be taken off if you don't want to predict values forever
self.user = input("\nInput an x value. ")
self.user = float(self.user)
self.ret = self.user * self.m + self.b
print("Expected y value is: " + str(self.ret))
def train(self):
for i in range(self.epoch):
self.feedforward()
self.backprop()
self.predict()

Длинный код, правда? Ну не совсем.

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

Спасибо за прочтение!