Log in

Машинне навчання простими словами. Частина 2

Рекомендовані Machine Learning Machine Learning

Продовження. Початок (Частина 1) тут

 

Частина 2. Навчання з підкріпленням

 

«Кинь робота в лабіринт і нехай шукає вихід»

Сьогодні використовують для:

  • Автопілотів автомобілів
  • Роботів-порохотягів
  • Ігор
  • Автоматизованої торгівлі
  • Управління ресурсами підприємств

Популярні алгоритми: Q-LearningSARSA, DQN, A3CГенетичний Алгоритм

Нарешті ми дійшли до речей, які, начебто, виглядають як справжній штучний інтелект. Багато авторів чомусь розташовують навчання з підкріпленням десь між навчанням з вчителем та без, але я не розумію чим вони схожі. Назвою?

Навчання з підкріпленням використовують там, де задача полягає не в аналізі даних, а у виживанні в реальному середовищі.

Середовищем може бути навіть відеогра. 

Роботи, які грають в Маріо, були популярні ще років п'ять тому.

Середовищем може бути навіть реальний світ. Як приклад - автопілот Тесли, який вчиться не збивати пішоходів, або роботи-порохотяги, головне завдання яких - налякати вашого кота з максимальною ефективністю.

Знання про навколишній світ такому роботу можуть бути корисні, але лише для довідки. Не важливо скільки даних він збере, у нього все одно не вийде передбачити всі ситуації. Тому його мета - мінімізувати помилки, а не передбачати всі ходи. Робот вчиться виживати в просторі з максимальним зиском: зібраними монетками в Маріо, тривалістю поїздки в Теслі або кількістю збитих роззяв (хе-хе-хе).

Саме виживання в середовищі і є ідеєю навчання з підкріпленням. Давайте кинемо бідного робота в реальне життя, будемо штрафувати його за помилки і нагороджувати за правильні вчинки. На людях норм працює, то ж чому б на і роботах не спробувати.

Розумні моделі роботів-порохотягів і самокеровані автомобілі навчаються саме так: їм створюють віртуальне місто (часто на основі карт справжніх міст), населяють випадковими пішоходами і відправляють вчитися нікого там не вбивати. Коли робот починає добре себе почувати в штучному GTA, його випускають тестувати на реальні вулиці.

Запам'ятовувати саме місто машині не потрібно - такий підхід називається Model-Free. Звичайно, тут є і класичний Model-Based, але в ньому нашій машині довелося б запам'ятовувати модель всієї планети, всіх можливих ситуацій на всіх перехрестях світу. Таке просто не працює. У навчанні з підкріпленням машина не запам'ятовує кожен рух, а намагається узагальнити ситуації, щоб виходити з них з максимальною вигодою.

Пам'ятаєте новину кількарічної давнини, коли машина обіграла людину в Ґо? Хоча незадовго до цього було доведено, що кількість комбінацій фізично неможливо прорахувати, адже вона перевищує кількість атомів у всесвіті. Тобто, якщо в шахах машина реально може прорахувати усі майбутні комбінації і перемагати, з Ґо така ідея нездійснена. Тому вона просто вибирала найкращий вихід з кожної ситуації і робила це досить точно, щоб обіграти якогось вусатого дядька.

Ця ідея лежить в основі алгоритму Q-learning і його похідних (SARSA і DQN). Буква Q в назві означає слово Quality, тобто робот вчиться робити найбільш якісні кроки в будь-якій ситуації, а всі ситуації він запам'ятовує як простий марковский процес.

Машина проганяє мільйони симуляцій в середовищі, запам'ятовуючи всі сформовані ситуації і виходи з них, які принесли максимальну винагороду. Але як зрозуміти, коли у нас склалася знайома ситуація, а коли абсолютно нова? Ось самокеруючий автомобіль стоїть біля перехрестя і загоряється зелений - значить можна їхати? А якщо справа мчить швидка допомога з мигалками?

Відповідь - ну хто його знає, ніяк, магії не буває, дослідники постійно цим займаються і винаходять свої велосипеди. Одні прописують всі ситуації руками, що дозволяє їм обробляти виняткові випадки типу проблеми вагонетки. Інші йдуть глибше і віддають цю роботу нейромережам, нехай самі все знайдуть. Так замість Q-learning'а у нас з'являється Deep Q-Network (DQN).

Reinforcement Learning для простого юзера виглядає як справжній інтелект. Тому що "wow, машина сама приймає рішення в реальних ситуаціях!" Він зараз на хайпі, швидко пре вперед і активно прагне в нейромережі, щоб стати ще точнішим (а не стукатися в ніжку стільця по двадцять разів).

Тому якщо ви любите дивитися на результати своєї праці і хочете популярності - сміливо стрибайте в методи навчання з підкріпленням (який же жахливий термін, кожен раз пересмикує) і створюйте канал на ютюбі! Навіть я б дивився.


Колись були дуже популярні генетичні алгоритми (за посиланням прикольна візуалізація). Це коли ми кидаємо купу роботів в середовище і змушуємо їх йти до мети, поки не здохнуть. Потім вибираємо кращих, схрещуємо, додаємо мутації і кидаємо ще раз. Через пару мільярдів років має вийти розумна істота. Теорія еволюції у дії.

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

Людству ще не вдалося придумати задачу, де вони були б реально ефективніші інших. Зате відмінно підходять для студентських експериментів і дозволяють кадрити наукових керівників «досягненнями», при цьому особливо не потіючи. Для ютюбу також підійде.

 

Частина 3. Ансамблі

 

«Купа дурних дерев вчиться виправляти помилки один одного»

Сьогодні використовують для:

  • Всього, де можна скористатися класичними алгоритмами (але працюють точніше)
  • Пошукові системи (★)
  • Розпізнавання об'єктів

Популярні алгоритми: Random Forest , Gradient Boosting

Переходимо до справжніх дорослих методів. Ансамблі та нейромережі - наші головні бійці на шляху до неминучої сингулярності. Сьогодні вони дають найточніші результати і використовуються усіма великими компаніями в продакшені. Лише про нейромережі й тріщать у кожному кутку, а слова «бустинг» і «бегінг», напевно, лякають тільки хіпстера з теккранча.

Разом з усією їхньою ефективністю, ідея до знущання проста. Виявляється, якщо взяти декілька не дуже ефективних методів навчання і навчити виправляти помилки один одного, якість такої системи буде аж ой-як дуже вище, ніж кожного з методів окремо.

Причому навіть краще, коли взяті алгоритми максимально нестабільні і сильно плавають стосовно вхідних даних. Тому частіше беруть Регресію і Дерева Рішень, яким достатньо однієї сильної аномалії в даних, щоб поїхала вся модель. А ось Баєса і K-NN не беруть ніколи - вони хоч і тупі, але дуже стабільні.

Ансамбль можна зібрати як завгодно, хоч випадково нарізати у каструльку класифікатори і залити регресією. За точність, правда, тоді ніхто не ручається. Тому є три перевірених способи робити ансамблі.

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

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

Чисто з досвіду - стекінг на практиці застосовується рідко, тому що два інших методи зазвичай точніші.

 Бегінг   Він же Bootstrap AGGregatING. Навчаємо один алгоритм багато разів на випадкових вибірках з вихідних даних. В кінці усереднюємо відповіді.

Дані в випадкових вибірках можуть повторюватися. Тобто з набору 1-2-3 ми можемо робити вибірки 2-2-3, 1-2-2, 3-1-2 і так поки не набридне. На них ми навчаємо один і той же алгоритм кілька разів, а в кінці знаходимо відповідь простим голосуванням.

Найпопулярніший приклад бегінга - алгоритм Random Forest, бегінг на деревах, який намальований на рисунку вище. Коли ви відкриваєте камеру на телефоні і бачите як вона окреслила обличчя людей в кадрі жовтими прямокутниками - швидше за все це їх робота. Нейромережа буде занадто повільна в реальному часі, а бегінг ідеальний, адже він може обчислювати свої дерева паралельно на всіх шейдерах відеокарти.

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


 Бустинг  Навчаємо алгоритми послідовно, кожен наступний приділяє особливу увагу тим випадкам, на яких помилився попередній.

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

Плюси - шалена, навіть нелегальна в деяких країнах, точність класифікації, якій позаздрять всі бабусі біля під'їзду. Мінуси вже названі - не паралелиться. Хоча все одно працює швидше нейромереж, які мов навантажені КРАЗи з піском у порівнянні зі спритним бустингом.

Потрібен реальний приклад роботи бустинга - відкрийте Яндекс і введіть запит. Чуєте, як Матрикснет гуркоче деревами і ранжує вам результати? Ось це якраз воно, Яндекс зараз весь на бустингу. Про Google не знаю.

Сьогодні є три популярних методи бустингу, відмінності між якими добре висвітлено у статті CatBoost vs. LightGBM vs. XGBoost

 

Частина 4. Нейромережі і глибоке навчання

 

«У нас є мережа з тисячі шарів, десятки відеокарт, але ми все ще не придумали де це може бути корисним. Нехай малює котиків! »

Сьогодні використовують для:

  • Замість всіх перелічених вище алгоритмів
  • Визначення об'єктів на фото і відео
  • Розпізнавання і синтез мови
  • Обробка зображень, перенесення стилю
  • Машинний переклад

Популярні архітектури: Перцептрон, Згорткові Мережі (CNN), Рекурентні Мережі(RNN), Автоенкодери

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

Будь-яка нейромережа - це набір нейронів і зв'язків між ними. Нейрон найкраще уявляти собі просто як функцію з купою входів і одним виходом. Завдання нейрона - взяти цифри зі своїх входів, виконати над ними функцію і віддати результат на вихід. Простий приклад корисного нейрона: знайти суму всіх цифр зі входів, і якщо їх сума більше N - видати на вихід одиницю, інакше - нуль.

Зв'язки - це канали, через які нейрони шлють один одному цифри. Кожен зв'язок має свою вагу - її єдиний параметр, який можна умовно уявити як міцність зв'язку. Коли через зв'язок з вагою 0,5 проходить число 10, воно перетворюється в 5. Сам нейрон не розбирається, що до нього прийшло і сумує все підряд - ось ваги й потрібні, щоб керувати на які входи нейрон повинен реагувати, а на які - ні.

Щоб мережа не перетворилася в анархію, нейрони вирішили пов'язувати не як захочеться, а по шарах. Всередині одного шару нейрони ніяк не пов'язані, але з'єднані з нейронами наступного і попереднього шару. Дані в такій мережі йдуть строго в одному напрямку - від входів першого шару до виходів останнього.

Якщо нафігачити (ой, вибачте) достатню кількість шарів і правильно розставити ваги в такій мережі, виходить наступне - подавши на вхід, скажімо, зображення написаної від руки цифри 4, чорні пікселі активують пов'язані з ними нейрони, ті активують наступні шари, і так далі і далі, поки в результаті не висвітлиться той самий вихід, який відповідає за четвірку. Результат досягнуто.

У реальному програмуванні, очевидно, жодних нейронів і зв'язків не пишуть, все зображають матрицями, тому що потрібна швидкість. У мене є два улюблених відео, в яких весь описаний мною процес наочно пояснений на прикладі розпізнавання рукописних цифр. Подивіться, якщо хочете розібратися.

 

 

Така мережа, де є декілька шарів і між ними пов'язані всі нейрони, називається перцептроном (MLP) і вважається найпростішою архітектурою для новачків. У бойових задачах особисто я ніколи її не зустрічав.

Коли ми побудували мережу, наша задача так правильно розставити ваги, щоб нейрони реагували на потрібні сигнали. Тут потрібно згадати, що у нас же є дані - приклади «входів» і правильних «виходів». Будемо показувати нейромережі малюнок тієї ж цифри 4 і говорити «побудуй свої ваги так, щоб при такому вході на твоєму виході завжди спалахувала четвірка».

Спочатку всі ваги просто розставлені випадково, ми показуємо мережі цифру, вона видає якусь випадкову відповідь (ваг же немає), а ми порівнюємо, наскільки результат відрізняється від потрібного нам. Потім йдемо по мережі в зворотному напрямку, від виходів до входів, і говоримо кожному нейрону - так, ти ось тут чогось активувався, через тебе все пішло не так, давай ти будеш трохи менше реагувати на ось цей зв'язок і трохи більше на отой, ок?

Через тисяч сто таких циклів «прогнали-перевірили-покарали» є надія, що ваги в мережі відкоригуються так, як би ми хотіли. Науково цей підхід називається Backpropagation або «Метод зворотного поширення помилки». Цікаво те, що щоб відкрити цей метод знадобилося двадцять років. До нього нейромережі навчали як могли.

Друге моє улюблене відео більш детальніше пояснює весь процес, але все так само просто, на пальцях.

 

 

Добре навчена нейромережа могла прикидатися будь-яким алгоритмом з цієї статті, а часто працювати навіть точніше. Така універсальність зробила нейромережі дико популярними. Нарешті у нас є архітектура людського мозку, говорили вони, потрібно просто зібрати багато шарів і навчити їх на будь-яких даних, сподівалися вони. Потім почалася перша Зима ШІ, потім відлига, потім друга хвиля розчарування.

Виявилося, що для навчання мережі з великою кількістю шарів були потрібні неможливі на ті часи потужності. Зараз будь-яке ігрове відро з жифорсами перевищує потужність тодішнього датацентру. Тоді навіть надії на це не було, і в нейромережах всі дуже сильно розчарувалися.

Поки років десять тому назад не бомбанули Deep learning.

В англійській вікіпедії є сторінка Timeline of machine learning, де добре видно сплески радості і хвилі відчаю.

У 2012 році згорткова нейромережа порвала всіх в конкурсі ImageNet, і тоді в світі раптово згадали про методи глибокого навчання, описаних ще в 90-х роках. Адже тепер у нас є відеокарти!

Відмінність глибокого навчання від класичних нейромереж полягала в нових методах навчання, які справлялися з великими розмірами мереж. Однак сьогодні лише теоретики розділяють, яке навчання можна вважати глибоким, а яке не надто. Ми ж, як практики, використовуємо популярні «глибокі» бібліотеки типу Keras , TensorFlow і PyTorch навіть коли нам треба зібрати міні-сітку на п'ять шарів. Просто тому що вони зручніші того, що було раніше. Ми називаємо це просто нейромережами.

Розповім про дві головні на даний момент.

 

Згорткові Нейромережі (CNN)

 

Згорткові мережі зараз на піку популярності. Вони використовуються для пошуку об'єктів на фото і відео, розпізнавання осіб, перенесення стилю, генерації і домальовування зображень, створення ефектів типу слоу-мо і поліпшення якості фотографій. Сьогодні CNN застосовують всюди, де є картинки або відео. Навіть у вашому айфоні кілька таких мереж дивляться на ваші фотографії, щоб розпізнати об'єкти на них.

 

 

Картинка вище - результат роботи бібліотеки Detectron , яку Facebook недавно заопенсорсив

Проблеми з зображеннями завжди були в тому, що незрозуміло, як виділяти на них ознаки. Текст можна розбити за пропозиціями, взяти властивості слів зі словників. Картинки ж доводилося мітити руками, пояснюючи машині, де у котика на фотографії вушка, а де хвіст. Такий підхід навіть назвали «handcrafting ознак» й раніше все так і робили.

 

 

Проблем у ручного крафтингу багато.

По-перше, якщо котик на фотографії притиснув вушка або відвернувся - все, нейромережа нічого не побачить.

По-друге, спробуйте самі зараз назвати хоча б десять характерних ознак, що відрізняють котиків від інших тварин. Я от не зміг. Однак коли вночі повз мене пробігає чорна пляма, навіть краєм ока я можу сказати котик це чи щур. Тому що людина не дивиться тільки на форму вух і кількість лап - вона оцінює об'єкт за купою різних ознак, про які навіть сама не замислюється. А отже, не розуміє і не може пояснити машині.

Я наслідок, складається враження, що машині треба самій вчитися шукати ці ознаки, складаючи з якихось базових ліній. Будемо робити так: для початку розділимо зображення на блоки 8x8 пікселів і виберемо яка лінія домінує в кожному - горизонтальна [-], вертикальна [|] або одна з діагональних [/]. Можуть і дві, і три, так теж буває, ми не завжди точно впевнені.

На виході ми отримаємо кілька масивів паличок, які, по-суті, є простими ознаками наявності обрисів об'єктів на зображенні. По-суті, це теж картинки, просто з паличок. Значить ми можемо знову вибрати блок 8x8 і подивитися вже, як ці палички поєднуються одна з одною. А потім ще і ще, і ще...

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

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

На виході ж ми поставимо простий перцептрон, який буде дивитися які поєднання активувалися і говорити кому вони більше характерні - кішці або собаці.

 

 

Краса ідеї в тому, що у нас вийшла нейромережа, яка сама знаходить характерні ознаки об'єктів. Нам більше не треба відбирати їх руками. Ми можемо скільки завгодно годувати її зображеннями будь-яких об'єктів, просто наґуґліть мільйон картинок з ними - мережа сама складе карти ознак з паличок і навчиться визначати що завгодно.

Щодо цього існує навіть несмішний жарт:

Дай нейромережі рибу - вона зможе визначати рибу до кінця життя. Дай нейромережі вудку - вона зможе визначати і вудку до кінця життя ...

Рекурентні Нейромережі (RNN)

 

Друга за популярністю архітектура на сьогоднішній день. Завдяки рекурентним мережам у нас є такі корисні речі, як машинний переклад текстів і комп'ютерний синтез мови. На них розв'язують усі завдання, пов'язані з послідовностями - голосові, текстові або музичні.

Пам'ятаєте олдскульні голосові синтезатори типу Microsoft Sam з Windows XP, який смішно вимовляв слова по буквах, намагаючись якось склеїти їх між собою? А тепер подивіться на Amazon Alexa або Алісу від Яндекса - вони сьогодні не просто вимовляють слова без помилок, вони навіть розставляють акценти в реченні!

 

 

Це відбувається тому, що сучасні голосові помічники навчають говорити не буквами, а фразами. Але одразу змусити нейромережу повністю видавати фрази не вийде, адже тоді їй треба буде запам'ятати всі фрази в мові і їх розмір буде велетенським. Тут на допомогу приходить той факт, що текст, мова або музика - це послідовності. Кожне слово або звук - це, так би мовити, самостійна одиниця, але яка залежить від попередніх. Коли цей зв'язок втрачається - виходить дабстеп.

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

Ось тільки з послідовністю знову біда, адже перцептрон не запам'ятовує те, що він генерував раніше. Для нього кожен запуск як перший раз. З'явилася ідея додати до кожного нейрона пам'ять. Так були придумані рекурентні мережі, в яких кожен нейрон запам'ятовував всі свої попередні відповіді і при наступному запуску використовував їх як додатковий вхід. Тобто нейрон міг сказати самому собі в майбутньому - агов, чувак, наступний звук повинен звучати вище, у нас тут голосна була (дуже спрощений приклад).

 

 

Була лише одна проблема - коли кожен нейрон запам'ятовував всі минулі результати, в мережі виникала така дика кількість входів, що навчити таку кількість зв'язків ставало нереально.

Коли нейромережа не вміє забувати - її не можна навчити (у людей та ж фігня).

Спочатку проблему вирішили в лоб - обрубали кожному нейрону пам'ять. Але потім придумали в ролі цієї «пам'яті» використовувати спеціальні комірки, схожі на пам'ять комп'ютера або регістри процесора. Кожна комірка дозволяла записати в себе цифру, прочитати або скинути - їх назвали комірки (осередки) довгої і короткострокової пам'яті (LSTM).

Коли нейрону було потрібно поставити собі нагадування на майбутнє - він писав це в комірку, коли навпаки вся історія ставала непотрібною (речення, наприклад, закінчилося) - комірки видалялися, залишаючи тільки «довгострокові» зв'язки, як в класичному перцептроні. Іншими словами, мережа навчалася не тільки встановлювати поточні зв'язки, а й ставити нагадування.

Просто, але працює!

 

 

Озвучені тексти для навчання почали брати звідки завгодно. Навіть базфід зміг вивантажити відеозаписи виступів Обами і вельми непогано навчити нейромережу розмовляти його голосом. На цьому прикладі видно, що імітувати голос - досить просте завдання для сьогоднішніх машин. З відео складніше, але це поки що.

 

 


 

Про архітектури нейромереж можна говорити нескінченно довго. Допитливих відправляю дивитися схему і читати статтю Neural Network Zoo, де зібрані всі типи нейронних мереж (є й росверсія).

 

Висновок: коли на війну з машинами?

 

На запитання «коли машини стануть розумнішими за нас і всіх нас поневолять?» я завжди відповідаю, що воно заздалегідь неправильне. У ньому занадто багато прихованих умов, які приймають як даність.

Ось ми говоримо «стануть розумнішими за нас». Значить ми маємо на увазі, що існує якась єдина шкала інтелекту, на вершині якої знаходиться людина, собаки нижче, а дурні голуби тусят в самому низу. Виходить людина повинна перевершувати тварин у всьому? Так? А в житті не так. Середньостатистична білка може пам'ятати тисячу схованок з горішками, а я не можу згадати куди закинув свої ключі. Виходить інтелект - це набір різних навичок, а не єдина величина, яку можна виміряти? Або просто запам'ятовування горішків в нього не входить? А вбивання людей входить?

Ну і найцікавіше для мене запитання - чому ми заздалегідь вважаємо, що можливості людського мозку обмежені? В інтернеті обожнюють малювати графіки, на яких технологічний прогрес позначений експонентою, а можливості звичайних юзерів константою. Але чи це насправді так?

Ось давайте, прямо зараз перемножте в голові 1689 на 951. Так, знаю, ви навіть не будете намагатися. Але дай вам калькулятор, це займе дві секунди. Чи це означає, що ви щойно розширили можливості свого мозку за допомогою калькулятора? Чи можна продовжувати їх розширювати іншими машинами? Я ось використовую нагадування на телефоні - чи це означає, що я розширюю свою пам'ять за допомогою машини?

Виходить, ми вже успішно розширюємо можливості нашого мозку за допомогою машин. Чи ні?

Подумайте. У мене все.

 

 

за матеріалами vas3k.ru

Mini Admini

Якщо не можеш вітер змалювати, прозорий вітер на ясному тлі, -
Змалюй дуби, могутні і крислаті, котрі од вітру гнуться до землі!

Коментарі (0)

Rated 0 out of 5 based on 0 voters
There are no comments posted here yet

Залиште свій коментар

Posting comment as a guest. Sign up or login to your account.
Вкладення (0 / 3)
Share Your Location
«
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
»

Наші контакти


Ідея, веб-дизайн і т.д.:

Олег Романів
oromaniv at franko.lviv.ua