Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 30
×

Туториал по полиномиальной регрессии на TensorFlow

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Лучший способ понять полиномиальную регрессию — это вернуться к линейной регрессии. Итак, давайте сначала сделаем несколько случайных дата поинтов.

Случайные точки данных

import numpy as np
import matplotlib.pyplot as plt
 
dataNum = 100 # Кол точек
 
x = np.linspace(-3, 3, dataNum) # Делаем случайные точки
y = np.sin(x) + np.random.uniform(-0.5, 0.5, dataNum)
 
plt.plot(x,y, 'bo') # Изображаем точки на графике
plt.show()

Теперь давайте посмотрим, как будет себя вести линейная регрессия.

Линейная регрессия

import tensorflow as tf
 
X = tf.placeholder("float") 
Y = tf.placeholder("float") 
 
w = tf.Variable(np.random.randn(), name = "w") 
b = tf.Variable(np.random.randn(), name = "b") 
 
learning_rate = 0.01
training_epochs = 300
 
# y = wx + b (формула нашей линии)
y_pred = tf.add(tf.multiply(X, w), b) 
  
# MSE
loss = tf.reduce_mean(tf.square(y_pred - Y))
  
# Gradient Descent Optimizer 
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss) 
  
# Инициализируем переменные
init = tf.global_variables_initializer()
 
# Тренировка модели
with tf.Session() as sess: 
    sess.run(init) 
 
    for epoch in range(training_epochs): 
        # Передаем каждую точку оптимизатору
        for (ix, iy) in zip(x, y): 
            sess.run(optimizer, feed_dict = {X : ix, Y : iy})   
      
    # Возвращаем натренированные коэффициенты 
    weight = sess.run(w) 
    bias = sess.run(b) 
 
# Создаем линию по коэффициентам  
line = weight * x + bias 
 
# Изображаем линию на графике 
plt.plot(x, y, 'bo', label ='Original data') 
plt.plot(x, line, 'k', label ='Fitted line') 
plt.title('Linear Regression') 
plt.legend() 
plt.show()

Мы видим, что, поскольку наши данные не линейны, даже наилучшая линия не может правильно заполнить все данные. Эта проблема недостаточно обученной модели также известна как недообучение или underfit. Это в основном означает, что наша модель слишком проста или недостаточно обучена, как в примере выше. Вот откуда приходит идея полиномиальной регрессии. Она позволяет нам построить более сложную линию, такую ​​как квадратичная кривая, кубическая кривая или любая другая кривая. Давайте посмотрим, как полиномиальная регрессия работает с нашими случайными точками данных.

Полиномиальная регрессия

sub_plt = plt.subplot() 
sub_plt.scatter(x, y, label = 'Original data')
plt.draw()
 
X = tf.placeholder("float")
Y = tf.placeholder("float")
 
# Тут основная часть полиномиальной регрессии
# Вместо того, чтобы использовать линейную формулу: y = wx + b
# Мы используем формулу кривой: y = x^n + x^(n-1) + ... + x + b
# Где n это степень нашей кривой
degree = 3
y_pred = tf.Variable(tf.random_normal([1]), name='bias')
for powi in range(1, degree + 1):
    W = tf.Variable(tf.random_normal([1]), name='Wpowi')
    y_pred = tf.add(tf.multiply(tf.pow(X, powi), W), y_pred)
 
learning_rate = 0.01
training_epochs = 1000
 
loss = tf.reduce_sum(tf.square(y_pred - Y)) / (dataNum)
 
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
 
init = tf.global_variables_initializer()
 
with tf.Session() as sess:
    sess.run(init)
 
    prevLoss = 0.0
    # Тренировка
    for epoch in range(training_epochs):
        for (ix, iy) in zip(x, y):
            sess.run(optimizer, feed_dict={X: ix, Y: iy})
 
        # Подсчет потерь
        currentLoss = sess.run(loss, feed_dict={X: x, Y: y})
 
        # Когда модель начинает медленно учится - останавливаем
        # И возвращаем последний результат
        if np.abs(prevLoss - currentLoss) < 0.0001:
            sub_plt.plot(x, y_pred.eval(feed_dict={X: x}, session=sess),'k', 
                         label = 'Fitted line')
            print('Loss:', currentLoss)
            break
        prevLoss = currentLoss
 
# Строим график
sub_plt.set_ylim([-3, 3])
plt.title('Polynomial Regression') 
plt.legend() 
plt.show()
Loss: 0.09154288

Это гораздо лучше. Теперь мы видим, что полиномиальная регрессия используется, когда наши данные не распределены линейно, поэтому мы строим кривую, которая лучше соответствует данным. Теперь, в примере полиномиальной регрессии, мы остановили нашу модель, когда разница между предыдущими и текущими потерями была очень маленькой. Такой прием используется, чтобы не оверфитится на данные.

Чтобы понять, что такое overfit и underfit, нам нужно немного погрузиться в математику.

Смещение vs Разброс

Смещение (bias) означает, что у нас есть ошибка прогноза, потому что наша модель не может уловить все паттерны в данных. Например, если наши данные выглядят как кубическая кривая, линейная регрессия не сможет уловить все данные, и, следовательно, наши потери будут высокими. Сильное смещение возникает, когда модель недостаточно натренирована (underfit).

Разброс (variance) означает, что у нас есть ошибка прогноза, потому что наша модель перетренирована, поэтому она очень хорошо работает с тренировочными данными, но не так хорошо с тестовыми данными. Когда модель оверфитится, возникает большой разброс.

Заключение

Несколько вещей, которые следует запомнить из этого урока:

  1. Если вам нужно построить линию регрессии для некоторых случайных данных или данных, которые соответствуют некоторому правилу (экспоненциальному, квадратичному, кубическому ...), вам, возможно, придется использовать полиномиальную регрессию.
  2. Старайтесь недопускать overfit и underfit. Это сильно повлияет на точность предсказаний. Для этого можно как в примере выше специально останавливать обучение, когда изменения небольшие чтобы избежать перетренеровок.
👍ПодобаєтьсяСподобалось1
До обраногоВ обраному8
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Оффтоп немного:

Мобильные видеокарты на лептопах для целей любительского датасаенса и прочей хайперформанс матстатистики. Кто-то сталкивался с подводными камнями? Например: хорошо, ты молодец, что написал свой чудный cuda код и отлично что он показывает хороший перформанс у тебя дома, но наши клаудсервера предпочитают иные идиомы.

#gear_acquisition_syndrome

Смотреть на чипсет и поддерживаемые версии cuda/opencl/opengl/vulkan. Всё упирается в Shader Model — это всего лишь набор инструкций чипа карточки — есть ли ветвления, какая глубина, сколько итераций цикла разрешено при выполнении программы. Мобильные карточки идентичны десктопным по функциям, уступают по производительности, и греются как печка под нагрузкой, так как радиатор маленький.

Но вообще как тебе ниже написали, нужно понимать юзкейс. Поклацать готовую модель, поискать на видео потоке красный шарик — хватит и лаптопа. Прогнать большие объемы данных через модель, например сделать симуляцию много-камерного зрения как у теслы, либо (я лет 5 назад делал задачу) — обучить модель для поиска и трекинга людей в толпе (pose-independent head detection) — тут не обойтись без десктопного железа как минимум, обучение занимает очень много времени, а его надо каскадами делать несколько раз на данных.

Да, наверное с юзкейса и стоило бы начинать, но он пока очень сырой, все еще эксплорю доменную область, а там такие глубины, что аж бездны :)

Я скажу більше, будь-яка більш менш серйозна чисельна задача потребує потужного заліза. Добре якщо це тільки один декстоп, а не десять.

Спасибо за отзыв!

недавно я видел на тематическом форуме с туториалами, как дядя датасаентист себе почти на 10к сыров набрал: towardsdatascience.com/...​-workstation-bd39c2f687e2

Но теперь уверен, что лучше в сторону PC аккуратно посмотреть, так чтобы 30 лет ипотеку не платить :)

Достатньо подивитись ціну однієї тесли v100, яка під 8к стоїть.

Та да, маркетингові маневри нвідеа.

Не тільки, по факту єдине рішення де 32 гб відеопам’яті (так раніше точно було)

Облака віл дрейн май покетс. Девайс хоть продать можно

Я ба більше скажу, деякі сітки дуже чутливі до розміру батчу, і треба уже не одна карта, а стійка з 4-8 карт для того щоб добре навчити модель.

Есть еще облака. Гугл Колаб в какой-то степени бесплатен.

Google Colab Pro за 10$ в месяц очень не плох, сессия длится 24 часа, всегда доступен и можно запускать 2е сессии с GPU.
Подключается Google Drive(если нужно туда докупить места) и хранить там свои датасеты и промежуточные результаты обучения и модели.

За такие деньги я не знаю где найти подобный хостинг для ML, пробовал vast.ai — разочаровал.

дуже плюсую за колаб — сам ним користуюсь, просто шикарний інструмент.

вот кстати да, и с CPU тоже могут быть те же проблемы. помнится, как-то долго не мог понять, почему лаптоп вдруг стал тормозить — а потом увидел CPU frequency = 0.14 GHz :)
что, впрочем, не отменяет полезность GPU в лаптопе для отладки и тестирования моделей на CUDA

Ноутбучна карта тільки для навчання(свого, а не нейронки) підходить. Те що слабенька то таке, там відеопам’яті мало. Більшість моделей не вийде запустити тренуватись.

Це гарний приклад як робити не треба. Існує багато речей на яких можна продемонструвати роботу з TensorFlow, але не поліноміальна регресія з використанням градієнтного спуску. Для низьких порядків її можна в декілька строк на numpy написати через коваріації/варіації виразити або виразити коеф з формули найменших квадратів(і тут теж декілька строк в numpy). Або використати напряму метод найменших квадратів чи інший, але не градієнтний спуск. Візьміть ряд якийсь чи MNIST, розберіть простий приклад з рекурентною сіткою чи згортковою, щось таке для чого дійсно треба така велика штука як TensorFlow.

Ви праві. Простих прикладів дійсно багато, але візьми ти і розбери якийсь приклад, перероби під своїм соусом і виклади. Це теж норм, це не плагіат. Дуже багато англомовних курсів, їх теж можна перекладати. Тут не так давно був пост по МЛ, людина теж явно не професіонал, але було цікаво читати чисто тому, що був якийсь унікальний експіріенс.

Якщо не знаєш що можна зробити, можна якусь задачку з hackerrank розібрати по МЛ. Там правда більше на сайкіт, але є такі що і на тензорі виглядатимуть актуально.

через коваріації/варіації виразити

А де можна про такий спосіб почитати?

Спасибо большое!

JFYI, результаты выдачи гугла недетерминистичны и зависят от юзер-ейджента, географического расположения, языка выдачи и прочих персональных печенек

Та да, понимаю. если мне есть чем гордиться, так это хоум страницами на ютубе и спотифай и шоппинг рекомендациями на амазоне

Ааа, дяка. Почитал. С моей точки зрения, шило на мыло из-за фундаментальных причин: en.m.wikipedia.org/...​i/Principal—agent_problem

У тебя в кеше контекст не тот ;)

Я про юзать гугл или утю для поиска в интернете

На англ вікіпедії точно є, але красиво розписано у статті якою нижче поділився Віталій habr.com/ru/post/514818 розділ статистика

спасибі на добрім слові. ту статтю написав мій товариш за мотивами однієї з лекцій, яку я читаю студентам. репозитарій, на який вона посилається, теж наша спільна робота — я видаю його студентам як розширений конспект лекцій.

так я ж і задоволений, що хоч хтось оцінив )) а то більшість з криками «ааааа теоріяяаааа» тікають як чорт від ладану ))

Нехай тікають, ковток свіжого повітря завжди в радість

«я убеждён, что матрицы вторичны». Как заведено на хабре, в комментариях куча сумасшедших, у автора хорошая выдержка.

так, там... оригінальний співрозмовник попався )) судячи з усього, він більше по обробці сигналів, можливо що частково самоучка, тому там дещо незвичні уявлення про математику. але навіть з того треду є певна користь — задача про пам’ять в О(1) доволі цікава, я навіть просив товариша не викидати картинки, які він намалював для пояснення, — використаю в лекції, хочу показати цю штуку студентам в якості курйозу. я правда не дуже впевнений, що опонент зрозумів рішення, яке йому було надано. як мінімум той фільтр, який він привів у наступному коментарі (en.wikipedia.org/...​sive_least_squares_filter ), еквівалентний приведеному рішенню при lambda=1. Ну ще з поправкою, що для фільтра така постановка задачі, що там на кожному кроці треба добувати параметри регресії і тому там величезна кількість танців з бубном, щоб позбутись операції обертання матриці.

А мы в универе это на дельфи делали на лабах в своё время...

Эксель. Подбор решения. Програмист — не нужен

Линейная/полиномиальная регрессия в случае наименьших квадратов решается простым перемножением матриц — на Tensorflow это буквально несколько строчек кода.

reduce_sum(..) / (dataNum) -> reduce_mean(..)

Зачем две session.run(..) для оптимизатора и лосса отдельно, если можно в таргеты session.run() скормить обе величины? Это будет быстрее и лаконичнее.

Еще я бы использовал «+» вместо tf.add(), «*» вместо tf.multiply(), «**» вместо tf.pow() и tf.square() - это опять-таки для лаконичности, поскольку внутри эти операторы все равно превратятся в tf.add(), tf.multiply() и tf.pow()/tf.square()

Я бы на месте автора добавил в данные выбросы и сделал функцию оптимизации как Trimmed MSE, тогда было бы видно все волшебство.

Тему «Смещение vs Разброс» надо или убрать, или раскрыть. Наивно полагать, что двух абзацев и трех картинок хватит, чтобы пояснить эти понятия.

КМК статья неплохая, спасибо.
Я только закончил каггловый курсик по ML и было интересно посмотреть, как решать несложную задачку средствами TF после поверхностного курса по Deep learning.
Как по мне — более опытные комментаторы могли бы воздержаться от метания кала в обзорную статью, которая рассчитана на людей, которым нужно объяснить что такое оверфит.

Когда в статью «Туториал по полиномиальной регрессии в TF» приходят с вопросами «И при чем тутTF» — я не вижу ничего конструктивного.
Когда в статье с названием «Туториал» требуют ответов на вопросы, которые покрывают целый модуль универского курса анализа данный, это не замотивирует автора написать ещё что-то сюда.
«Отправили читать и изучать» — а кого-то просили об этом ?
Чувак поковырял, разобрался, сделал постик для поделиться, а ему пришли и натоксичили, браво

Ну микроскопом и микроскопом, так туториалы и пишутся.
В туториалах по веб-фреймфоркам голосовалки пишут или крестики-нолики, и пока все живы

Как часто в туториалах по веб-фреймворкам вы встречаете фразу

Чтобы понять, что такое X, нам нужно немного погрузиться в математику.

??

Без хотябы ссылок на «интересное» туториал превращается в туториал «как сделать тролейбус из буханки хлеба»

Уважаемый Armin Van Tubin, я прекрасно понимаю что в sklearn всё пишется в 2 строки. Статья написана с целью практики двух регрессий на TF. Если вам не хочется юзать TF — не стоит называть туториал плохим, а стоит перейти на нужный вам туториал. К тому же туториал по sklearn не имеет смысла, так как там прочитать пару секунд док и несколько строк кода.

Теперь по TF: статья была написана на английском для Google code-in 2019. Как вы понимаете гугл хочет чтобы я юзал TF. В поисках по интернету я не нашел ни одной практики но этим регрессиям и написал с нуля свою.

По теории: ниже был комментарий с теорией (habr.com/ru/post/514818) Там нет ни строчки кода, а теории расписано на 5 листов. Опять же, если кому-то нравится такой формат больше — милости прошу.

не стоит называть туториал плохим, а стоит перейти на нужный вам туториал

Если вам не нравятся коментарии на этом форуме, то можете перейти на нужный вам форум и слушать песню «Валенки» там ;)

Ваш туториал не просто плох, он — ужасен

Спасибо за отзыв ;) Я только начал писать и скоро выпущу ещё статьи. Жду вас там

Вот вам мой отзыв: в следующий раз постарайтесь подойти к проблеме более проактивно. Например:
1 вы видели мало туториалов по полиноминальной регрессии. Интересно почему так? Не есть ли полиноминальная регрессия частным случаем более общего метода?
2 линейная регрессия «в лоб» не работает для вашего сырого датасета. Почему так? Как читатель вашего туториала может понять, что его случай похож на описаный в вашем туториале?

Потому что если слепой ведет слепого, то они оба рискуют так погрузиться в математику, что как горох об стену

Упд:

3 вот есть код в туториале, который решает задачу. Может ли он её решать лучше? Почему?

Там нет ни строчки кода, а теории расписано на 5 листов

Справедливості ради, там є посилання на цілий гітхаб-репозитарій з кодом (github.com/...​eilstein/machine_learning ), а для даної конкретної задачі там є посилання ті нещасні 2 рядки коду, які її вирішують в гугл колаб (colab.research.google.com/...​ynb#scrollTo=bpnbCDkSw5I6 ) і навіть вставлена гіфка роботи того всього для зовсім лінивих чи в кого акаунта в гуглі нема (hsto.org/...​xouzaslryuzxrrzy9iga8.gif ). Воно там сховано під спойлером «гифка», тому і правда важко знайти.

более опытные комментаторы могли бы воздержаться от метания кала в обзорную статью, которая рассчитана на людей, которым нужно объяснить что такое оверфит.

Потому что она на самом деле ни фига не объясняет. Два кривых листинга с непонятной магией и куча странных слов.

Что это такое и зачем оно нужно?

Непонятно только, при чём тут TensorFlow. Зачем столь серьёзное средство для такой простой задачи?
На ней что, кроме линейной и полиномиальной ничего не строится?
Полиномиальная строится по точному совпадению с какими-то точками или есть мера отклонения? Как насчёт метода наименьших квадратов?
Есть ли возможность строить аппроксимацию сплайнами (хотя бы B и S)? Есть ли сравнение затрат и качества результата для таких подходов?

Хорошая статья. Рекомендую всем прочитать для ознакомления.

Ознакомления с чем и как?
Вы всерьёз считаете, что пара загадочных листингов и решение задачи уровня самых азов вычмата поможет понять серьёзную библиотеку?

Тут на форуме кто-то когда-то плевался когда регрессии градиентным спуском решают.

хто бачив як сходиться градієнтний спуск той в цирку не сміється використовує хоча б стохастичний градієнтний спуск.

Отлично он сходиться к ближайшему локальному минимуму и никуда иначе.

так це за першу ітерацію, а за другу — до глобального

так це за першу ітерацію

За першу каденцію! Оберіть нашу партію вдруге!

Оберіть нашу партію вдруге!

А Ви обіцяєте, що цього разу ми таки досягнемо глобального дна мінімуму, а не застрягнемо в локальному?

Методом наименьших квадратов

Спасибо большое, Виктор. Обязательно почитаю.

Решать как систему линейных уравнений — любым доступным способом.

Отличная статья! Очень мало в интернете видел практику по полиномиальной регрессии.

Спасибо, хорошее практическое введение в TensorFlow!
Также читателям рекомендую пройти первые 3 недели курса Ына по ML, если теория, изложенная в статье, кажется слишком сложной на данный момент.

если теория, изложенная в статье, кажется слишком сложной на данный момент

Де Ви тут теорію знайшли, боюсь спитати? Нормальна теорія це щось таке: habr.com/ru/post/514818 . Крім того приведена імплементація приховує той факт, що поліноміальна регресія — це лінійна регресія з відповідними фічами. От, наприклад, в scikit-learn це дуже добре видно. Там відповідна дія робиться:

make_pipeline(PolynomialFeatures(2), LinearRegression())

Відразу видно, що спершу генеруються фічі, а потім проводиться звичайна лінійна регресія. Код можна роздивитись ближче тут: colab.research.google.com/...​ynb#scrollTo=bpnbCDkSw5I6

Да, Виталий, вы абсолютно правы. Цель этого туториала была не грузить теорией, а
1) показать код линейной и полиномиальной регрессий, чтобы люди могли скопировать и вставить код в свой проект (в интернете почти нет практики на подобную тему).
2) рассказать простыми словами и с примерами для чего нам вообще нужна полиномиальная регрессия и немного объяснить термины, которые часто на слуху типа overfit vs underfit (опять таки, показал с картинкой, чтобы понятно было), bias vs variance.

Это можно считать практикой, если у кого-то после теории возникли проблемы с кодом либо нет желания читать эту самую теорию.

Перед тем, как я запущу ваш код на своей машине, расскажите мне, пожалуйста, простыми словами, чем полиноминальная регрессия лучше линейной, в случае когда входные данные сгегерированы как очевидно нелинейная зависимость + еррор:

x = np.linspace(1, 10, dataNum) # Делаем случайные точки
y = np.log(1+x) + np.random.uniform(-0.5, 0.5, dataNum)

И если лучше, то какой степени полином мне надо фитить на данные так, что бы избежать «overfit»?

1) думаю весь мой туториал я рассказывал, что когда данные не линейно распределены, то линия не может всё зафитить, как бы она не старалась, так как Линейная регрессия работает только с Линейной зависимостью (смотрите картинки)
2) Тут, соглашусь, нужен небольшой ручной тюнинг, смотря как ваши данные распределены.

Видите кривую и хотите построить полином? — определяете её степень, тюните параметр degree, запускаете код. Безусловно можно это сделать по другому или автоматизировать тюнинг, но я хотел сделать код полинома похожим на Лин рег, чтобы было видно разницу.

Ох тоже мне бином Тейлора!

Расскажите тогда, как «на глаз» определить степень кривой по конечному количеству точек в многомерном случае?

Линейная регрессия работает только с Линейной зависимостью (смотрите картинки)

Це абсолютно неправильно. Слово «лінійна» в назві регресії немає нічого спільного з залежністю, яку вона апроксимує. Вона лінійна, тому що Ви шукаєте лінійну комбінацію певних базисних функцій. В одновимірному випадку якщо базисні функції 1 та х — буде пряма лінія. Якщо базисні функції 1, х, х**2, ітд — буде поліном якогось степеня. З тим же успіхом можете взяти які хочете функції і буде щось ще. Але це все лінійна регресія.

Видите кривую и хотите построить полином? — определяете её степень, тюните параметр degree, запускаете код. Безусловно можно это сделать по другому или автоматизировать тюнинг

Для таких випадків його не можна, а треба автоматизувати. Це робиться або нарощуванням порядку полінома з валідацією чи перевіркою скоректованого коефіцієнта детермінації, або регуляризаціями, наприклад Lasso, Ridge. Визначати порядок на око — це нонсенс. При наявності шуму в даних навіть в одновимірному випадку це не так просто зробити, а на практиці дані будуть багатовимірними і їх в принципі не вийде намалювати.

Щодо нарощування порядку полінома існує такий феномен:

uk.m.wikipedia.org/...​iki/Прокляття_розмірност

Але головне не грузиться теорією аби не засмутитися

так я і не гружусь — я гружу теорією інших )) у мене взагалі ціла лекція є про лінійну регресію

Підписатись на коментарі