import time
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
def f(x): # Функция f(x)
return x * x - 5 * x + 5
def df(x): # Проивзодная функции f(x)
return 2 * x - 5
N = 20
xx = 0
lmd = 0.1
∇f(x) — стрелка вверх (т.е куда быстрее всего растет f) — это направление наискорейшего роста
-∇f(x) — направление наискорейшего убывания (в комментах материал)
Можем кстати подставить в нашу формулу пример
‼️ САМА СУТЬ — НАЙТИ ТОЧКУ, ГДЕ ДВИЖЕНИЕ ПРЕКРАЩАЕТСЯ (итерации прекращаются) — еще проще, найти глобальный минимум.
Совсем скоро продолжим
Please open Telegram to view this post
VIEW IN TELEGRAM
import numpy as np
import matplotlib.pyplot as plt
def f(x): # f(x) = x^2 - 5x + 5 # парабола
return x*x - 5*x + 5
def df(x): # f'(x) = 2x - 5 # наклон графика в точке x
return 2*x - 5
N = 20 # число итераций
x = 0.0 # стартовая точка x0
lr = 0.1 # шаг обучения (λ)
xs = np.linspace(-1, 5, 400)
fig, ax = plt.subplots() — будет создавать окошко Figure и систему координат Axes (сетка, подписи и две оси — x, y)ax.grid(True) — включает сетку на осяхax.plot(xs, f(xs), label="f(x)") — рисует линию функции f(x) по сетке xs. pt = ax.scatter([x], [f(x)], c='red', s=50) — рисует красную точку в текущем положении (x, f(x)) для визуализации текущего x на каждом шаге спуска. ax.set_xlim(xs.min(), xs.max()) — фиксирует границы оси X от минимума до максимума нашей сетки (таким образом, будем отображаться ровно тот интервал, где мы нарисовали кривую + масштаб во время анимации не будет прыгать)ax.set_ylim(f(xs).min()-1, f(xs).max()+1) — фиксирует границы оси Y по значениям функции. Почему берём min/max именно от xs и f(xs) plt.show(block=False) — показывает окно не блокируя выполнение кода.plt.ion()
fig, ax = plt.subplots()
ax.grid(True)
ax.plot(xs, f(xs), label="f(x)")
pt = ax.scatter([x], [f(x)], c='red', s=50)
ax.set_xlim(xs.min(), xs.max())
ax.set_ylim(f(xs).min()-1, f(xs).max()+1)
plt.show(block=False)
pt = ax.scatter([x], [f(x)], c='red', s=50) for _ in range(N):
x = x - lr * df(x) # шаг: x_{k+1} = x_k - λ f'(x_k)
pt.set_offsets([[x, f(x)]]) # кладет новые (x, y) в объект точки (грубо говоря, это обновление уже нарисованной точки, будет переносить маркер в новые корды)
fig.canvas.draw_idle() # Рисует содержимое окна ; перерисовывает
plt.pause(0.03) # фигура перерисовывается + пазуа
plt.ioff() # выключить интерактив
ax.scatter([x], [f(x)], c='blue', s=50, label="финал") # финальная точка (это куда мы пришли, глобальный минимум)
ax.axvline(2.5, ls='--', label="x* = 2.5") # вертикальная линия минимума
ax.legend()
print(x)
plt.show()
Please open Telegram to view this post
VIEW IN TELEGRAM
import numpy as np
# исходная функция, которую нужно аппроксимировать моделью a(x)
def func(x):
return 0.1 * x**2 - np.sin(x) + 5
# здесь объявляйте необходимые функции
coord_x = np.arange(-5.0, 5.0, 0.1) # значения по оси абсцисс [-5; 5] с шагом 0.1
coord_y = func(coord_x) # значения функции по оси ординат
sz = len(coord_x) # количество значений функций (точек)
eta = np.array([0.1, 0.01, 0.001, 0.0001]) # шаг обучения для каждого параметра w0, w1, w2, w3
w = np.array([0., 0., 0., 0.]) # начальные значения параметров модели
N = 200 # число итераций градиентного алгоритма
def features(x):
x = np.asarray(x)
return np.stack([np.ones_like(x), x, x**2, x**3], axis=1)
🔵 Функция np.asarray() в библиотеке NumPy — используется для преобразования входных данных в объект ndarray.🔵 ndarray (N-dimensional array) — класс многомерных массивов в библиотеке NumPy🔵 Входные данные могут быть в виде списков, кортежей или других объектов, похожих на массивы. Если входные данные уже являются массивом NumPy, функция не создаёт копию🔵 В нашем коде делает из входа (список/массив) numpy-вектор формы (n,).
А нужно это, чтобы дальше работали векторные операции x**2, x**3
np.ones_like(x) — делает массив единиц такой же формы и типа, как x. Это столбец для свободного члена w₀ — форма также (n, ) — т.е вектор из n единиц. В нашей функции признаков этот вектор из единиц идёт как первый столбецЧто такое формы (n,), (n,1), (n,4)
Я уже как-то разбирал данный момент, но вернуться стоит:
Please open Telegram to view this post
VIEW IN TELEGRAM
x = np.array([10., 20., 30.])
x.shape # (3, )
------------
[10. 20. 30.]
x_col = x.reshape(-1, 1)
x_col.shape # (3, 1)
------------
[[10.]
[20.]
[30.]]
S = np.column_stack([np.ones_like(x), x, x**2, x**3])
S.shape
-------------
[[ 1. 10. 100. 1000.]
[ 1. 20. 400. 8000.]
[ 1. 30. 900. 27000.]]
Please open Telegram to view this post
VIEW IN TELEGRAM
Что хотите дальше ❓
Anonymous Poll
36%
18%
9%
36%
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
CodeLab
👀 Всем ку, подписичники прибавились, а значит пора выложить пост. Я вдруг понял, что задачки с бинарной классификацией закончились, но поводов расстраиваться нет, ведь мы переходим к градиентному спуску.
Здесь, здесь, здесь и здесь мы уже рассмотрели эту…
Здесь, здесь, здесь и здесь мы уже рассмотрели эту…
Anonymous Quiz
0%
2.4
0%
3.4
80%
2.8
0%
3.2
0%
3.8
0%
3.6
20%
2.0
0%
1.8
def predict(w, x):
S = features(x)
return S @ w
S = features(x)
return S @ w
import numpy as np
def func(x): # Функция
return 0.1 * x ** 2 - np.sin(x) + 5
def features(x): # Матрица признков
x = np.asarray(x)
return np.stack([np.ones_like(x), x, x ** 2, x ** 3], axis = 1)
def predict(w, x): # a(x) = Sw
S = features(x)
return S @ w
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Love. Death. Transformers.
- так и че ты дум чат жпт нас всех убьет не
- аэээм бляяя юр тут как бы две стороны есть
- а программисты с ними че будет м
- нууу смотря какие тип там крутые или не оч там с опытом без
- а вот другие профессии чат жпт с ними что сделает а
- да тут яхззз на самом деле оно как то всегда само там разруливается
- оке я пон тя. в чем сила
- в любви
- аэээм бляяя юр тут как бы две стороны есть
- а программисты с ними че будет м
- нууу смотря какие тип там крутые или не оч там с опытом без
- а вот другие профессии чат жпт с ними что сделает а
- да тут яхззз на самом деле оно как то всегда само там разруливается
- оке я пон тя. в чем сила
- в любви
Друзья, сегодня пост, начинайте ждать ⌛️
Please open Telegram to view this post
VIEW IN TELEGRAM
def risk(w, x, y):
y_hat = predict(w, x) # считаем предсказания: S @ w
n = len(x) # количество точек (должно равняться len(y))
return (1.0 / n) * np.sum((y_hat - y) ** 2) # MSE
y_hat = predict(w, x)
x = [0, 1, 2]
ones_like = [1, 1, 1]
x**2 = [0, 1, 4]
x**3 = [0, 1, 8]
S = stack(ones, x, x**2, x**3, axis=1) =
[[1, 0, 0, 0],
[1, 1, 1, 1],
[1, 2, 4, 8]] # shape (3, 4) - форма массива
w = [1, 2, 0, 0] # shape (4,)
Предсказания равны:
y_hat = [1, 3, 5] # shape (3,)
func(0) = 0.1*0 - sin(0) + 5 = 5.00000
func(1) = 0.1*1 - sin(1) + 5 ≈ 0.1 - 0.84147 + 5 = 4.25853
func(2) = 0.1*4 - sin(2) + 5 ≈ 0.4 - 0.90930 + 5 = 4.49070
y ≈ [5.00000, 4.25853, 4.49070]
Ошибка e = y_hat - y ≈ [1-5, 3-4.25853, 5-4.49070] ≈ [-4.00000, -1.25853, 0.50930]
Квадраты: e**2 ≈ [16.00000, 1.5839, 0.2594]
Сумма: ≈ 16 + 1.5839 + 0.2594 = 17.8433
Среднее (делим на n=3): Q ≈ 17.8433 / 3 ≈ 5.9478
Please open Telegram to view this post
VIEW IN TELEGRAM
Друзья, занимался делами, теперь допишем пост для кода:
🧑💻 На данный момент наш код выглядит как-то так:
🟢 Давайте еще раз быстро пробежимся и закончим:
🔵 Функция? — Есть, за нее отвечает функция func()
🔵 Признаки мы тоже предусмотрели, за нее отвечает функция features(), входные признаки мы преобразовываем в numpy массив, и возвращаем матрицу признаков S (в матрице у нас столбец единиц — для bias, x, x², x³ ), короче говоря, features превращала каждый скаляр xᵢ в вектор признаков в вектор признаков.
🔵 Теперь нужна функция для прогноза — predict(). Функция вычисляет 🟰 a(x) = Sw 🟰 — по сути, умножение нашей матрицы S (переменной мы присваиваем значение матрицу) на вектор признаков w.
🔵 Теперь функция risk() — возвращает по-сути MSE — среднеквадратическая между предсказаниями и истинными значениями. Здесь подаем в функцию аж 3 аргумента — w (параметры модели, и это единственное, что мы меняем, risk() будет зависеть от w ⏺ x (входные данные по которым мы считаем признаки) и делаем предсказания y_hat — это вектор предсказаний (результат матричного умножения S @ w) ⏺ y — это истинные значения. Логика примерно такая: минимизируем функцию потерь по w, а x, y — это данные.
import numpy as np
def func(x):
return 0.1 * x ** 2 - np.sin(x) + 5
def features(x):
x = np.asarray(x)
return np.stack([np.ones_like(x), x, x ** 2, x ** 3], axis = 1)
def predict(w, x):
S = features(x)
return S @ w
def risk(w, x, y):
y_hat = predict(w, x)
n = len(x)
return (1.0 / n) * np.sum((y_hat - y) ** 2)
Please open Telegram to view this post
VIEW IN TELEGRAM