Обсуждении учебных данных для нейронной сети

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

Во-первых, как вы могли заметить, при обсуждении учебных данных для нейронной сети входные переменные мы обозначаем через X, а целевые переменные – через Y. В общем случае они являются матрицами. X имеет размерность NxD, где N – количество примеров (наблюдений), а D – количество входных признаков. Y иногда считается имеющей размерность Nx1; при работе с матрицами это значит, что Y записывается в виде вектора-столбца. Обратите внимание, что запись Nx1 означает, что мы работаем с двухмерным объектом. В других случаях Y может рассматриваться просто как вектор длины N; тогда это будет одномерный объект. В Numpy он рассматривается именно в таком понимании, поэтому обычно при работе с кодом Y будет одномерным объектом размера N, в отличие от двухмерного объекта размером Nx1.

Неотъемлемой частью нашей работы являются прогнозы. Если X представляет собой входные переменные, а Y – целевые переменные, то p(Y|X) является прогнозом. P(Y|X) представляет собой полное распределение вероятностей по всем индивидуальным значением внутри матрицы Y при заданной матрице X. Это матрица такой же размерности, как и Y.

С другой стороны, p(y=k|X) означает значение вероятности. Оно представляет собой вероятность того, что y принадлежит к классу k при заданном входном векторе x.

Обратите внимание, что, как правило, при рассмотрении отдельных наблюдений или векторов мы используем маленькие буквы, а когда речь идёт о матрицах – то большие.

Запись P(Y|X) весьма неудобна, особенно при написании кода. Как вы знаете, имена переменных не могут содержать круглые скобки, поэтому приходится использовать имена переменных вроде p_y_given_x, py_x или Py, ни одно из которых на самом деле не является оптимальным. Одна из старых этому альтернатив, с которой вы познакомились в курсе линейной регрессии, – использовать для обозначения прогноза символ ŷ, который в коде мы называли переменной Yhat. Заметьте, что и в этом случае нужный символ не получается представить как имя переменной в коде.

Именно из-за таких случаев и происходит путаница. Другой альтернативой может быть использование X для обозначения входных переменных, T – для целевых переменных, Y – для прогнозов. Это удобно в том плане, что исчезает необходимость везде писать p(Y|X). Впрочем, это Y всё равно входит в противоречие с другим Y, поскольку ранее Y обозначало целевую переменную, а теперь – прогноз.

Вот потому-то очень важно знать контекст, в котором используется Y, чтобы понимать, в каком значении оно используется. Если вы одновременно видите Y и T, то должно быть ясно, что T – это целевая переменная, а Y – прогнозная переменная. Если Y присваивается значение исходящей переменной нейронной сети, то должно быть понятно, что Y – прогнозная переменная. Если же вы видите вместе Y и Y_hat или Y и p_y_given_x, то, очевидно, Y в этом случае является целевой переменной.

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

Как вы, вероятно, уже поняли из предыдущих лекций этого курса, у нас есть несколько соглашений о величинах объектов. К примеру, N означает количество собранных нами наблюдений (примеров) эксперимента, D представляет количество входных признаков, являющееся к тому же размером входного слоя нейронной сети, M означает размер скрытого слоя, а K представляет размер исходящего слоя. K является числом исходящих классов и может быть любой величиной от 2 и больше. Обратите внимание, что все они пишутся с большой буквы, но подробнее мы обсудим это позже.

Если у нас нейронная сеть с одним скрытым слоем, одним из способов обозначения весовых коэффициентов является следующий. Матрица весовых коэффициентов, идущих от входного слоя к скрытому, обозначается W, а свободные члены скрытого слоя обозначаются b. Всё это вы уже видели в линейной и логистической регрессиях. В нейронных сетях матрица весовых коэффициентов от скрытого к исходящему слою обозначается V, а свободные члены исходящего слоя обозначаются через c. Не забывайте, что поскольку W, b и c должны отображать вектор от предыдущего слоя к последующему, то размерность W должна быть равной DxM, размерность b должна быть равной M, размерность V – равной MxK, а размерность c – равной K.

Вы можете представить ситуацию, когда при дальнейшем добавлении слоёв в нейронную сеть у нас закончатся буквы, поэтому использование V и c на самом деле может оказаться проблематичным. Вместо этого мы можем перечислить количество наших W и b. Так, при переходе от входного слоя к первому скрытому у нас будут W1 и b1, при переходе от первого скрытого слоя ко второму скрытому слою у нас будут W2 и b2 и так далее. Но поскольку W и b у нас теперь пронумерованы, нам придётся, чтобы не перепутать, присваивать им индексы по-другому. Например, номер слоя можно оставить в качестве индекса, а собственно индексы записывать в круглых или квадратных скобках. Другой вариант – оставить предыдущие подстрочные индексы, а номер слоя записывать надстрочным индексом:

Любой из этих способов хорош, если они позволяют не запутаться.

В связи с вышесказанным мы можем указывать или не указывать индексы в разных местах, если они являют собой разные вещи. К примеру, если мы рассматриваем целевую переменную T конкретно для n-го наблюдения и k-го класса, мы можем обозначить её несколькими способами. В Numpy, как мы знаем, всё будет рассматриваться как матрицы, поэтому мы можем записать T[n,k]. В других случаях мы можем также писать T(n,k), Tnk, Tnk и так далее. Главное – помнить, что n и k представляют собой разные вещи: k показывает, какой рассматривается узел исходящего слоя нейронной сети, а n – какое рассматривается наблюдение из наших данных. Поэтому, видимо, лучшим вариантом является использование надстрочных и подстрочных индексов.

Ещё одна связанная с этим проблема – это какие именно буквы мы используем для индексов. Как вы знаете из математики и программирования, i, j и k являются общеупотребимыми при написании оператора цикла или суммирования. Так, в предыдущем примере мы использовали i для индексирования входного слоя, так что оно пробегало значения от 1 до D, j мы использовали для индексирования скрытого слоя, так что оно пробегало значения от 1 до M, а k – для индексирования исходящего слоя, так что оно пробегало значения от 1 до K. I, j и k являются, как вы, вероятно, убедились при изучении программирования, общеупотребимыми, так что неудивительно, что и здесь может быть путаница.

Та же проблема с i, j и k возникает снова, когда у нас заканчиваются буквы – например, когда у нас больше одного скрытого слоя и нам нужно подобрать новые индексы вне этих трёх букв. Самый общий способ – подобрать такие буквы, которые не используются где-либо ещё – например, q, r и s.

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

Далее, у нас есть ещё и коэффициент обучения, который, как вы знаете, используется в градиентном спуске. Обычно для коэффициента обучения мы используем греческие буквы вроде θ или α. В принципе, из контекста должно быть ясно, что мы делаем, поскольку градиентный спуск всегда выступает в одной и той же форме.

И наконец, у нас есть функция затрат, она же целевая функция. Её также иногда называют функцией ошибок. Как правило, для её обозначения мы используем буквы E и J. Обычно при упоминании затрат или ошибки мы говорим о чём-то, что хотим минимизировать. Но, как вы знаете, при использовании вероятностной интерпретации минимизация затрат эквивалентна минимизации отрицательного логарифма функции правдоподобия, что, естественно, в свою очередь эквивалентно максимизации логарифма функции правдоподобия. Таким образом, минимизируя отрицательный логарифм функции правдоподобия, вы совершаете градиентный спуск, а максимизируя логарифм функции правдоподобия, вы совершаете градиентное восхождение.

Обычно мы используем большую букву L для обозначения функции правдоподобия и малую букву l для обозначения логарифма функции правдоподобия. Но иногда, говоря о логарифме функции правдоподобия или даже отрицательном логарифме функции правдоподобия, мы будем использовать просто большую букву L, поскольку малое l можно легко перепутать с большим I.

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

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

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

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

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

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

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

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

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

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