Інтелект в айфоне. Як нейронні мережі в iOS 10 і MacOS допомагають Apple бути лідерами
Компанія Apple використовує технологію машинного самонавчання на своїх пристроях досить довго: Siri відповідає на питання і розважає користувача, iPhoto розпізнає обличчя на фото, додаток Mail обчислює листи, що містять спам. Як у розробників додатків, у нас є доступ до певних розділів, представленим інтерфейсом програмування додатків (API) Apple, наприклад, до розпізнавання осіб. А починаючи з iOS 10, ми отримаємо високорівнева API для розпізнавання мови і SiriKit.
Можливо, іноді хочеться вийти за межі API, вбудованих в платформу, і створити щось унікальне. Часто ми відчуваємо власні можливості комп'ютерного самонавчання, використовуючи одну з безлічі готових бібліотек або базуючись безпосередньо на високій обчислювальної потужності інтерфейсів Accelerate або Metal.
Наприклад, мої колеги налагодили в нашому офісі вхідні систему, яка використовує iPad для розпізнавання особи, потім постить гифку в бесіді Slack і дозволяє користувачам відкрити двері, використовуючи умовну команду.
Тепер у нас є першокласна підтримка для нейронних мереж: на Міжнародній конференції розробників ПЗ (WWDC) 2016 компанія Apple представила не один, а два API, що працюють на базі нейронних мереж; вони називаються Basic Neural Network Subroutines (BNNS) і Convolutional Neural Networks (CNN).
Машинне самонавчання і нейронні мережі
Основоположник в створенні інтерфейсів додатків, Артур Самуель визначив машинне самонавчання як «область досліджень, яка дає комп'ютерів можливість навчатися без безпосереднього процесу програмування». Системи комп'ютерного самонавчання часто використовуються для роботи з даними, які не можуть бути описані за допомогою традиційних моделей.
Наприклад, можна легко написати програму, яка вважає площа будинку, якщо відомі дані про розміри і формах всіх приміщень; але неможливо придумати формулу для розрахунку вартості будинку. Система машинного самонавчання, з іншого боку, відмінно підходить для вирішення подібних завдань. Надаючи програмі такі відомі дані про реальний світ, як ринкова вартість, розмір будинку, кількість спалень і т.д., можна навчити програму розраховувати приблизну вартість.
Нейронні мережі - одна з найбільш типових моделей для створення систем машинного самонавчання. У той час, як математичні основи нейронних мереж були описані вже понад півстоліття тому, в 1940-х рр., Паралельна обчислювальна обробка зробила їх більш реальними в 1980-х, а інтерес до глибокого вивчення привів до відродження нейронних мереж в 2000-х.
Нейронні мережі складаються з декількох шарів, кожен з яких містить одну або кілька вузлових точок. Найпростіша нейронна мережа складається з трьох шарів: вхідного, прихованого і вихідного. Вузли вхідного шару можуть являти собою окремі пікселі зображення або інші параметри. Вихідні вузли часто є результатом класифікації, наприклад «собака» або «кішка», якщо ми намагаємося автоматично визначити зміст картинки. Вузли прихованого шару запрограмовані для того, щоб зробити операцію на вході або застосувати активаційну функцію нейрона.
типи шарів
Існує три основних типи шарів: з'єднувальні, свёрточние і повністю взаємопов'язані.
З'єднувальний шар об'єднує дані, зменшує їх обсяг, як правило, використовуючи максимальне або середнє значення внесеної інформації. Послідовність свёрточних і сполучних шарів можуть бути об'єднана, щоб поступово перегнати фотографію в збірник з поступово збільшуються ознаками більш високого рівня.
Свёрточний шар видозмінює зображення, застосовуючи матрицю згортки до кожного його пікселя. Якщо ви коли-небудь використовували фільтри Pixelmator або Photoshop, ви напевно стикалися з такою матрицею. Як правило, вона має розміри 3х3 або 5х5 і застосовується до пікселів вхідний картинки, щоб розрахувати обсяги нових пікселів на вихідний зображенні. Для того, щоб отримати обсяг вихідного зображення, ми перемножимо обсяги пікселів вихідного зображення і порахуємо середнє арифметичне.
Наприклад, наступна матриця зробить зображення розмитим:
У той час як ця зробить його більш чітким:
0 -1 0
-1 5 -1
0 -1 0
Свёрточний шар нейронних мереж використовує матрицю згортки для обробки вхідних даних і генерування даних для останнього шару, наприклад, для виділення нових параметрів зображення, таких як кути.
Повністю взаємопов'язаний шар може бути представлений як свёрточний шар, в якому фільтр буде такого ж розміру, як і вихідне зображення. Іншими словами, його можна вважати функцією, яка призначає вагові коефіцієнти для окремих пікселів, середні результати і видає єдиний вихідний обсяг.
Навчання нейронної мережі і отримання висновків
Кожен шар повинен бути налаштований згідно з визначеними параметрами. Так, свёрточний шар необхідно забезпечити як інформацією про вихідні і виведених зображеннях (розмір, кількість каналів і т.д.), так і безпосередньо параметрами свёрточного шару (розмір ядра, матриці і т.д.). Повністю взаємопов'язаний шар визначає вхідні та вихідні вектори, функцію активації і навантаження.
Для правильної роботи всіх компонентів нейронну мережу необхідно навчити. Процес навчання є пропуск входять даних через нейронну мережу. Одночасно з пропуском відбувається визначення вихідних даних, вимірювання похибки (тобто наскільки фактичний результат різниться з прогнозованим), а також коригування вихідного обсягу за рахунок зворотної передачі помилки навчання. Для навчання нейронної мережі можуть знадобитися сотні, тисячі і навіть мільйони прикладів.
В даний час нові API машинного навчання Apple можуть бути використані для створення нейронних мереж, здатних тільки на отримання висновків, але не на навчання. І все ж освітній IT-проект Big Nerd Ranch створює класні речі.
Інтерфейс Accelerate: BNNS
Перший новий API є частиною системи Accelerate і називається BNNS, що означає Basic Neural Network Subroutines (Основні підпрограми нейронної мережі). BNNS є доповненням до BLAS (Basic Linear Algebra Subroutines - базові підпрограми лінійної алгебри), які використовувалися деякими сторонніми розробниками в додатках по машинному навчання.
BNNS визначає групи в класі BNNSFilter. Інтерфейс Accelerate підтримує три типи шарів: свёрточний шар (створений за допомогою функції BNNSFilterCreateConvolutionLayer), повністю взаємопов'язаний шар (BNNSFilterCreateFullyConnectedLayer) і з'єднувальний шар (BNNSFilterCreatePoolingLayer).
База даних MNIST database являє собою популярний набір даних, що містить десятки тисяч рукописних цифр, які були відскановані і підлаштовані під піксельний зображення 20 на 20.
Один з підходів до обробки графічних даних полягає в перетворенні зображення в векторний формат і передача його через повністю взаємопов'язаний шар. У випадку з інформацією з бази даних MNIST, після такого перетворення зображення 20x20 стане векторних на 400 значень.
Ось яким чином рукописну цифру 1 можна перетворити в векторне зображення:
Нижче представлений приклад коду для настройки повністю взаємопов'язаного шару, який приймає вектор розміром 400 в якості вхідних даних, використовує сигмовидную функцію активації і виводить вектор розміром 25:
// input layer descriptor BNNSVectorDescriptor i_desc = {.size = 400, .data_type = BNNSDataTypeFloat32, .data_scale = 0, .data_bias = 0,}; // hidden layer descriptor BNNSVectorDescriptor h_desc = {.size = 25, .data_type = BNNSDataTypeFloat32, .data_scale = 0, .data_bias = 0,}; // activation function BNNSActivation activation = {.function = BNNSActivationFunctionSigmoid, .alpha = 0, .beta = 0,}; BNNSFullyConnectedLayerParameters in_layer_params = {.in_size = i_desc.size, .out_size = h_desc.size, .activation = activation, .weights.data = theta1, .weights.data_type = BNNSDataTypeFloat32, .bias.data_type = BNNSDataTypeFloat32,}; // Common filter parameters BNNSFilterParameters filter_params = {.version = BNNSAPIVersion_1_0; // API version is mandatory}; // Create a new fully connected layer filter (ih = input-to-hidden) BNNSFilter ih_filter = BNNSFilterCreateFullyConnectedLayer (& i_desc, & h_desc, & in_layer_params, & filter_params); float * i_stack = bir; // (float *) calloc (i_desc.size, sizeof (float)); float * h_stack = (float *) calloc (h_desc.size, sizeof (float)); float * o_stack = (float *) calloc (o_desc.size, sizeof (float)); int ih_status = BNNSFilterApply (ih_filter, i_stack, h_stack);
Інтерфейс Metal!
Друга нейронна мережа API є частиною системи Metal Performance Shaders (MPS). У той час як Accelerate є основою для виконання швидких обчислень на CPU, Metal доводить GPU до найвищих обертів. Основа інтерфейсу називається CNN (Convolution Neural Network).
MPS поставляється з аналогічним набором APIs. Створення свёрточного шару вимагає використання функцій MPSCNNConvolutionDescriptor і MPSCNNConvolution. Функція MPSCNNPoolingMax забезпечить параметри з'єднувального шару, а повністю взаємопов'язаний шар буде створений за допомогою функції MPSCNNFullyConnected. Функція активації визначається такими підкласами, як MPSCNNNeuron: MPSCNNNeuronLinear, MPSCNNNeuronReLU, MPSCNNNeuronSigmoid, MPSCNNNeuronTanH, MPSCNNNeuronAbsolute.
Порівняння BNNS і CNN
Таблиця являє собою список функцій активації в Accelerate і Metal:
Accelerate / BNNS
Metal Performance Shaders / CNN
BNNSActivationFunctionIdentity
BNNSActivationFunctionRectifiedLinear
MPSCNNNeuronReLU
MPSCNNNeuronLinear
BNNSActivationFunctionLeakyRectifiedLinear
BNNSActivationFunctionSigmoid
MPSCNNNeuronSigmoid
BNNSActivationFunctionTanh
MPSCNNNeuronTanH
BNNSActivationFunctionScaledTanh
BNNSActivationFunctionAbs
MPSCNNNeuronAbsolute
Функції об'єднання:
Accelerate / BNNS
Metal Performance Shaders / CNN
BNNSPoolingFunctionMax
MPSCNNPoolingMax
BNNSPoolingFunctionAverage
MPSCNNPoolingAverage
Accelerate і Metal забезпечують дуже схожий набір можливостей для нейронних мереж, тому вибір між ними буде залежати від програми. З урахуванням того, що графічні процесори (GPU) зазвичай використовуються для необхідних в машинному навчанні обчислень, локальність даних може стати причиною, по якій версія Metal CNN покаже гірші результати, ніж Accelerate BNNS. Але якщо нейронна мережа працює на основі даних, які були завантажені в графічний процесор за допомогою MPSImage або нового MPSTemporaryImage, в такому випадку Metal виглядає явним переможцем.
джерело