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

Обсуждение, новости, материал и сплетни — все здесь https://t.me/CodeLabMLChat
Download Telegram
🔤🔤🌹🌷 5️⃣

👨‍💻 Итак, продолжаем:

⚙️ Как я уже говорил в прошлом посте, мы имеем код, нам лишь остается его дописать. Но проблема в том. что есть много моментов, с которыми мы еще не работали, вот их и попытаемся понять. Итак, мы имеем такой код:

import numpy as np

np.random.seed(0) # псевдослучайные числа образуют одну и ту же последовательность (при каждом запуске)
x = np.arange(-1.0, 1.0, 0.1) # аргумент [-1; 1] с шагом 0,1

size_train = len(x) # размер выборки
w = [0.5, -0.3] # коэффициенты модели
model_a = lambda m_x, m_w: (m_w[1] * m_x + m_w[0]) # модель
loss = lambda ax, y: (ax - y) ** 2 # квадратическая функция потерь

y = model_a(x, w) + np.random.normal(0, 0.1, len(x)) # целевые значения


‼️ Главный вопрос в том, что мы хотим? Мы уже имеем простую модельку 🟰 y = w₀ + w₁ * x 🟰. Нам нужно найти эмпирический риск с помощью MSE.

🧠 Эмпирический риск — это средняя величина ошибки алгоритма на обучающей выборке.

🟰 Q(a, X) = 1/n * ∑ loss(a, yᵢ) 🟰 — Формула среднего эмпирического риска.

🟰 loss(a, yᵢ) = (a(xᵢ , w) − yᵢ)² 🟰— Квадратическая функция потерь.

🟰 a(x,w) = w₀ + w₁ ⋅ x 🟰 — Параметрическая модель с параметрами w₀ = 0.5 w₁ = -0.3

🟰 yᵢ = w₀ + w₁ * xᵢ + ϵᵢ 🟰 i = 1, 2, ..., n 🟰


🧑‍💻 Касаемо первых строк ничего нового. просто импорт и просто установка 🟰 np.random.seed(0) 🟰для генератора случайных чисел (одни и те же значения каждый раз).

🧑‍💻🟰 x = np.arange(-1.0, 1.0, 0.1) 🟰 — Создаём массив x значений от -1.0 до (не включая) 1.0 с шагом 0.1, получаем [-1.0, -0.9, -0.8, ..., 0.9] и так 20 значений

🧑‍💻 🟰 size_train = len(x) 🟰 У нас это значение равно 20

🧑‍💻 🟰 w = [0.5, -0.3] 🟰 — веса модели (коэффициенты линейного уравнения), 🔗 w[0] = 0.5 — это смещение (bias, свободный член), 🔗 w[1] = -0.3 — это наклон (slope) — определяет, вверх или вниз идёт прямая. ➡️ Получаем модель 🟰 y = 0.5 - 0.3x 🟰

🧑‍💻‼️ Теперь очень важно, 🟰model_a = lambda m_x, m_w: (m_w[1] * m_x + m_w[0]) 🟰Это лямбда-функция, то есть функция в одну строку, она строит модель линейной регрессии (нашу прямую на плоскости) — 🟰 a(x,w) = w₀ + w₁ ⋅ x 🟰

🔵m_x — массив аргументов (это наш x)

🔵m_w — массив весов (в нашем случае w = [0.5, -0.3])

⚙️ "Берем x, умножаем на второй коэффициент w (то есть наклон), и прибавляем первый коэффициент (смещение)"


Как это работает? Это не наш случай, данные немного отличаются, поэтому показываю на примере:

m_x = np.array([1, 2, 3])  
m_w = [0.5, -0.3]

# Если мы подставим:

model_a(m_x, m_w) → (-0.3 * m_x + 0.5)

# Получаем:

y = -0.3 * np.array([1, 2, 3]) + 0.5

# Сами вычисления:

-0.3 * [1, 2, 3] = [-0.3, -0.6, -0.9]
[-0.3, -0.6, -0.9] + 0.5 = [0.2, -0.1, -0.4]
Please open Telegram to view this post
VIEW IN TELEGRAM
432
🔤🔤🌹🌷 6️⃣


🧑‍💻 Теперь функция потерь: 🟰 loss = lambda ax, y: (ax - y) ** 2 🟰

🔵 ax — это предсказания модели: a(x, w), как вы помните, оно равно 🟰 a(x,w) = w₀ + w₁ ⋅ x 🟰

🔵 y — это реальные значения

⚙️ Квадрат разницы между y_pred и y будет равен:

🟰 loss(a, yᵢ) = (a(xᵢ , w) − yᵢ)² 🟰

🧑‍💻 🟰 y = model_a(x, w) + np.random.normal(0, 0.1, len(x)) 🟰

🔵 🟰 model_a(x, w) 🟰 — предсказываем идеальные значения, которые дала бы наша линейная модель.

🔵 np.random.normal(0, 0.1, len(x)) 🟰 — создаём шум:

распределение: нормальное (гауссовское)

среднее = 0 → в среднем шум не искажает

стандартное отклонение = 0.1 → поэтому шум у нас слабый

длина = столько же, сколько в x

🧑‍💻 🟰 Q = loss(model_a(x, w), y).mean() 🟰

🔵 🟰 model_a(x, w) 🟰 — снова предсказываем значения на основе модели

🔵 🟰 loss(...) 🟰 — получаем массив ошибок (в квадрате) между предсказанием и y.

🔵 🟰 .mean() 🟰 — берём среднее значение всех этих ошибок

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

Q(y_pred, yᵢ)) = 1/n * ∑ loss(y_pred, yᵢ) вот мы и получили эмпирический риск
Please open Telegram to view this post
VIEW IN TELEGRAM
3321
🔤🔤🌹🌷 7️⃣

👨‍💻 Итак, друзья, вы уже увидели этот график в комментариях к прошлому посту (надеюсь, хотя код вывода графика не подразумевает. Так вот сейчас мы это и исправим..

⚙️ Код мы сильно изменять не будет, достаточно добавить несколько строчек:

🧑‍💻 Добавим библиотеку seaborn:

📱 Seaborn — библиотека для создания статистических графиков на языке Python. Она построена на основе библиотеки Matplotlib и тесно интегрирована со структурами данных из Pandas.


import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np


🧑‍💻 Теперь изменим немного последние строки и сам вывод, все остальное остается неизменным:
y_pred = model_a(x, w)
Q = loss(y_pred, y).mean()


sns.lineplot(x = x, y = y_pred, color = 'red')
sns.scatterplot(x = x, y = y)
plt.show()


‼️🧑‍💻 Теперь хотел поговорить немного про логику самого кода:

📇 Если возвращаться к ламбде, то вот эта строка: 🟰 model_a = lambda m_x, m_w: (m_w[1] * m_x + m_w[0]) 🟰— может выглядеть и вот так:
def model_a(m_x, m_w):
return m_w[1] * m_x + m_w[0]


🔵 И когда мы вызываем 🟰 model_a(x, w), 🟰 мы передаем

m_x = x
m_w = w


🧑‍💻 Аналогично будет и со 2 функцией:

def loss(y_pred, y):
return (y_pred - y) ** 2


⚙️ y мы получаем со строки 🟰y = model_a(x, w) + np.random.normal(0, 0.1, len(x))🟰

⚙️ y_pred — предсказанные значения (из model_a)

🧑‍💻 Весь код:

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(0)

x = np.arange(-1.0, 1.0, 0.1)

size_train = len(x)
w = [0.5, -0.3]
# model_a = lambda m_x, m_w: (m_w[1] * m_x + m_w[0])

def model_a(m_x, m_w):
return m_w[1] * m_x + m_w[0]

# loss = lambda y_pred, y: (y_pred - y) ** 2

def loss(y_pred, y):
return (y_pred - y) ** 2

y = model_a(x, w) + np.random.normal(0, 0.1, len(x))

y_pred = model_a(x, w)
Q = loss(y_pred, y).mean()

sns.lineplot(x = x, y = y_pred, color = 'red')
sns.scatterplot(x = x, y = y)
plt.show()
Please open Telegram to view this post
VIEW IN TELEGRAM
4321
🧑‍💻Друзья, немного приболел, но новый пост уже в процессе
Please open Telegram to view this post
VIEW IN TELEGRAM
421
👨‍💻 Итак, новый пост, так что возрадуемся! Я внатуре чета приболел нехило, но щас чувствую себя получше. Разбираем новое задание:

🌷🔤🔤🔤

0⃣‼️ Нам нужно вычислить коэффициенты w модели: a(x,w) = w₀ + w₁ ⋅ x. Также нам нужно в коде сформировать обучающую выборку X в виде матрицы: 📎 1 x₁ 📎
📎 1 x₂ 📎
📎 1 x₃ 📎
и вычислить коэффициенты w, используя Q (средний эмпирический риск при MSE)
.

🔤🔤🌹🔤🔤🪷🔤🔤

1⃣:

🟰Q(a, X) = 1/n * (X * w - Y)²🟰— Эмпирический риск при квадратической функции потерь

🟰∂Q(a, X)/ ∂w = 2/n * Xᵀ (X * w - Y) = 0🟰— Дифференцируем выражение по вектору w

🟰w = (Xᵀ * X)⁻¹ * Xᵀ * Y🟰— Находим вектор по w

2⃣‼️ Что важно понимать? Мы хотим найти уравнение прямой: y = w0 + w1 * x, так вот, в матричном виде это будет выглядеть вот так: y = X @ w

3⃣⚙️ Теперь делаем все с примером, возьмем рандомные значения X и Y:

X = [[1, 1],
[1, 2],
[1, 3]]

Y = [[2.1], — Это наши True значения
[2.9],
[3.8]]

4⃣🛍 Теперь считаем по формуле 🟰w = (Xᵀ * X)⁻¹ * Xᵀ * Y🟰:

4⃣.1⃣ Считаем Xᵀ X:

Xᵀ = [[1,1,1],[1,2,3]]

Xᵀ @ X =
[[1, 1, 1], [[1, 1],
[1, 2, 3]] x [1, 2],
[1, 3]]

= [[1*1 + 1*1 + 1*1, 1*1 + 1*2 + 1*3],
[1*1 + 2*1 + 3*1, 1*1 + 2*2 + 3*3]]


= [[3, 6],
[6, 14]]


4⃣.2⃣ Считаем Xᵀ Y:

Xᵀ Y = [[1,1,1],[[2.1],[1,2,3]]x[2.9],[3.8]]=[[1∗2.1+1∗2.9+1∗3.8],[1∗2.1+2∗2.9+3∗3.8]]=[[8.8],[19.3]]

4⃣.3⃣ Теперь собираем формулу 🟰w = (Xᵀ * X)⁻ ¹ * Xᵀ * Y🟰:

🟰 Xᵀ X = [[3, 6], [6, 14]] 🟰

🟰 Xᵀ Y = [[8.8], [19.3]] 🟰

4⃣.4⃣ Теперь ищем обратную 2x2 матрицу, опять же, все по формулам!

🟰 [[a,b], [c,d]]⁻ ¹ =1 / (ad−bc) ∗ [[d,−b], [−c,a]] 🟰

🔤🔤🔤 Таак, надеюсь вам все понятно, а если нет, то комменты открыты, спрашивайте на здоровье.

‼️ Чтобы найти обратную матрицу 2×2, нам нужно вычислить детерминант, вот формула:

🟰det = ad − bc🟰

🟰det = 3 ⋅ 14 − 6 ⋅ 6 = 42 − 36 = 6 🟰— Подставляем и получаем 6 (наш знаменатель )

🟰 (XᵀX)⁻ ¹ = (1/6) * [[14, -6],
[-6, 3]]
🟰

4⃣.5⃣ Умножаем:

📊 w = (1/6) * [[14, -6],
[-6, 3]] @ [[8.8],
[19.3]] = [[7.4],
[5.1]]



🔗 Теперь получаем модель 🟰y ≈ 1.233 + 0.85 ∗ x🟰

🧑‍💻 w₀ = 1.233 — смещение (bias)

🧑‍💻 w₁ = 0.85 — коэффициент наклона

🌹🔤🔤🔤🪷🌷

Завтра +- все это мы интерпретируем в виде кода, там полегче будет намного. Даже эта писанина сверху — это не сложно, просто попытайтесь вникнуть в то, что я написал.
Please open Telegram to view this post
VIEW IN TELEGRAM
5432
💬 С какого устройства вы просматриваете канал?
Anonymous Poll
67%
Телефон
33%
Пк
👨‍💻 Всем ку! Сегодня пишем продолжение этого поста. В прошлый раз, напомню вам, мы разобрали задание буквально на атомы (со стороны математики), теперь мы разберем 🧑‍💻 код...(нам нужно если че вычислить коэффициенты w модели: a(x,w)

0⃣🧠 Так ну первые строчки расписывать смысла мало, импортируем 📱нампай, устанавливаем random.seed (чтобы при каждом выполнении, результаты не менялись) и создаем массив от -1 до 1с шагом 0.1:

import numpy as np

np.random.seed(0) # Здесьможем ставить любое число в скобки

x = np.arange(-1.0, 1.0, 0.1) # будет вот так - [-1. , -0.9, -0.8, ..., 0.8, 0.9]


1⃣📊 Теперь генерируем y_true (это наши придуманные настоящие значения):

Y = -5.2 + 0.7 * x + np.random.normal(0, 0.1, len(x))

# w0 = -5.2 — сдвиг

# w1 = 0.7 — коэффициент наклона

# np.random.normal(0, 0.1, len(x)) — случайный шум с нормальным распределением (среднее 0, стандартное отклонение 0.1)


2⃣‼️ Теперь важно: у нас есть Y, являющийся одномерным вектором (такая вот у него структура - (20,)), поэтому превращаем его в вектор-столбец формы (20, 1). А делаем мы так, потому что нам нужно будет использовать матричное умножение (попозже будет пример и поймете).

3⃣📊 Строим матрицу признаков:

X = np.column_stack((np.ones(len(x)), x))


⚙️ Теперь она будет выглядеть так:

X =
[[ 1. -1. ]
[ 1. -0.9]
..............
[ 1. 0.9]]


4⃣🛍 Остается лишь найти вес w и задача готова:

w = np.linalg.inv(X.T @ X) @ X.T @ Y



‼️ Теперь ооочень важно, самое важное ‼️

👨‍💻 Объясню как можно проще: у нас был X и Y, выглядят они в начале вот так:

x = [-1.  -0.9 -0.8 ... 0.9]    # (20,)

Y = [-5.14 -5.05 -4.79 ... -4.58] # (20,)


🔵 То есть структура у них следующая:

x.shape == (20,)
Y.shape == (20,)


🔵 Затем, делаем из Y вектор-столбец:

Y = Y.reshape(-1, 1)  # (20, 1)


🔵 Что касаемо X, мы создаем его со свободным членом (это который b). А вот и та самая строка:

X = np.column_stack((np.ones(len(x)), x))  # (20, 2)


🔵 И вот так будут выглядеть наши данные:

X =
[[ 1. -1. ]
[ 1. -0.9]
...
[ 1. 0.9]]


🔵 Теперь наша моделька должна найти w0, и w1, то есть w = [w0, w1], тут нужно поподробнее:

w = np.linalg.inv(X.T @ X) @ X.T @ Y


🟰 L(w) = |Y - X @ w|² 🟰 — мы минимизируем функцию суммы квадратов ошибки, берем производную по w и как результат получаем:

🟰 w = (Xᵀ @ X)⁻ ¹ @ Xᵀ @ Y 🟰— подробнее мы рассмотрели в прошлом посте

🌹🔤🔤🔤🪷🌷

5⃣‼️ Подводим итог:

Y (20,) был одномерный, применили reshape и сделали его вектор-столбцом (20, 1) чтобы работать с умножением. Также и x был (20,), а стал матрицей X с двумя столбцами (20, 2). ЕДИНИЧКИ мы добавили. потому что в Y у нас прописано -5.2 (это наш свободный член), вот его мы и учитываем (поэтому добавляем столбец единиц).

⚙️ Затем мы решили вот это уравнение 🟰 w = (X.T @ X)^(-1) @ X.T @ Y 🟰и получили:


w = [[w0],
[w1]]


X.shape = (20, 2)

Y.shape = (20, 1)

w.shape = (2, 1)

X @ w = (20, 1) — наши предсказания!
Please open Telegram to view this post
VIEW IN TELEGRAM
4322
👨‍💻 Друзья, каналу ровно ГОД! Всех Вас я поздравляю, мы двигались и будем двигаться дальше

🌸🔤🌹🔤 🌸🔤🌹🔤 🌸🔤🌹🔤 🌸🔤🌹🔤
Please open Telegram to view this post
VIEW IN TELEGRAM
8432
👨‍💻 Друзья, пока что готовлю пост, выйдет в скором времени!
Please open Telegram to view this post
VIEW IN TELEGRAM
1
👨‍💻 У нас есть матрица признаков X размера (n, d) и целевой вектор y размера (n, 1).
Какой матричной формулой находятся оптимальные веса w в задаче линейной регрессии? 📱
Anonymous Quiz
8%
w = X^(-1) * y
17%
w = X.T * y
67%
w = (X.T @ X)^(-1) @ X.T @ y
8%
w = X @ X.T @ y
1111
👨‍💻 Итак, всем супер привет, новое задание от Тайлера Дердена:

📈 На рисунке в комментах представлена разделяющая линия в пространстве двух признаков x₁ x₂. ⚙️ Точками отмечены координаты, через которые проходит линия. Размер клеток по каждой из координат равен 1. Нам нужно (АНАЛИТИЧЕСКИ) вручную вычислить по графику вектор параметров, ...

🟰 w = [w₁, w₂, w₃]ᵀ 🟰

... которым описывается изображенная разделяющая линия в соответствии с выражением:

🟰 w₁ * x₁ + w₂ * x₂ + w₀ = 0 🟰

🧠 Вооот, а нам нужно накодить такую штуку, которая будет выводить значение вектора w в виде списка или кортежа:

0⃣📇 Первое, что вы должны сделать, это залезть в комменты этого поста. Дальше вы увидите график, в котором нужно определить координаты точек:

x1, y1 = -3, 1
x2, y2 = 3, 5


1⃣ Кайф, точки определили, теперь решим задание, но для начала, попробуем без кода:

⚙️ Формулу вы уже и сами знаете: 🟰 y = kx + b 🟰

‼️ Теперь важно, потому что дальше вы можете подумать, как будете выполнять данное задание, решение будет позже:

📊 Чтобы понять, как изменяется y в зависимости от x, нам нужно НАЙТИ угловой коэффициент:

🟰 k = (y₂ - y₁) / (x₂ - x₁) 🟰

Пока что вам задание подставить значения и получить готовое уравнение прямой:
Please open Telegram to view this post
VIEW IN TELEGRAM
3221
🧑‍💻🧑‍💻 Йоу, завтра постараюсь сделать пост, так что ждите
Please open Telegram to view this post
VIEW IN TELEGRAM
4441
👨‍💻 Йоу воссап друзья! Как и обещал, пишу — вот кстати прошлый пост (советую начать с него):

2⃣🧑‍💻 Я сказал вам в прошлом посте, чтобы вы нашли угловой коэффициент (чего вы конечно не сделали)

🟰 k = (y₂ - y₁) / (x₂ - x₁) 🟰— вот даже формула есть, поэтому дерзаем:

🟰 k = (5 - 1) / (3 - (-3)) = 4 / 6 = 2/3 🟰

3⃣⚙️ Теперь находим смещение b (всегда ориентируемся по этой формуле 🟰 y = kx + b 🟰)

Напомню, что в прошлый раз мы нашли точки:

🔵x1, y1 = -3, 1
🔵x2, y2 = 3, 5

Так вот, подставляем первую точку (-3, 1)

🟰 b = y - kx 🟰

🟰 b = 1 - (2/3) * (-3) = 1 + 2 = 3 🟰 — подставляем

🟰 y = (2/3) * x + 3 🟰— получаем такое уравнение прямой

🟰 y - (2/3) * x - 3 = 0 🟰 — домножим на 3, чтобы избавиться от дроби

🟰 3y - 2x - 9 = 0 🟰

🟰 -9 - 2x + 3y = 0 🟰

⚙️ w = [-9, -2, 3] — получаем такую штуку, она и будет ответом для нашей задачи. У меня есть еще пару вариантов решений, еще нужно будет код разобрать, а я пошел спать
Please open Telegram to view this post
VIEW IN TELEGRAM
5531
Какой из векторов весов НЕ соответствует уравнению прямой y = (2/3)x + 3?
Anonymous Quiz
44%
w = [1, 1, -1]
22%
w = [6, 4/3, -2]
22%
w = [3, 2/3, -1]
11%
w = [-9, -2, 3]
1111
Что будет после выполнения?

import numpy as np a = np.array([1, 2, 3]) b = a b[0] = 99
Anonymous Quiz
23%
a = [1, 2, 3]
69%
a = [99, 2, 3]
0%
a = [0, 2, 3]
8%
Ошибка, нельзя присваивать массивы напрямую
2221
👨‍💻 Сегодня постараюсь замутить пост
Please open Telegram to view this post
VIEW IN TELEGRAM
532
👨‍💻 🧑‍💻 Не так давно в этом посте мы начали рассматривать ГРАДИЕНТНЫЙ СПУСК. Вы уже заметили, что в последнее время градиентный спуск стал неотъемлемой темой в моих постах. 🤯 Тема очень важная и разбирать нам ее придется очень и очень долго... Ладно, не будем о плохом, держите очередную непонятную формулу (ее мы кстати уже рассмотрели в этом посте):

0⃣🟰 θ = θ − 𝜂 ⋅ ∇ J (θ)🟰

🧑‍💻 𝜃 — параметры модели (веса)

🧑‍💻 𝜂 — learning rate (шаг обучения)

🧑‍💻 J(θ) — функция потерь

🧑‍💻∇₀J(θ) — градиент этой функции по параметрам

👨‍💻 Так вот, все, что мы рассмотрели — это был градиентный спуск (Batch). Что за batch? Это один из видов градиентного спуска, можно сказать, что он базовый.

1⃣ Теперь переходим к SGD:

🔤🔤🔤

🔤🌷🔤🔤🔤🔤🔤🌷🔤🔤

🔤🌹🔤🔤🔤🔤🔤🌷

🔤🔤🔤🔤🔤🔤🌷

⚙️ На каждой итерации берёт один случайный пример из датасета и делает шаг в направлении уменьшения ошибки.


🟰θ = θ − 𝜂 ⋅ ∇₀ J (θ; xᵢ ; y ᵢ)🟰

🧑‍💻 𝜃 — параметры модели (веса)

🧑‍💻 𝜂 — learning rate (шаг обучения)

🧑‍💻x ; yᵢ — случайная обучающая пара

🧑‍💻 J(θ; ᵢ ; yᵢ) — функция потерь на этой паре

🟰 L(w, b) = 1/2 * (y - (wx + b))² 🟰

Дальше будем считать градиенты, а пока спать
💤😴
Please open Telegram to view this post
VIEW IN TELEGRAM
2221
🙏
Please open Telegram to view this post
VIEW IN TELEGRAM
6321
🧑‍💻 Сегодня пост постараюсь замутить крутецкий, желания ваши, кстати, можете писать в комментариях, вполне возможно, что они учтутся
Please open Telegram to view this post
VIEW IN TELEGRAM
4221