Модификация весовых коэффициентов с помощью градиентного спуска

В этой лекции мы обсудим, как модифицировать весовые коэффициенты нашей модели логистической регрессии для уменьшения ошибки.

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

Модификация весовых коэффициентов с помощью градиентного спуска. Теория

Что мы делали в случае линейной регрессии? Мы формулировали квадратичную функцию ошибок, находили её производную относительно весовых коэффициентов, приравнивали к нулю и таким образом находили значение весовых коэффициентов. В случае кросс-энтропийной функции ошибок мы по-прежнему можем взять производную, но не можем вычислить значение весовых коэффициентов, приравняв производную к нулю. Сомневающимся предлагаю убедиться в этом самостоятельно.

Что же в таком случае мы можем сделать? Пусть у нас есть кривая функции ошибок:

Модификация весовых коэффициентов с помощью градиентного спуска

Установим случайные значения для весового коэффициента в некоторой точке. Предположим, например, что значение производной в этой точке равно -1, а значение весового коэффициента равно -2. Суть в том, чтобы небольшими шагами двигаться в сторону производной.

Размер шага – это то, что мы называем коэффициентом обучения. В нашем примере установим его равным единице. Тогда модифицированное значение весового коэффициента будет равно:

w=-2-1*(-1)=-1.

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

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

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

Мне периодически задают вопрос – как выбирать коэффициент обучения? К сожалению, нет научно обоснованного метода определения коэффициента обучения. Вам просто нужно пробовать разные числа и смотреть, как при этом всё работает.

Итак, как мы можем использовать градиентный спуск применительно к логистической регрессии? Начнём с целевой функции:

J = - \sum_{n=1}^{N} t_n \;log (y_n)+(1 - t_n)\; log (1 - y_n).

Нам нужно найти производную. В дифференциальном счислении есть так называемое цепное правило, поэтому нам необязательно делать всё сразу. Сначала мы можем найти производную по J относительно y, потом найти производную по y относительно сигмоиды (обозначим её через a), затем – производную по a относительно w, после чего их перемножить, чтобы получить окончательный ответ:

\frac {\partial J} {\partial w_i} = \sum_ {i=1}^{N} \; \frac {\partial J} {\partial y_n} \;\frac {\partial y_n} {\partial a_n} \;\frac {\partial a_n} {\partial w_i},

 

 a_n = w^T x_n.

Так и сделаем. Производная \frac {\partial J} {\partial y_n} равна:

\frac {\partial J} {\partial y_n} = - t_n \;\frac {1} {y_n} + (1 - t_n) \frac {1} {1 -y_n} * (-1)

Это потому, что производная логарифма равна единице, делённой на аргумент логарифма.

Далее найдём производную по сигмоиде. Получим:

y_n = \sigma (a_n) = \frac {1} {1 + e^{-a_n}},

\frac {\partial y_n} {\partial a_n} = \frac {-1} {(1 + e^{-a_n})^2} * (e^{-an}) \;* \;-1 = \frac {e^{-an}} {(1+ e^{- a_n})^2}} =\frac {1} {1 + e^{-a_n}} * \frac {e^{-an}} {1+ e^{- a_n} }= y_n (1 - y_n).

Следующее – производная \frac {\partial a_n} {\partial w_i}. Поскольку wi является линейной функцией, ответом будет xni:

a_n = w^Tx_n = w_0 x_{n0} + w_1 x_{n1} + w_2 x_{n2} + \;...

\frac {\partial a_n} {\partial w_i} = x_{ni},

Теперь найдём окончательное решение. Обратите внимание, что в первой части производной \frac {\partial J} {\partial w_i} взаимно сокращается yn, а во второй её части – взаимно сокращается (1 – yn):

\frac {\partial J} {\partial w_i} = - \sum_{n=1}^{N} \frac {t_n} {y_n} y_n (1 - y_n) x_{ni} - \frac {1 - t_n} {1 - y_n} y_n (1 - y_n) x_{ni} =

= - \sum_{n=1}^{N} t_n (1 - y_n) x_{ni} - (1 - t_n) y_n x_{ni}\;

\frac {\partial J} {\partial w_i} = - \sum_{n=1}^{N} [t_n - t_n y_n - y_n + t_n y_n] x_{ni} = \sum_{n =1}^{N} (y_n - t_n) x_{ni}.

Поскольку все элементы с индексом i из левой части зависят только от элементов с индексом i из правой части, мы можем переписать уравнение в векторной форме:

\frac {\partial J} {\partial w}=\sum_{n=1}^{N} (y_n - t_n) x_n,

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

Используя векторную форму, помните, что скалярное произведение является суммой элементов с соответствующими индексами:

a^Tb = \sum_{n = 1}^{N} a_n b_n.

Мы можем переписать наше уравнение в более явно выраженной векторной форме. Не забывайте, что X у нас является матрицей размерности NxD, а Y и T имеют размерность Nx1. W имеет размерность Dx1. Мы можем этого достичь, транспонировав матрицу X и перемножив на выражение YT:

\frac {\partial J} {\partial w} = X^T (Y - T).

 

Получается произведение матриц с размерностями DxN и Nx1, в результате чего получается матрица размерности Dx1, поскольку N является внутренней размерностью, которая сокращается, а внешние размерности равны D и 1.

А что же с членом смещения? В логистической регрессии он легко вводится в уравнение простым добавлением столбца, состоящего из единиц:

\frac {\partial J} {\partial w_0} = \sum_{n=1}^{N} (y_n - t_n) x_{n0} = \sum_{n =1}^{N} (y_n - t_n).

Модификация весовых коэффициентов с помощью градиентного спуска. Код

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

Большую часть кода мы возьмём из предыдущей программы.

import numpy as np

N = 100

D = 2

X = np.random.randn(N,D)

X[:50, :] = X[:50, :] – 2*np.ones((50, D))

X[:50, :] = X[:50, :] + 2*np.ones((50, D))

T = np.array([0]*50 + [1]*50)

ones = np.array([[1]*N]).T

Xb = np.concatenate((ones, X), axis=1)

w = np.random.randn(D + 1)

z = Xb.dot(w)

def sigmoid(z):

return 1/(1 + np.exp(-z))

Y = sigmoid(z)

def cross_entropy(T, Y):

E = 0

для i в xrange(N)

если T[i] == 1:

E -= np.log(Y[i])

еще:

E -= np.log(1 – Y[i])

return E

print cross_entropy (T, Y)

Итак, у нас есть два нормально распределённых класса, один из которых центрируется к точке с координатами (-2; -2), а второй – к точке с координатами (+2; +2). Уберём частное решение для байесовского классификатора. Установим коэффициент обучения равным 0,1, сделаем 100 итераций и будем выводить на экран результат.

learning_rate = 0.1

для i в xrange(100)

если i % 10 == 0:

print cross_entropy(T, Y)

w += learning_rate * np.dot((T-Y).T, Xb)

Y = sigmoid(Xb.dot(w))

print ‘’Final w:’’, w

Запустив программу, увидим, что ошибка резко уменьшается примерно после 30 итераций. Весовые коэффициенты находятся: один – в районе нуля и два значения – в районе 14. Обратите внимание, что хотя это расширение частного случая решения, но полученные значения кажутся чересчур большими.

Мы обсудим это в следующей нашей статье.

Максимизация правдоподобия

Здравствуйте и вновь добро пожаловать на занятия по теме «Обработка данных: логистическая регрессия на языке Python».

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

Итак, пусть у нас есть есть монета, причём вероятность выпадения у неё орла равна p: p(H) = p; эта вероятность нам неизвестна. Тогда вероятность выпадения решки, естественно, равна 1-p: p(T) = 1 – p.

Проведём опыт, чтобы определить значение p. Пусть мы подбросили монету 10 раз (N = 10), причём орёл выпал 7 раз, а решка – три раза.

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

L = p^7 (1 - p)^3.

Мы можем так записать, поскольку каждое кидание монеты является независимым, а потому мы можем перемножить вероятности каждого кидания монеты.

Нам нужно найти максимум L относительно p, а точнее – найти такое p, чтобы L было максимальным. Для этого, конечно, нам придётся использовать дифференциальное счисление. Чтобы избежать трудностей, мы возьмём логарифм функции правдоподобия. Такое действие правомерно, поскольку функция логарифма является монотонно растущей. Это значит, что точка, в которой функция правдоподобия достигает максимума, одновременно является точкой, в которой логарифм функции правдоподобия также достигает максимума.

Этим и займёмся. Обозначим логарифм функции правдоподобия через L:

l = log [p^7 (1 - p)^3] = log p^7 + log (1 - p)^3 = 7 log\;p + 3 log (1 - p).

Приравняем производную к нулю:

\frac {\partial l} {\partial p} = \frac {7} {p} + \frac {3} {(1 - p)} * (-1) = 0.

И решим относительно p:

\frac {7} {p} = \frac {3} {1 - p}; \;hereof \;p = \frac {7} {10} = p (H).

Таким образом, мы получили p = 7/10, что равно вероятности выпадения орла, то есть именно то, чего мы и ожидали.

Используем теперь схожую идею применительно к логистической регрессии.

У нас есть вероятность P(y=1|x)  – мы можем считать её вероятностью выпадения орла при кидании монеты. Она равна сигмоиде произведения транспонированного w на x. Обозначим её через y:

P (y = 1|x) = \sigma (w^T x).

Функция правдоподобия для N случаев будет равна:

L = \prod_{n=1}^{N} y_n\;^{t_n} (1 - y_n)^{1 - t_n}.

Отсюда следует, что если целевая переменная t равна единице, то функция правдоподобия равна yn, а если целевая переменная равна нулю, то правдоподобие равно 1 – yn.

Что любопытно, если мы возьмём логарифм функции правдоподобия, то получим уравнение кросс-энтропийной функции ошибок, которую мы обсуждали ранее:

l = \sum_{n} t_n \;log \;y_n + (1 - t_n) \;log (1 - y_n).

Единственное отличие – отсутствие знака «минус» перед формулой. Таким образом, максимум логарифма функции правдоподобия – это то же самое, что минимум кросс-энтропийной функции ошибок.

Понравилась статья? Поделить с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: