MSE

MSE (Mean Squared Error) или по-русски среднеквадратичная ошибка — это один из самых простых и популярных способов измерения качества работы модели.

Имея правильный ответ y и предсказание ŷ, можно вычислить их разность. Если сложить такие разности для всех ответов, возведённые в квадрат и разделить на количество элементов выборки, получится число, характеризующее качество модели:


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




Для этого случая MSE будет равна 69,2.

Тут мы сталкиваемся с проблемой интерпретации этого значения. В идеальном случае, когда все ответы предсказаны точно, MSE будет равна нулю. А как понять, что показывает число 69,2? Модель сделала предсказание плохо или хорошо? К сожалению, однозначно ответить на эти вопросы невозможно.

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

Когда работаешь с MSE, нужно всегда помнить о том, что эта оценка совершенно неустойчива к выбросам.

Расстояние между двумя точками на поверхности Земли

Представим, что для чего-то понадобилось измерить расстояние между двумя точками на поверхности Земли, например, расстояние между Красной площадью и Эрмитажем. Конечно, можно попробовать решить задачу в лоб и посчитать евклидово расстояние по формуле:


но этот подход не заработает по той простой причине, что евклидова метрика предназначена для вычисления расстояния на плоскости, а поверхность Земли — это всё-таки фигура, очень близкая к сфере.

Для решения такой задачи нужно обратиться к редко используемым тригонометрическим функциям.

Одна из таких функций, называется синус-верзус, или, по-другому, версинус. Он представляет собой расстояние от центральной точки дуги, измеряемой удвоенным данным углом, до центральной точки хорды, стягивающей дугу. Вычисляется версинус по формуле:




Гаверсинус — это просто половина версинуса, и именно эта функция поможет нам в решении задачи с поиском расстояния:





Для любых двух точек на сфере гаверсинус центрального угла между ними вычисляется по формуле:




В этой формуле:


  • d — это центральный угол между двумя точками, лежащими на большом круге

  • r — радиус сферы

  • φ₁ и φ₂ — широта первой и второй точек в радианах

  • λ₁ и λ₂ — долгота первой и второй точек в радианах

Обозначим временно гаверсинус отношения длины к радиусу как переменную h:


Тогда длину d можно вынести за знак равенства:


а для того, чтобы избавиться от дроби, выразим гаверсинус через арксинус:



затем раскроем переменную h:




подставим формулу гаверсинуса и получаем формулу вычисления расстояния:





Теперь вернёмся к исходной задаче поиска расстояния между Красной площадью и Эрмитажем.

Для Красной площади Гугл подсказал координаты (55.7539° N, 37.6208° E), а для Эрмитажа — (59.9398° N, 30.3146° E).

Прежде, чем подставлять координаты в формулу, их нужно перевести в радианы.

Для того, чтобы вычислить длину, в соответствии с формулой, нужно полученное значение арксинуса умножить на два радиуса сферы. Подсчёты усложняет тот факт, что Земля не является идеальной сферой и её радиус немного варьируется. Воспользуемся усреднённым значением радиуса, который, в соответствии со стандартом WGS84 приблизительно равен 6371км:




Произведя умножение, получаем искомое значение, которое приблизительно равно 634.57 км.

Кстати, из-за того, что Земля — не идеальная сфера, погрешность расчётов с использованием этой формулы, составляет около 0,5%.

Правило Стёрджеса

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

Железного стопроцентного правила, которое позволяет решить эту проблему, не существует. Однако, есть несколько популярных вариантов.

Первый и самый известный вариант — правило Стёрджеса, подойдет в том случае, когда данные имеют нормальное распределение:



где n — количество элементов выборки.

Вместо логарифма по основанию 2, в таком случае формула будет выглядеть так:



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





затем поделить получившееся значение на k:



Этот подход был предложен в далёком 1926 году, когда размеры выборок, по сравнению с современными, были микроскопичными, поэтому принято считать, что оно хорошо работает с массивами, содержащими до 200 элементов.

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


или интерквартильный размах:




В некоторых случаях для определения количества частей хорошо подходит простой метод — вычисление квадратного корня из количества элементов:


(no subject)

Для того, чтобы быстро найти тег LaTeX для символа, который никогда не писал или писал давно, но забыл, например, proportional to "", нужно пойти на сайт detexify.kirelabs.org, написать символ от руки и получить тег.

Норма Фробениуса

Норма Фробениуса или, как её ещё называют Евклидова норма, — это квадратный корень сумм квадратов модулей элементов матрицы размера m × n:

Простой пример. Есть матрица размера 3 × 3:

Она же, но с элементами, возведёнными в квадрат:

Сумма элементов этой матрицы будет равна 60. Квадратный корень из 60 примерно равен 7,746. Это число и есть норма Фробениуса для нашей матрицы.

Есть иной способ вычисления нормы Фробениуса: как квадратный корень произведения следа этой матрицы и эрмитово-сопряжённой матрицы:


https://ru.wikipedia.org/wiki/Норма_матрицы#Норма_Фробениуса

генератор, нарезанный на куски

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

Задача лаконично решается при помощи itertools.islice и itertools.chain:

from itertools import chain, islice

def batcher(data, b_size):
    iterator = iter(data)
    for first in iterator:
        yield list(chain([first], islice(iterator, b_size-1)))

PReLU

PReLU или Parametric ReLU — это логическое развитие обыкновенной активационной функции ReLU. Основное отличие между ними состоит в том, что у PReLU есть обучаемые параметры.

PReLU определяется следующей формулой:



В этой формуле yi — это то, что приходит на вход активационной функции канала i, а ai — это коэффициент, отвечающий за наклон отрицательной части. Индекс i у параметра ai показывает, что нелинейная активация может быть разной для разных каналов. При этом, если ai приравнять к нулю, активационная функция превратится в простую ReLU.

Формулу выше можно записать ещё и немного по-другому:




Вот как выглядит PReLU на графике, при параметре ai = 0.25:




Если значение параметра ai мало и фиксированно, например 0.01, PReLU становится Leaky ReLU (LReLU). Основной идеей создания LReLU было устранение нулевого градиента, однако, по факту, LReLU даёт ничтожно малый прирост точности, по сравнению с обычной ReLU, поэтому о ней нет смысла говорить.

Функция PReLU хороша тем, что с её добавлением, количество параметров сети увеличивается незначительно: общее количество новых параметров каждого слоя всего лишь равно количеству каналов этого слоя.

PReLU может быть channel-shared. Это означает, что значение параметра a будет общим для всех каналов. В этом случае в формуле у параметра не будет индекса:




Оптимизация

Градиент параметра ai для одного слоя вычисляется по формуле:




где ℇ — это оптимизируемая функция.

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



а правая часть — градиент активации, который вычисляется как:



Для channel-shared варианта в формулу добавляется ещё один знак суммы:



потому как в этом случае требуется суммировать все каналы слоя.

Обновление значения параметра ai производится по формуле:


в которой µ — это momentum, а ϵ — скорость обучения.

При обновлении значения параметра ai не используется L2-регуляризация (weight decay), поскольку она быстро приводит значение параметра к нулю, а это превращает PReLU в обычную ReLU.




Kaiming He et al. Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification. arXiv:1502.01852 [cs.CV]

вымывание и взрыв градиента

При построении глубокой сети с очень большим количеством слоёв появляются неприятные эффекты — вымывание градиента и его взрыв (vanishing/exploding gradients).

Для того, чтобы понять, откуда берутся эти эффекты, поглядим на сеть с большим количеством слоёв:


Для простоты на схеме показано по два нейрона на каждом слое, но это лишь для упрощения восприятия, на самом деле их может быть много, а самих слоёв — больше сотни.

У каждого слоя этой сети есть своя матрица весов: w[1], w[2],w[3] и так далее, вплоть до w[l].

Для упрощения будем считать, что активационная функция линейна:




а вектор bias равен нулю:




В этом случае предсказание ŷ будет представлять собой произведение матриц весов всех слоёв и x:



Почему так? Поглядим внимательно на произведение двух последних элементов w[1] и x. Так как мы условились ранее, что bias равен нулю, то это будет не что иное как z[1]:


a[1] — это нелинейность, применённая к z[1], но, так как мы договорились, что нелинейность у нас линейная, a[1] будет равно z[1]:




Логично, что произведение последних трёх элементов будет представлять собой a[2]:




a[3], в свою очередь, будет представлять собой произведение последних четырёх элементов:


и так далее, вплоть до последней матрицы w[l]. Общее произведение всех матриц и x в итоге дают предсказание ŷ.

Теперь представим, что значения элементов всех матриц весов w[l] чуть больше, чем у единичной матрицы:



Так как размерность последней матрицы w[l] может отличаться от остальных, ŷ можно представить как произведение w[l] на матрицу в степени (l-1), умноженную на x:



По сути, значение ŷ будет равно 1.5 в степени (l-1), умноженное на x:


Если сеть глубока, то значение l будет большим и, соответственно, значение ŷ будет очень большим.

А теперь представим, что значения в матрицах весов стали немного меньше нуля, например, 0.5:




в этом случае значение ŷ будет очень маленьким.

Если значения матрицы весов чуть больше, чем единичная матрица, то для очень глубокой сети следует ожидать градиентный взрыв. Если значения чуть меньше, чем единичная матрица, то произойдёт вымывание градиента.



Спасибо, Andrew Ng

jupyter в python script без # In[]:

По дефолту jupyter nbconvert --to python перед кодом каждой ячейки проставляет комментарий # In[]: с номером ячейки внутри квадратных скобок. Избавиться от этого визуального мусора можно при помощи параметра --TemplateExporter.exclude_input_prompt=True.


http://nbconvert.readthedocs.io/en/latest/config_options.html

матрица latex и выравнивание элементов

Если для матрицы использовать {bmatrix}:

\begin{bmatrix}
0 & -7 & 2 \\
-3 & 1 & 0 \\
8 & 2 & -1
\end{bmatrix}


то выравнивание элементов по умолчанию производится по центру:




Как простым способом заставить {bmatrix} выравнивать по правой стороне, найти не удалось, но нашёлся другой способ — {array}  с выравниванием {rrr}:


\left[
\begin{array}{rrr}
0 & -7 & 2 \\
-3 & 1 & 0 \\
8 & 2 & -1
\end{array}
\right]


на выходе получается вот так: