CodeLab
145 subscribers
538 photos
20 videos
159 links
Говорим просто о сложном

Обсуждение, новости, материал и сплетни — все здесь https://t.me/CodeLabMLChat
Download Telegram
Друзья, готовлю крупный крутецкий пост, наберитесь терпения 🙏🙏
Please open Telegram to view this post
VIEW IN TELEGRAM
653
🔤🔤🔤🌹🔤🪷 🔤🔤🌷🌸🔤🌹🔤

👨‍💻Сегодня разберем код для простой нейросетки, которая по входным признакам будет определять пол человека.

⁉️ Что мы имеем?

🔵2 входа (две переменные для входных данных) — Input Layer

🔵Скрытый слой из 2 нейронов (h1 и h2) — Hidden Layers

🔵Выходной слой с 1 нейроном (o1) — Output Layer

🔵Также у нас будет функция обучения (для настройки веса нашей сети)

0⃣📱 Нейросеть будет написана с 0, поэтому импортируем одну лишь библиотеку — Numpy

import numpy as np


1⃣ Функция активации — сигмоида

def sigmoid(x):
return 1 / (1 + np.exp(-x))


🛍 В общем, эта штука называется функцией активации. Мы подаем данные и она преобразует его в диапазон от 0 до 1. По итогу вычислений, чем больше x, тем ближе он к единице. Также и в обратную сторону — чем меньше x, тем ближе к 0. Если же x = 0, вероятность 50% (наша нейронка будет не уверена в ответе).

2⃣ Производная сигмоиды (главная функция для гладиентного спуска):

def deriv_sigmoid(x):
fx = sigmoid(x)
return fx * (1 - fx)


‼️ Вот тут надо подробнее:

⚙️ Эта функция вычисляет, насколько сильно x влияет на результат. 📊 Это нужно для корректировки веса во время обучения (сюда включаем градиентный спуск)...
Please open Telegram to view this post
VIEW IN TELEGRAM
322
21
211
🧑‍💻Всем ку, продолжаем воркать:

3⃣ Создаем класс для нашей нейросети

class OurNeuralNetwork:


4⃣📊 Далее инициализируем веса (w) и смещения (b)

🧑‍💻 def __init__(self): — здесь init это конструктор класса, он вызывается автоматически при создании объекта (он задачет случайные веса и смещения для нашей нейросетки)

🧑‍💻 self — это ссылка на текущий объект класса (с помощью него класс получает доступ к переменным ниже)

🧑‍💻 w1, w2, w3, w4, w5, w6 — это веса связей между нейронами

🧑‍💻 b1, b2, b3 — это смещения (bias)

🧑‍💻 np.random.normal() — мы уже как то затрагивали такое, просто генерятся случайные числа

def __init__(self):
self.w1 = np.random.normal()
self.w2 = np.random.normal()
self.w3 = np.random.normal()
self.w4 = np.random.normal()
self.w5 = np.random.normal()
self.w6 = np.random.normal()

self.b1 = np.random.normal()
self.b2 = np.random.normal()
self.b3 = np.random.normal()


5⃣ Feedforward

🧠 Feedforward (прямое распространение, forward pass )это процесс обработки данных в нейронной сети , при котором информация движется лишь в одном направлении : от входного слоя через скрытые слои к выходному.


📇 Итак, нейросеть получает два числа x[0] и x[1], затем в скрытом слое вычисляется h1 (через w1, w2, b1) и h2 (через w3, w4, b2). Выходным слоев является o1 (итоговый ответ — предсказание нейросетки)

def feedforward(self, x):
h1 = sigmoid(self.w1 * x[0] + self.w2 * x[1] + self.b1)
h2 = sigmoid(self.w3 * x[0] + self.w4 * x[1] + self.b2)
o1 = sigmoid(self.w5 * h1 + self.w6 * h2 + self.b3)
return o1


6⃣ Backpropagation

⚙️ Обратное распространение ошибки (backpropagation) — это метод, который используется для обучения нейронных сетей путём минимизации ошибки предсказания


🧑‍💻 Итак, здесь learn_rate = 0.1 — это скорость обучения (чем выше, тем быстрее учится)

🧑‍💻 epochs = 1000 — количество эпох равное 1000 показывает сколько раз нейросеть пройдет через все данные

def train(self, data, all_y_trues):
learn_rate = 0.1
epochs = 1000


😴💤
Please open Telegram to view this post
VIEW IN TELEGRAM
432
Какой метод добавляет элемент в конец списка?
Anonymous Quiz
14%
insert()
79%
append()
7%
extend()
0%
pop()
311
👀
Please open Telegram to view this post
VIEW IN TELEGRAM
332
Сегодня пост, готовьтесь нах 🤬
Please open Telegram to view this post
VIEW IN TELEGRAM
3332
👨‍💻 Всем здарова, третий пост про нейроночку. Если вы чето не понимаете, в комментах сможем нормально обусдить. Прошлый пост 🔜 тут, а первый пост 🔜 тут.

7⃣📱 Прописываем цикл обучения для нейронки:

🧑‍💻 for epoch — это номер текущей эпохи (это по сути проход по всем данным обучения)

🧑‍💻 epochs — количество полных проходов по всем данным обучения

📇 Касаемо внутреннего цикла:

🧑‍💻 for x, y_true in zip(data, all_y_trues)

⚙️ data — входные данные

⚙️ all_y_truesнаши предсказанные ответы

⚙️ zip(data, all_y_trues) берет по одной паре (x, y_true) на каждой итерации (x — один входной пример) и y_true — его правильный ответ. ‼️ Если непонятно, то данная строка по сути соединяет входные данные и правильные ответы (или можно еще объяснить это так: 'модель по очереди берёт данные и их ответы для обучения')

for epoch in range(epochs):
for x, y_true in zip(data, all_y_trues):


8⃣🤯 Forward Propagation:

Forward propagation (также известное как прямой проход) — процесс передачи входных данных через слои нейронной сети для генерации вывода


📊 Итак, для начала, считаем суммы для нейронов скрытого слоя:

🧑‍💻 sum_h1 и sum_h2 — взвешенные суммы входных данных + смещение (b) Взвешенная сумма это сумма входных данных, умноженных на их веса, плюс смещение (bias)

🧑‍💻 h1, h2применяем сигмоиду, чтобы получить значения нейронов

🧑‍💻 sum_o1 — взвешенная сумма h1, h2 + смещение

🧑‍💻 o1 — результат после сигмоиды

🧑‍💻 y_pred = o1 — финальное предсказание

sum_h1 = self.w1 * x[0] + self.w2 * x[1] + self.b1
h1 = sigmoid(sum_h1)

sum_h2 = self.w3 * x[0] + self.w4 * x[1] + self.b2
h2 = sigmoid(sum_h2)

sum_o1 = self.w5 * h1 + self.w6 * h2 + self.b3
o1 = sigmoid(sum_o1)
y_pred = o1


0⃣ Производная функции ошибки MSE:

d_l_d_pred = -2 * (y_true - y_pred)


⚙️‼️Если вы спросите почему так, то данная строка это результат вычислений производной y_pred в формуле L = (y_true - y_pred)²

⚙️ Эта строка это в целом производная функции ошибки MSE (среднеквадратичной ошибки) по предсказанию (y_pred)

💤😴
Please open Telegram to view this post
VIEW IN TELEGRAM
333
🧑‍💻🧑‍💻 Регрессионные модели определяются их весами и смещением — параметрами модели. Однако перед обучением модели мы можем подкрутить множество других ручек, таких как скорость обучения,количество периодов, степень (если рассматривать модель полиномиальной
регрессии) и многие другие.
Они называются
гиперпараметрами.


🔵Любая величина, которую вы устанавливаете перед процессом обучения — это гиперпараметр;
🔵Любая величина, которую модель создает или изменяет в процессе обучения — это параметр.
Please open Telegram to view this post
VIEW IN TELEGRAM
522
Какой метод в библиотеке scikitlearn используется для разделения данных на обучающую и тестовую выборки?
Anonymous Quiz
64%
train_test_split()
18%
split_data()
18%
divide_dataset()
0%
data_split()
Какой из следующих параметров в линейной регрессии отвечает за наклон прямой?
Anonymous Quiz
45%
intercept
36%
slope
9%
coefficient
9%
bias
11
Какой показатель используется для оценки качества линейной регрессии?
Anonymous Quiz
0%
Precision
23%
F1-score
54%
R-squared
23%
Accuracy
111
Что выведет код?
my_dict = {'a': 1, 'b': 2, 'c': 3}
print(my_dict.get('d', 4))
Anonymous Quiz
8%
1
0%
2
58%
4
8%
3
25%
2765
111
a = [1, 2, 3]
b = a
b.append(4) print(a)
Anonymous Quiz
29%
[1, 2, 3]
53%
[1, 2, 3, 4]
0%
[4, 3, 2, 1]
18%
Ошибка
0%
[4]
211
Только попробуйте ответить неправильно
🧑‍💻 Сегодня пост
Please open Telegram to view this post
VIEW IN TELEGRAM
2
👨‍💻 Итак, завершаем посты с созданием несложной нейросети:

🔟⚙️ Обратное распространение ошибки (Backpropagation):

d_pred_d_w5 = h1 *  deriv_sigmoid(sum_o1)
d_pred_d_w6 = h2 * deriv_sigmoid(sum_o1)
d_pred_d_b3 = deriv_sigmoid(sum_o1)

d_ypred_d_h1 = self.w5 * deriv_sigmoid(sum_o1)
d_ypred_d_h2 = self.w6 * deriv_sigmoid(sum_o1)

d_h1_d_w1 = x[0] * deriv_sigmoid(sum_h1)
d_h1_d_w2 = x[1] * deriv_sigmoid(sum_h1)
d_h1_d_b1 = deriv_sigmoid(sum_h1)

d_h2_d_w3 = x[0] * deriv_sigmoid(sum_h2)
d_h2_d_w4 = x[1] * deriv_sigmoid(sum_h2)
d_h2_d_b2 = deriv_sigmoid(sum_h2)


📇 Итак, разберем пару строчек из кода выше 🔼:

🧑‍💻 d_pred_d_w5 = h1 * deriv_sigmoid(sum_o1) — здесь sum_o1 это взвешенная сумма (сумма входных данных, умноженных на их веса, плюс смещение (bias)) на выходном нейроне

🧑‍💻 deriv_sigmoid(sum_o1) — производная сигмоиды, показывающая, насколько sum_o1 влияет на o1

🧑‍💻 h1 — входное значение для w5

Если h1 большое, w5 сильнее влияет на o1


🧑‍💻 d_pred_d_w6 = h2 * deriv_sigmoid(sum_o1) — тут аналогично только для w6 (проще говоря, тут показано влияение w6 на o1)

🧑‍💻 Также аналогично и для b3 d_pred_d_b3 = deriv_sigmoid(sum_o1) ( влияние смещения на выход)

🧑‍💻 Следующая строка ( влияние h1 и h2 на o1) — d_ypred_d_h1 = self.w5 * deriv_sigmoid(sum_o1) — итак, здесь показано насколько вес w5 влияет на выход, для h2 выйдет аналогично...

🧑‍💻 Теперь влияние входных параметров (w1, w2, w3, w4, b1, b2) на скрытые нейроны (h1 и h2): d_h1_d_w1 = x[0] * deriv_sigmoid(sum_h1) — вес w1 умножается на градиент сигмоиды, аналогично будет для w2 и влияния смещения — d_h1_d_b1 = deriv_sigmoid(sum_h1)

🧑‍💻 Для второго скрытого нейрона (h2) будет тоже самое: d_h2_d_w3 = x[0] * deriv_sigmoid(sum_h2), аналогично для w4 и влияния смещения — d_h2_d_b2 = deriv_sigmoid(sum_h2)

📊 1⃣1⃣ Обновление весов (градиентный спуск)

🛍 Итак, здесь происходит корректировка параметров (мы их уже знаем — w1, w2, b1), отвечающих за первый нейрон скрытого слоя h1:

🗂 Чтобы вы не путались в переменных:

🧑‍💻 d_l_d_pred — градиент ошибки по выходу сети

🧑‍💻 d_ypred_d_h1 — влияние h1 на o1

🧑‍💻 d_h1_d_w1 и d_h1_d_w2, d_h1_d_b1 — влияние весов и смещения на h1

🔜 Каждый параметр уменьшается на некую величину, зависящую от градиентов и learn_rate (скорости обучения). Это делает предсказания точнее.


self.w1 -= learn_rate * d_l_d_pred * d_ypred_d_h1 * d_h1_d_w1
self.w2 -= learn_rate * d_l_d_pred * d_ypred_d_h1 * d_h1_d_w2
self.b1 -= learn_rate * d_l_d_pred * d_ypred_d_h1 * d_h1_d_b1


📊 Аналогично, обновляются веса второго нейрона (h2):

self.w3 -= learn_rate * d_l_d_pred * d_ypred_d_h2 * d_h2_d_w3
self.w4 -= learn_rate * d_l_d_pred * d_ypred_d_h2 * d_h2_d_w4
self.b2 -= learn_rate * d_l_d_pred * d_ypred_d_h2 * d_h2_d_b2


📊 Также аналогично и для обновления веса выхода (o1):

self.w5 -= learn_rate * d_l_d_pred * d_pred_d_w5
self.w6 -= learn_rate * d_l_d_pred * d_pred_d_w6
self.b3 -= learn_rate * d_l_d_pred * d_pred_d_b3


🗃 1⃣2⃣ Каждые 10 эпох будем отслеживать ошибку:

if epoch % 10 == 0:
y_preds = np.array([self.feedforward(x) for x in data])
loss = mse_loss(all_y_trues, y_preds)
print(f"Epoch {epoch} loss: {loss:.3f}")


*⃣ Вычисляются предсказания для всех входных данных

*⃣ Считается ошибка MSE (среднеквадратичная ошибка)

*⃣ Выводится прогресс (Epoch {epoch} loss: {loss:.3f})

1⃣3⃣ Подготовка данных:

Здесь мы имеем 4 примера и переменную all_y_trues, которая содержит правильные метки или ответы, тут, как вам удобно.

data = np.array([
[-2, -1],
[25, 6],
[17, 4],
[-15, -6]
])

all_y_trues = np.array([1, 0, 0, 1])


1⃣4⃣ Последний этап — создание и обучение нейронки

network = OurNeuralNetwork()
network.train(data, all_y_trues)
Please open Telegram to view this post
VIEW IN TELEGRAM
2211
А вот он и весь код:

🔤🔤🔤🌹🔤🪷 🔤🔤🌷🌸🔤🌹🔤

import numpy as np

def sigmoid(x):
return 1 / (1 + np.exp(-x))

def deriv_sigmoid(x):
fx = sigmoid(x)
return fx * (1 - fx)

def mse_loss(y_true, y_pred):
return ((y_true - y_pred) ** 2).mean()

class OurNeuralNetwork:
def __init__(self):
self.w1 = np.random.normal()
self.w2 = np.random.normal()
self.w3 = np.random.normal()
self.w4 = np.random.normal()
self.w5 = np.random.normal()
self.w6 = np.random.normal()

self.b1 = np.random.normal()
self.b2 = np.random.normal()
self.b3 = np.random.normal()

def feedforward(self, x):
h1 = sigmoid(self.w1 * x[0] + self.w2 * x[1] + self.b1)
h2 = sigmoid(self.w3 * x[0] + self.w4 * x[1] + self.b2)
o1 = sigmoid(self.w5 * h1 + self.w6 * h2 + self.b3)
return o1

def train(self, data, all_y_trues):
learn_rate = 0.1
epochs = 1000

for epoch in range(epochs):
for x, y_true in zip(data, all_y_trues):
sum_h1 = self.w1 * x[0] + self.w2 * x[1] + self.b1
h1 = sigmoid(sum_h1)

sum_h2 = self.w3 * x[0] + self.w4 * x[1] + self.b2
h2 = sigmoid(sum_h2)

sum_o1 = self.w5 * h1 + self.w6 * h2 + self.b3
o1 = sigmoid(sum_o1)
y_pred = o1

d_l_d_pred = -2 * (y_true - y_pred)

d_pred_d_w5 = h1 * deriv_sigmoid(sum_o1)
d_pred_d_w6 = h2 * deriv_sigmoid(sum_o1)
d_pred_d_b3 = deriv_sigmoid(sum_o1)

d_ypred_d_h1 = self.w5 * deriv_sigmoid(sum_o1)
d_ypred_d_h2 = self.w6 * deriv_sigmoid(sum_o1)

d_h1_d_w1 = x[0] * deriv_sigmoid(sum_h1)
d_h1_d_w2 = x[1] * deriv_sigmoid(sum_h1)
d_h1_d_b1 = deriv_sigmoid(sum_h1)

d_h2_d_w3 = x[0] * deriv_sigmoid(sum_h2)
d_h2_d_w4 = x[1] * deriv_sigmoid(sum_h2)
d_h2_d_b2 = deriv_sigmoid(sum_h2)

self.w1 -= learn_rate * d_l_d_pred * d_ypred_d_h1 * d_h1_d_w1
self.w2 -= learn_rate * d_l_d_pred * d_ypred_d_h1 * d_h1_d_w2
self.b1 -= learn_rate * d_l_d_pred * d_ypred_d_h1 * d_h1_d_b1

self.w3 -= learn_rate * d_l_d_pred * d_ypred_d_h2 * d_h2_d_w3
self.w4 -= learn_rate * d_l_d_pred * d_ypred_d_h2 * d_h2_d_w4
self.b2 -= learn_rate * d_l_d_pred * d_ypred_d_h2 * d_h2_d_b2

self.w5 -= learn_rate * d_l_d_pred * d_pred_d_w5
self.w6 -= learn_rate * d_l_d_pred * d_pred_d_w6
self.b3 -= learn_rate * d_l_d_pred * d_pred_d_b3

if epoch % 10 == 0:
y_preds = np.array([self.feedforward(x) for x in data])
loss = mse_loss(all_y_trues, y_preds)
print(f"Epoch {epoch} loss: {loss:.3f}")

data = np.array([
[-2, -1],
[25, 6],
[17, 4],
[-15, -6]
])

all_y_trues = np.array([1, 0, 0, 1])

network = OurNeuralNetwork()
network.train(data, all_y_trues)
Please open Telegram to view this post
VIEW IN TELEGRAM
4111