По мере того как искусственный интеллект становится все более популярным, все больше людей пытаются понять нейронные сети и то, как они работают. Чтобы проиллюстрировать, нейронные сети - это компьютерные системы, которые предназначены для обучения и совершенствования, что в некоторой степени связано с человеческим мозгом.
В этом блоге я покажу вам пример использования линейной регрессии в 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.
Спасибо за прочтение!