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

Обсуждение, новости, материал и сплетни — все здесь https://t.me/CodeLabMLChat
Download Telegram
3221
👨‍💻 Всем желаю здравия, продолжаем пост про АЛГОРИТМ ПЕРСЕПТРОНА.

2⃣ В прошлом посте мы разобрали функцию score(). Напомню, формула у нас такая:

🟰 score(x) = w₁ * x₁ + w₂ * x₂ + .... wₙ * xₙ + b 🟰

🔵features(x) — входные данные, признаки объекта

🔵weight(w) — параметры модели

🔵bias(b) — смещение

‼️ Если представить, что у нас 2 признака (x₁ и x₂): веса (это w) будут определять наклон прямой. bias(b) — расположение прямой, features(это координаты x) — это просто точка, которую мы проверяем, по какую сторону прямой она лежит.

📱 В общем, def score()функция для вычисления линейной комбинации признаков, на выходе просто получаем любое вещественное число, если очень коротко, это сырая оценка нашей модели (насколько сильно точка тянет в сторону класса 1 или 0)



3⃣ Хорошо, теперь следующая функция — step(x):

def step(x):
if x >= 0:
return 1
else:
return 0


‼️ Это пороговая функция активации, на вход функция берет число (например, результат score()). А на выходе возвращает 1 или 0. Если score >= 0 → класс 1, если score < 0 → класс 0.

4⃣ def prediction()

⚙️ Итак, это функция предсказаний, она по сути комбинирует предыдущие 2 функции и выдает 0 или 1 (класс метки).

📱 То есть, берем входные (фичи, веса и смещение) ➡️ сначала вызывается функция score(), возвращает она число (где точка относительно линии) ➡️ это число сразу же подается в step(), которая возвращает 0 или 1 ➡️prediction() возвращает результат как итоговое предсказание.


def prediction(weights, bias, features):
return step(score(weights, bias, features))


5⃣ Функция ошибки def error():

def error(weights, bias, features, label):
pred = prediction(weights, bias, features)
if pred == label:
return 0
else:
return np.abs(score(weights, bias, features))


🔵 pred = prediction(weights, bias, features) — Для начала, модель делает предсказания для точки (это функция выше: 0 ил 1).

🔵 if pred == label: — Сравниваем предсказание с настоящей меткой label (label была выше)

🔵Если предсказание = метка: возвращаем 0, если нет, то ошибка будет равна абсолютному значению score()

🔵return np.abs(score(weights, bias, features)) — Берем по модулю

🧑‍💻 Пока что вот так получается код:

from matplotlib import pyplot as plt
import numpy as np
import random
import utils

features = np.array([[1,0],[0,2],[1,1],[1,2],[1,3],[2,2],[2,3],[3,2]])
labels = np.array([0,0,0,0,1,1,1,1])


utils.plot_points(features, labels)


def score(weights, bias, features):
return features.dot(weights) + bias

def step(x):
if x >= 0:
return 1
else:
return 0

def prediction(weights, bias, features):
return step(score(weights, bias, features))

def error(weights, bias, features, label):
pred = prediction(weights, bias, features)
if pred == label:
return 0
else:
return np.abs(score(weights, bias, features))
Please open Telegram to view this post
VIEW IN TELEGRAM
3221
Forwarded from Denis Sexy IT 🤖
Самое главное забыл - показали чехол для поездок в Барселону, наконец-то 👍
Please open Telegram to view this post
VIEW IN TELEGRAM
222
👀
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Бэкдор
This media is not supported in your browser
VIEW IN TELEGRAM
Открываем ЛЮБЫЕ домофоны с ChatGPT — нейронка поможет попасть в подъезд, если вы случайно забыли ключи.

Все просто:

1️⃣ Показываем нейронке домофон в режиме видео.
2️⃣ ИИ выдаст код для открытия ЛЮБОГО домофона. Мы проверили, в России работает на УРА!

Сохраняйте фичу.

👍 Бэкдор
Please open Telegram to view this post
VIEW IN TELEGRAM
👨‍💻Всем привет, друзья! Долго меня не было, админ как всегда решает кучу вопросов.

🧑‍💻 Прикреплю код с прошлого поста, чтобы вы вспомнили о чем вообще идет речь (код - АЛГОРИТМ ПЕРСЕПТРОНА)

from matplotlib import pyplot as plt
import numpy as np
import random
import utils

features = np.array([[1,0],[0,2],[1,1],[1,2],[1,3],[2,2],[2,3],[3,2]])
labels = np.array([0,0,0,0,1,1,1,1])


utils.plot_points(features, labels)


def score(weights, bias, features):
return features.dot(weights) + bias

def step(x):
if x >= 0:
return 1
else:
return 0

def prediction(weights, bias, features):
return step(score(weights, bias, features))

def error(weights, bias, features, label):
pred = prediction(weights, bias, features)
if pred == label:
return 0
else:
return np.abs(score(weights, bias, features))


6⃣ Функция подсчета средней ошибки персептрона — mean_perceptron_error()

def mean_perceptron_error(weight, bias, features):
total_error = 0
for i in range(len(features)):
total_error +- error(weight, bias, features[i], labels[i])
return total_error / len(features)


‼️ Объявляем функцию ➡️затем счетчик total_error ➡️цикл по всем точкам ➡️ после цикла делим сумму на количество объектов ➡️получаем среднюю ошибку по выборке

🟢Можем глянуть на примере:

weights = [1, 2] # Начальные веса
bias = -4 # Смещение

for i in range(len(features)): # Проходим по всем точкам
print(prediction(weights, bias, features[i]), error(weights, bias, features[i], labels[i]))


7⃣ Функция perceptron_trick() — функция для обучения модели

🔵 Тут можно выделить короткую версию кода и длинную, начнем с короткой:

def perceptron_trick(weights, bias, features, label, learning_rate = 0.01):
pred = prediction(weights, bias, features)
for i in range(len(weights)):
weights[i] += (label - pred) * features[i] * learning_rate
bias += (label - pred) * learning_rate
return weights, bias


🔵 pred = prediction(weights, bias, features) — считаем предсказание (0 или 1) для текущей точке

🔵Напомню, что predictions() — это функция, которая позволит понять, 'по какую сторону' границы оказалась точка.

🔵weights[i] += (label - pred) * features[i] * learning_rate — Итак, важная строчка — ведь это обновление весов. Как это работает

⚙️ Если модель угадала (например, label=1, pred=1 или label=0, pred=0), то label - pred = 0 ➡️ веса не меняются.

🔵Если модель ошиблась:

label=1, pred=0 ➡️ label - pred = 1 ➡️ веса увеличиваются (подтягиваем границу ближе к этой точке).

label=0, pred=1 ➡️ label - pred = -1 ➡️ веса уменьшаются (отталкиваем границу от этой точки).


🔵bias += (label - pred) * learning_rate — а тут идет обновление нашего смещения. работает по тому же принципу что и веса.

⚙️ Смещение bias двигает границу вверх/вниз (или влево/вправо), чтобы лучше разделять классы


🔵Возвращаем новые параметры — return weights, bias

Как то так 💤
Please open Telegram to view this post
VIEW IN TELEGRAM
5221
0⃣🧑‍💻Друзья, ща мини пост будет. Я как то на днях разбирал деревья решений и решил скинуть Вам код:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier, export_text # Это и есть наше дерево решений
from sklearn.metrics import accuracy_score # Метрика для деревьев
from sklearn.model_selection import train_test_split # разделили данные

rng = np.random.default_rng(42)


1⃣ Генерим данные:

n = 300
mean0 = [-1.0, 0.0] # Часть точек находится в этом диапазоне
mean1 = [1.3, 0.8] # Часть точек в этом
cov = [[0.7, 0.2], #
[0.2, 0.6]]

X0 = rng.multivariate_normal(mean0, cov, size = n // 2) # по 150 точек на класс
X1 = rng.multivariate_normal(mean1, cov, size = n // 2)

#
X = np.vstack([X0, X1])
y = np.hstack([np.zeros(n // 2), np.ones(n // 2)])


🔵Матрица ковариации (ковариационная матрица, дисперсионно-ковариационная матрица) — это квадратная матрица, которая количественно оценивает, как изменяются две переменные относительно друг друга.

🔵Речь идет про переменную cov — она задает разброс и наклон точек

🔘Диагональ ([0,0] и [1,1]) — дисперсия по каждой оси ➡️ ширина по X и по Y.

🔘Вне диагонали ([0,1] и [1,0]) — ковариация ➡️ показывает, наклонены точки или нет.


🔵 Тут можно поподробнее, у нас есть ковариационная матрица:

cov = [[0.7, 0.2],
[0.2, 0.6]]


🔘Можете чекнуть формулу дисперсии так вот это среднее «квадратичное отклонение» значений от их среднего.

🔘Если по-простому: насколько сильно данные «размазаны» вокруг среднего значения.

🔵В ковариационной матрице:

🔘Диагонали (верхний левый и нижний правый) = дисперсии (разброс по каждой оси отдельно).

🔘Вне диагонали (верхний правый и нижний левый) = ковариации (как связаны оси друг с другом) — они одинаковые

🔵Следующим этапом идем смотреть формулу корреляции (Формула корреляции:

(Определение коэффициента корреляции Пирсона)

‼️ Ковариация и корреляция — понятия в статистике, которые отличаются тем, что ковариация измеряет степень, в которой две переменные меняются вместе, а корреляция — не только степень, но и направление отношения между переменными.


Чтобы Вам было понятно, зададим такой вопрос:

Растут ли две величины вместе или одна вверх, другая вниз?

🔘Если ковариация положительная ➡️ X и Y вместе растут.

🔘Если отрицательная ➡️ X растёт, Y падает.

🔘Если около 0 ➡️ связи почти нет.

‼️ Проблема в том, что ковариация зависит от единиц измерения. Чтобы от такой проблемы избавиться ➡️ придумали корреляцию — делить ковариацию на масштабы разброса X и Y.
🔘Эти масштабы — стандартные отклонения (корни из дисперсий).

🧑‍💻 Например:

🔵Пусть у нас 3 человека:

🔘Рост (X): [1, 2, 3] метра, среднее — 2

🔘Вес (Y): [2, 4, 6] кг, среднее — 4

🔘Если подставим в формулу — получим 1.33 — Ковариация положительная, X и Y растут вместе. Но если мы пересчитаем ковариацию в сантиметрах или граммах, она вырастет в 100 раз!!!

🔵Дисперсия же говорит: насколько в среднем значения расходятся от среднего (разброс).

🔵Стандартное отклонение (σ) — это корень из дисперсии, то есть тот же разброс, но в тех же единицах, что и данные.

🔵Если у роста σ ≈ 10 см → большинство людей будут ±10 см от среднего.

🔵Если у веса σ ≈ 15 кг → большинство людей будут ±15 кг от среднего.


🧑‍💻 Пока что вот так...
Please open Telegram to view this post
VIEW IN TELEGRAM
422
Друзья, кулити, скоро напишу пост 🧑‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
611
Сейчас рассматриваю вариант изменить формат постов: ЛИБО чаще выходят, но небольшие, ЛИБО большие, но выходить будут реже.
👨‍💻 Признайтесь, думали, что я больше НЕ НАПИШУ Давно меня не было, но пора бы продолжить вещать Вам про ML! За время своего отсутствия я ничуть не отупел и все также занимался, но без Вас. А также ХОЧУ ВНЕСТИ ПРАВКУ: попробуем сделать посты покороче, чтобы их было удобнее делить и, возможно, понимать и не теряться. ‼️ НЕ ЗАБЫВАЙТЕ ПРО ССЫЛКИ, ведь их будет теперь больше, чтобы вы могли разобраться в материале еще и САМИ

⚙️ В прошлый раз мы поговорили про ковариацию, корреляцию и, как вообще выглядят наши данные.

‼️ СМОТРИМ ТУТ

🟢Теперь, что касаемо обучения, нам нужно ПОДЕЛИТЬ НАШИ ДАННЫЕ — делаем это с помощью функции train_test_split():

Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3,
random_state=7, stratify=y)


🟢Теперь поговорим про функцию train_test_split(), что она делает — В функцию мы ПЕРЕДАЕМ ДВА МАССИВА, X (матрица признаков), y (вектор целевых меток), а ВОЗВРАЩАЕТ функция четыре массива:

🔵Xtr — обучающие признаки

🔵Xte — тестовые признаки

🔵ytr — обучающие метки

🔵yte — тестовые метки


🟢 Работает функция ПО ПОЗИЦИЯМ АРГУМЕНТОВ. то есть, на входе подается матрица признаков X — на выходе X_train, x_test. Аналогично с y — на входе массив меток, а на выходе — y_train, y_test.

‼️ То есть, функция ВСЕГДА возвращает по два массива на каждый входной аргумент — сначала train, потом test.

🟢Теперь углубимся в работу функции: она создает индексы всех строк X — [0, 1, 2, ..., n-1]. Выглядит это как то так:

idx: 0 1 2 3 4 5
X = [x0, x1, x2, x3, x4, x5]
y = [y0, y1, y2, y3, y4, y5]


NEXT POST ➡️
Please open Telegram to view this post
VIEW IN TELEGRAM
5222
👨‍💻 Дорогие мои подписичники, вот и подошел к концу мой отдых, пора писать посты! У меня произошло много всего разного, как-нибудь обязательно ВАМ расскажу, а пока разберем задание с нашего любимого курса Сергея Балакирева на степике. Условие задания (скрины с самого степика и ссылка на задание будет в комментах):

Итак. чего нас вообще просят сделать? У нас есть обучающая выборка из точек: x = (x₁, x₂) и метки y ∈ {+1, -1}

🔵Нам нужно подобрать параметры прямой (разделяющей линии):

‼️ w₁ * x₁ + w₂ * x₂ + w₀ = 0

🔵Чтобы вектор параметров был (этот наш вектор весов и будет задавать разделяющую прямую выше ⬆️):

‼️ w = [w₀, w₁, w₂]ᵀ

📊 Итак. давайте рассмотрим то условие, которое нам дал автор курса:

0⃣🔵Задаем функцию loss и берем логарифмическую функцию потерь:

import numpy as np 

def loss(w, x, y):
M = np.dot(w, x) * y
return np.log2(1 + np.exp(-M))


‼️Тут давайте поподробнее — M = np.dot(w, x)это обычное скалярное прозведение wᵀx. Чтобы понять правильно функцию ниже, разберем пример на простых цифрах:

🔵Пусть у нас будут известны w, x:

w = [1, -1]

x = [2, 1]


🔵Теперь посчитаем скалярное произведение:

w * x = 1 * 2 + (-1) * 1 = 2 - 1 = 1


🔵 Теперь представим, что y = +1:

M = (w * x) * y = 1 * 1 = 1


‼️ СЧИТАЕМ LOSS:

L =  log₂(1 + e ⁻ ʷᵀ ˣ ʸ)

L = log₂(1 + e⁻ᴹ)

L = log₂(1 + e⁻¹)

e⁻¹ = 0.37

L = log₂(1 + 0.37) = 0.45


‼️ Сделаем вывод, что ошибка у нас МАЛЕНЬКАЯ.

Итак, а теперь представим что y = - 1 (то есть w * x нам давал значение 1, сама обученная наша модель якобы так посчитала, а вот y (целевое значение) равен -1) — то есть в реальности у нас класс другой. Попробуем посчитать, учитывая что класс у нас ошибочный:

L = log₂(1 + e⁻(⁻¹))

L = log₂(1 + e¹)

L ≈ 1.894


ЧТО МЫ ПОЛУЧИЛИ? Число большое, модель ошиблась и штраф будет больше. Итак, наша M — это показатель того, насколько наша модель права. Если знак правильный, M > 0, loss будет минимальный и наоборот.

💤 Скоро увидимся
Please open Telegram to view this post
VIEW IN TELEGRAM
11❤‍🔥3👀3🤬2
👨‍💻Привет, мои подписичники! Сегодня продолжаем писать код и разбирать задачи использования SGD при бинарной классификации. В ПРОШЛОМ ПОСТЕ мы разобрали всего одну функцию, зато как... Сегодня, надеюсь, одной функцией не обойдется:

🟢 Если вкратце, прошлый пост был про loss и смысл величины M (определяли знак). Наша модель считала одно число wᵀx и по знаку этого числа она (модель) решает: класс + 1 или - 1. Также ввели величину M (если знак совпал с меткой — модель права, и наоборот). В конце разобрали логарифмическую функцию потерь:
return np.log2(1 + np.exp(-M))


‼️Теперь, наша задача — НАУЧИТЬ МОДЕЛЬ подбирать веса так, чтобы ошибок было меньше:

1⃣ Следующая функция будет отвечать за производную (градиент df). Работа этой функции будет отвечать на вопрос: 'Как менять веса w, чтобы Наш loss уменьшался?'

🟢Сама функция дана по условию, но разобрать ее стоит:

def df(w, x, y):
M = np.dot(w, x) * y
return -(np.exp(-M) * x.T * y) / ((1 + np.exp(-M)) * np.log(2))


🟢Для начала, напомню:

‼️ Мы дифференцируем вот эту ⬇️ самую функцию потерь. Здесь расписывать будет слишком долго. поэтому можете взять листочек и сами нечеркать! Нам по сути нужно получить ∂L/∂w, так что деразайте.

L =  log₂(1 + e ⁻ ʷᵀ ˣ ʸ) 

L = log₂(1 + e⁻ᴹ) # Функция потерь для одной точки


🟢В коде наша производная будет выглядеть именно так:

return -(np.exp(-M) * x.T * y) / ((1 + np.exp(-M)) * np.log(2))


Так, что теперь? M = y * (wᵀ x) — как и раньше (просто показатель, права модель/не права).

2⃣ Дальше, нам определенно нужны данные:

data_x = [(3.0, 4.9), (2.7, 3.9), (3.0, 5.5)....

data_y = [1, -1, 1, -1, -1.....


🔵 data_x — это наши обучающие точки, где каждый элемент это пара чисел (координаты на плоскости)

🔵data_y — это метки или целевые переменные (тут либо + 1, либо -1)

3⃣ Подготавливаем данные:

x_train = np.array([[1, x[0], x[1]] for x in data_x])
y_train = np.array(data_y)


🔵У нас data_x — это просто список кортежей (x1, x2). А мы каждый такой кортеж приводим к виду: (1, x1, x2). Зачем? — Чтобы учесть свободный коэффициент, bias — этим занимается строка с x_train

🔵y_train — это просто список меток классов +1/-1

4⃣ Некоторые параметры (даны по условию)

🔵 Размер обучающей выборки (сколько всего у нас обучающих точек)
n_train = len(x_train)  


🔵 Начальные весовые коэффициенты (стартовые веса)

w = [0.0, 0.0, 0.0]  


🔵Теперь, шаг обучения (lr) отдельно для каждого веса

nt = np.array([0.5, 0.01, 0.01])  


🔵Значение параметра лямбда для вычисления скользящего экспоненциального среднего Qe (Это что-то типа сглаживания для нашего loss, автор ставит значение 0.01 для сильного сглаживания)

lm = 0.01  


🔵Число итераций алгоритма (каждая итерация это взятие случайно точки, вычисления градиента и обновления весов)

N = 1000


5⃣ Мы потихоньку ПОДХОДИМ К КОНЦУ задачи:

‼️Qe — это и есть сглаженная ошибка (экспоненциальное среднее loss).

Qe = 0 


🔵 Генерация одинаковых последовательностей чисел (с таким мы сталкивались уже много)

np.random.seed(0)


6⃣ ГЛАВНЫЙ ЦИКЛ:

for n in range(N):
k = np.random.randint(0, n_train - 1)
Qe = lm * loss(w, x_train[k], y_train[k]) + (1 - lm) * Qe
w = w - nt * df(w, x_train[k], y_train[k])

Q = (np.dot(x_train, w) * y_train < 0).mean()


‼️Итак, мы делаем N итераций обучения нашего алгоритма (каждая итерация = шаг стохастического градиентного спуска).

🟢 k = np.random.randint(0, n_train - 1) — Здесь мы берем случайный индекс k и выбираем один объект из выборки данных (вся суть SGD)

🟢Qe = lm * loss(w, x_train[k], y_train[k]) + (1 - lm) * Qe — Это формула экспоненциального скользящего среднего (если грубо говоря — это просто сглаженная ошибка)

🟢 w = w - nt * df(w, x_train[k], y_train[k])САМОЕ ГЛАВНОЕ, обновляем градиент (Градиент 'указывает', в какую сторону растет ошибка (на то он и градиент), а мы идем в противоположную сторону)

7⃣ ФИНАЛЬНЫЙ Q

Q = (np.dot(x_train, w) * y_train < 0).mean()


‼️Таак, тут у нас проглядывается знакомая формул M = y * (wᵀ x), а именно в этой части строки — (np.dot(x_train, w) * y_train

Тг не дает больше объяснять 😢
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥6👀2🤬1
Не дай бог кто то ответит неправильно
Скоро пост ⌛️
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥3