Неделя 2: Основы программирования нейронных сетей

искусственный интеллект

Неделя 2: Основы программирования нейронных сетей

Каталог статей

2.1 Бинарная классификация

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

Кроме того, при расчете нейронной сети обычно есть первый шаг, называемый паузой вперед (forward pause) или прямое распространение (foward propagation), за которым следует шаг, называемый обратной паузой (backward pause) или шаг, называемый обратным распространением**. Так что на этой неделе я также покажу вам, почему процесс обучения нейронной сети можно разделить на две отдельные части: прямое распространение и обратное распространение.

В курсе я буду использовать логистическую регрессию (logistic regression), чтобы передать эти идеи, чтобы концепции можно было легче понять. Даже если вы узнали о логистической регрессии раньше, я думаю, что здесь есть что-то новое и интересное, ожидающее своего открытия и понимания, так что давайте приступим к делу.

Логистическая регрессия — это метод бинарной классификации (binary classification) алгоритм. Прежде всего, давайте начнем с задачи.Вот пример задачи с двумя классами.Если у вас есть изображение в качестве входных данных, например этот кот, если вы распознаете это изображение как кота, выведите метку 1 в качестве результата; если распознано, что это не кошка кошка, то в качестве результата выведите метку 0. Теперь мы можем использовать буквы y y y для обозначения результирующей метки вывода, как показано ниже:
269118812ea785aee00f6ffc11b5c882

Давайте посмотрим, как изображение представляется на компьютере.Чтобы сохранить изображение, вам необходимо сохранить три матрицы, которые соответствуют красному, зеленому и синему цветовым каналам в изображении.Если размер вашего изображения 64x64 пикселей, то у вас есть три матрицы размером 64x64, соответствующие значениям интенсивности красного, зеленого и синего пикселей в изображении. Для простоты изложения здесь я нарисовал три очень маленькие матрицы, обратите внимание, что они имеют масштаб 5х4 вместо 64х64, как показано на изображении ниже:
在这里插入图片描述

Чтобы поместить эти значения пикселей в вектор признаков, нам нужно извлечь эти значения пикселей и поместить их в вектор признаков x x x. Чтобы преобразовать эти значения пикселей в вектор признаков xxx, нам нужно определить вектор признаков xxx следующим образом, чтобы представить это изображение: мы убираем все пиксели, такие как 255, 231 и т. д., пока все красные пиксели вынимаются, затем, наконец, 255, 134,..., 255, 134 и т. д., пока вы не получите вектор признаков, в котором перечислены все значения красных, зеленых и синих пикселей в изображении. Если размер изображения 64х64 пикселя, то суммарные размеры вектора х х х будут 64 на 64 на 3, что является общим количеством пикселей в трехпиксельной матрице. В этом примере результат равен 12 288. Теперь мы используем n x = 12 , 288 n_x = 12 288 nx​= 12 288 для представления размерности входного вектора признаков. Иногда для краткости я буду напрямую использовать строчную букву n n n для представления размерности входного вектора признаков x x x. Итак, в задаче с двумя классами наша цель состоит в том, чтобы изучить классификатор, который принимает вектор признаков изображения в качестве входных данных, а затем предсказывает, равен ли результат yyy 1 или 0, то есть предсказывает, есть ли на картинке кошка. :
在这里插入图片描述

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

Определение символа:

x x x: представляет размерные данные n x n_x nx​, которые являются входными данными, и размерность ( n x , 1 ) (n_x,1) (nx​,1);

y ​ y​ y​: указывает результат вывода, значение равно ( 0 , 1 ) ​ (0,1)​ (0,1)​;

( x ( i ) , y ( i ) ) (x ^ {(i)}, y ^ {(i)}) (x (i), y (i)): представляет iii группу данных, возможно, обучающие данные или тестовые данные, которые по умолчанию являются обучающими данными;

X = [x(1),x(2),...,x(m)] X=[x^{(1)},x^{(2)},...,x^{(m )}] X=[x(1),x(2),...,x(m)]: указывает входные значения всех наборов обучающих данных, помещенных в nx × m n_x×m nx​× матрица m, где mmm представляет количество выборок;

Y = [y(1),y(2),...,y(m)] Y=[y^{(1)},y^{(2)},...,y^{(m )}] Y=[y(1),y(2),...,y(m)]: соответствует выходному значению всех обучающих наборов данных с размерностью 1 × m 1 × m 1 × m .

Пара ( x , y ) (x, y) (x, y) используется для представления одной выборки, xxx представляет собой вектор признаков размером nx n_x nx​, yyy указывает, что метка (результат вывода) может быть только 0 или 1.
И обучающая выборка будет состоять из ммм обучающих выборок, где ( x ( 1 ) , y ( 1 ) ) (x ^ {(1)}, y ^ {(1)}) (x (1), y (1) ) Представляет ввод и вывод первой выборки, ( x ( 2 ) , y ( 2 ) ) (x ^ {(2)}, y ^ {(2)}) (x (2), y (2)) представляет ввод и вывод второй выборки до последней выборки ( x ( m ) , y ( m ) ) (x ^ {(m)}, y ^ {(m)}) (x (m), y (m) )), то все они вместе представляют всю обучающую выборку. Иногда, чтобы подчеркнуть, что это количество обучающих выборок, его записывают как M train M_{train} Mtrain​, Когда дело доходит до тестового набора, мы будем использовать M test M_{test} Mtest​ для представления количество образцов в тестовом наборе. Итак, это количество образцов в тестовом наборе:
在这里插入图片描述

Наконец, чтобы представить обучающий набор более компактно, мы определим матрицу, представленную в верхнем регистре XXX, которая состоит из входного вектора x ( 1 ) x ^ {(1)} x (1), x ( 2 ) x ^ { (2)} x(2) и т. д., и помещаем их в столбцы матрицы, как показано ниже, так что теперь мы помещаем x ( 1 ) x^{(1)} x(1) в качестве первого столбца в матрица x ( 2) x^{(2)} x(2) в качестве второго столбца, x ( m ) x^{(m)} x(m) помещается в mmm-й столбец, а затем мы получить матрицу тренировочного набора XXX. Итак, эта матрица имеет столбцы mmm, mmm - количество выборок в обучающем наборе, а затем высота этой матрицы обозначается как nx n_x nx​, обратите внимание, что иногда по другим причинам матрица XXX будет складываться обучающими выборками в строках вместо столбцов, как показано на следующем рисунке: транспонирование x ( 1 ) x^{(1)} x(1) до транспонирования x ( m ) x^{(m)} x(m) , но в реализации нейросети При использовании формы слева весь процесс реализации упрощается:
在这里插入图片描述

Теперь для быстрого освежения: X X X — это матрица размера n x n_x nx, умноженная на m m m, когда вы используетеPythonПри реализации вы увидитеX.shape, этоPythonкоманда для отображения масштаба матрицы, т.е.X.shapeРавный ( n x , m ) (n_x,m) (nx​,m), X X X представляет собой матрицу размера n x n_x nx​, умноженную на m m m. Подводя итог, вот как обучающие выборки (набор входных векторов X X X) представлены в виде матрицы.

Как насчет выходных меток y y y? Точно так же, чтобы упростить реализацию нейронной сети, добавление в столбец метки yyy сделает последующие вычисления очень удобными, поэтому мы определяем YYY в верхнем регистре равным y(1), y(m),... , у ( м ) {{у} ^ {\ влево ( 1 \ справа)}}, {{у} ^ {\ влево ( м \ справа)}}, ..., {{у} ^ {\ влево ( m \right)}} y(1),y(m),...,y(m), так что вот матрица размера 1 на mmm, используйте то же самоеPythonбудет представлен какY.shapeравно ( 1 , m ) (1,m) (1,m), что указывает на то, что это матрица размером 1 на m m m.
在这里插入图片描述

По мере реализации нейронных сетей на последующих уроках вы обнаружите, что правильное соглашение об обозначениях хорошо организует данные различных обучающих выборок. И я говорю о данных, которые включают не только x x x или y y y, но и другие величины, которые вы увидите позже. Возьмите данные для разных обучающих выборок и сложите их в столбцы матрицы, как мы только что сделали для xxx или yyy, чтобы сформировать символическое представление, которое мы будем использовать позже для логистической регрессии и нейронных сетей. Если иногда вы забываете значение этих символов, например, что такое ммм или что такое ннн, или забываете что-то еще, мы также разместим описание символов на веб-сайте курса, и тогда вы сможете быстро обратиться к каждому конкретному. Что означает символ означает, что ж, давайте перейдем к следующему видео, где мы начнем с логистической регрессии.
Примечание. Описание символов также приведено в приложении.

2.2 Логистическая регрессия

В этом видео мы рассмотрим алгоритм обучения логистической регрессии, который подходит для задач бинарной классификации, В этом разделе в основном будет представлена ​​логистическая регрессия.Hypothesis Function(предполагая функцию).

Для задач двоичной классификации, учитывая входной вектор признаков XXX, он может соответствовать изображению, вы хотите идентифицировать это изображение, чтобы увидеть, является ли это изображением кошки или нет, вам нужен алгоритм Чтобы иметь возможность выводить прогноз, вы можете назвать его только y ^ \hat{y} y^​, что является вашей оценкой фактического значения yyy. Говоря более формально, вы хотите, чтобы y ^ \hat{y} y^​ представляло возможность или шанс того, что y y y равно 1, учитывая входные признаки X X X. Другими словами, если X X X — это изображение, которое мы видели в последнем видео, вы хотите, чтобы y ^ \hat{y} y^​ сказало вам, насколько вероятно, что это изображение кота. Как упоминалось в предыдущем видео, X X X представляет собой вектор размерности n x n_x nx (эквивалентный вектору признаков с признаками n x n_x nx). Мы используем www для представления параметров логистической регрессии, которая также является вектором размерности nx n_x nx (поскольку www на самом деле является весовым коэффициентом признака, размерность такая же, как у вектора признака), и в параметре есть bbb, который является действительным числом (представляющим смещение). Таким образом, учитывая входные данные xxx и параметры www и bbb, как нам сгенерировать выходное прогнозируемое значение y ^ \hat{y} y^​, вы можете попробовать, но не делать, это пусть y ^ = w T x + b \ шляпа{y}={{w}^{T}}x+by^​=wTx+b.
在这里插入图片描述

На этом этапе мы получаем линейную функцию на входе xxx, которую вы фактически используете при выполнении линейной регрессии, но это не очень хороший алгоритм для задач бинарной классификации, потому что вы хотите y ^ \hat{y} y^ представляет вероятность того, что фактическое значение yyy равно 1, y ^ \hat{y} y^​ должно быть между 0 и 1. Это проблема, которую необходимо решить, потому что w T x + b {{w}^{T}}x+b wTx+b может быть намного больше 1 или даже иметь отрицательное значение. Это не имеет смысла для вероятности, которую вы хотите от 0 до 1, поэтому в логистической регрессии наш результат должен быть y ^ \hat{y} y^​равным линейной функции, полученной из вышеприведенного дочернего элемента в качестве независимой переменной.sigmoidВ функции в нижней части рисунка выше показана формула, которая преобразует линейную функцию в нелинейную.

На картинке нижеsigmoidГрафик функции, если поставить горизонтальную ось как ось z z z, то примерно z z zsigmoidФункция такая, она плавно переходит от 0 к 1, позвольте мне обозначить здесь вертикальную ось, это 0, точка пересечения кривой, пересекающей вертикальную ось, равна 0,5, а это примерно z z zsigmoidИзображение функции. Обычно мы используем z z z для представления значения w T x + b {{w}^{T}}x+b wTx+b.
在这里插入图片描述

оsigmoidФормула для функции такова: z )=1+e−z1​, где zzz — действительное число, вот некоторые вещи, на которые следует обратить внимание: если zzz очень велико, то e − z {{e}^{-z}} e−z будет близко к 0, о зззsigmoidФункция будет приблизительно равна 1, деленному на 1, плюс некоторый член, очень близкий к 0, потому что показатель степени eee будет близок к 0, если это отрицательное число с большим абсолютным значением, поэтому, если zzz велико, то около zzzsigmoidФункция будет очень близка к 1. И наоборот, если zzz очень маленькое или отрицательное число с большим абсолютным значением, то e − z {{e}^{-z}} e−z станет очень большим числом, вы можете подумать, что это 1, деленное на 1 плюс очень, очень большое число, так что это близко к 0. На самом деле вы видите, что когда z z z становится большим отрицательным числом по модулю, примерно z z zsigmoidФункция будет очень близка к 0, поэтому при реализации логистической регрессии ваша задача состоит в том, чтобы сделать параметры машинного обучения www и bbb такими, чтобы y ^ \hat{y} y^​ стала парой y = 1 y=1 y = 1 является хорошей оценкой вероятности случая.
在这里插入图片描述

Прежде чем перейти к следующему шагу, введем соглашение об обозначениях, которое отделяет параметр w w w от параметра b b b. Следует отметить одну вещь относительно обозначений: когда мы программируем нейронные сети, мы часто отделяем параметры w w w от параметров bb b, где параметр bb соответствует смещению. Возможно, вы видели другие символические представления этой проблемы в предыдущих курсах по машинному обучению. Например, в некоторых случаях вы определяете дополнительную функцию с именем x 0 {{x}_{0}} x0​ и делаете ее равной 1, тогда XXX теперь является переменной nx n_x nx​плюс 1 измерение , тогда вы определяете y ^ = σ ( θ T x ) \ hat {y} = \ sigma \ left ( {{\ theta } ^ {T}} x \ right) y ^​= σ (θTx)sigmoidфункция. В этом альтернативном соглашении о записи у вас есть вектор параметров θ 0 , θ 1 , θ 2 , . \theta }_{2}},...,{{\theta }_{{{n}_{x}}}} θ0​,θ1​,θ2​,...,θnx​​ , так что θ 0 {\theta }_{0}} θ0​ действует как bbb, которое является действительным числом, а остальные θ 1 {\theta }_{1}} θ1​ до θ nx {{\theta }_ {{{n}_{x}}}} θnx действует как www, в результате чего при реализации нейронной сети существует более простой способ разделить bbb и www. Но в этом уроке мы не будем использовать ни одно из этих условных обозначений, так что не волнуйтесь.
Теперь, когда вы знаете, как выглядит модель логистической регрессии, следующее, что нужно сделать, это обучить параметры w w w и параметры b b b, вам нужно определить функцию стоимости, давайте объясним это на следующем уроке.

2.3 Функция стоимости логистической регрессии

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

Зачем нужна функция стоимости:

Для обучения параметров w w w и параметра b b b модели логистической регрессии нам нужна функция стоимости, а параметр w w w и параметр b b b получаются путем обучения функции стоимости. Давайте сначала посмотрим на выходную функцию логистической регрессии:
在这里插入图片描述

Чтобы модель научилась настраивать параметры, вам нужно предоставить обучающий набор образцов mm, который позволит вам найти параметры w w w и параметры b b b на обучающем наборе, чтобы получить результат.

Для прогнозируемого значения обучающего набора мы записываем его как y ^ \hat{y} y^​, мы надеемся, что он будет близок к значению yyy в обучающем наборе, Чтобы представить приведенную выше формулу более подробно, нам нужно объяснить вышеизложенное Определение для обучающей выборки, эта форма также используется для каждой обучающей выборки, мы используем эти надстрочные индексы со скобками, чтобы отличить индекс от выборки, прогнозируемое значение, соответствующее обучающей выборке iii, равно y ( i ) {{y}^{(i)}} y(i), is w T x ( i ) + b {{w}^{T}}{{x}^{(i)}}+ b wTx (i)+b, затем пройтиsigmoidфункция, которую нужно получить, или zzz можно определить как z ( i ) = w T x ( i ) + b {{z}^{(i)}}={{w}^{T}}{{x}^{ (i)}}+bz(i)=wTx(i)+b, мы будем использовать это обозначение ( i ) (i) (i) для аннотации, верхний индекс ( i ) (i) (i) для указания того, что данные представляет xxx Или yyy или zzz или iii обучающую выборку других данных, вот что означает верхний индекс (i)(i)(i).

Функция потерь:

Функция потерь, также известная как функция ошибок, используется для измерения работы алгоритма.Функция потерь: L ( y ^ , y ) L\left( \hat{y},y \right) L(y^​,y).

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

Функция потерь, которую мы используем в логистической регрессии: y \right)=-y\log(\hat{y})-(1-y)\log(1-\hat{y}) L(y^​,y)=-ylog(y^​)− (1-y) лог(1-y^​)

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

Когда y = 1 y=1 y=1 функция потерь L = − log ⁡ ( y ^ ) L=-\log (\hat{y}) L=−log(y^​), если вы хотите, чтобы функция потерь LLL должно быть как можно меньше, то y ^ \hat{y} y^​ должно быть как можно больше, потому чтоsigmoidФункция принимает значение [ 0 , 1 ] [0,1] [0,1], поэтому y ^ \hat{y} y^​ будет бесконечно близко к 1.

Когда y = 0 y=0 y=0 функция потерь вы хотите, чтобы функция потерь LLL была как можно меньше, тогда y ^ \hat{y} y^​ должно быть как можно меньше, потому чтоsigmoidФункция принимает значение [ 0 , 1 ] [0,1] [0,1], поэтому y ^ \hat{y} y^​ будет бесконечно близко к 0.

В этом классе есть много функций, которые имеют аналогичные эффекты с текущей, то есть, если yyy равно 1, мы стараемся сделать y ^ \hat{y} y^​ как можно большим, а если yyy равно до 0, мы пытаемся сделать y как можно больше ^ \hat{y} y^​ становится меньше.
Функция потерь определяется в одной обучающей выборке. Она измеряет, насколько хорошо алгоритм работает в одной обучающей выборке. Чтобы измерить, насколько хорошо алгоритм работает на всех обучающих выборках, нам нужно определить функцию стоимости алгоритма. Функция стоимости алгоритма представляет собой суммирование функции потерь по образцам ммм и деление на ммм:
J ( ш , б ) знак равно 1 м ∑ я знак равно 1 м L ( y ^ ( я ) , y ( я ) ) знак равно 1 м ∑ я знак равно 1 м ( - y ( я ) журнал ⁡ y ^ ( я ) - ( 1 - y ( я ) ) журнал ⁡ ( 1 - y ^ ( я ) ) ) J \ влево ( ш , б \ вправо) = \ гидроразрыва {1} {м} \ сумма \ limits_ {я = 1} ^ {м }{L\left( {{{\шляпа{y}}}^{(i)}}, {{y}^{(i)}} \right)}=\frac{1}{m}\sum \limits_{i=1}^{m}{\left( -{{y}^{(i)}}\log {{{\hat{y}}}^{(i)}}-(1- {{y}^{(i)}})\log (1-{{{\hat{y}}}^{(i)}}) \right)} J(w,b)=m1​i= 1∑mL​L(y^​(i),y(i))=m1​i=1∑m​(−y(i)logy^​(i)−(1−y(i))log( 1−у^(я)))
Функция потерь применима только к одной обучающей выборке, подобной этой, а функция стоимости представляет собой общую стоимость параметров, поэтому при обучении модели логистической регрессии нам нужно найти соответствующие www и bbb, чтобы минимизировать общую стоимость функция стоимости JJJ .
В соответствии с нашим выводом алгоритма логистической регрессии и выводом функции потерь для одной выборки и выводом функции общих затрат для параметров, выбранных алгоритмом, результаты показывают, что логистическую регрессию можно рассматривать как очень небольшую Нейронная сеть В следующем видео мы увидим, что делают нейронные сети.

2.4 Градиентный спуск

Что может градиентный спуск?

На своем тестовом наборе обучите параметры w w w и b b b путем минимизации функции стоимости (функции стоимости) J ( w , b ) J (w, b) J (w, b),
在这里插入图片描述

Как показано на рисунке, во второй строке дана функция стоимости (cost function) того же алгоритма логистической регрессии, что и раньше.

Визуальная иллюстрация градиентного спуска
在这里插入图片描述

На этом рисунке горизонтальная ось представляет ваши параметры пространства, а www bbb, на практике www может быть более высоким измерением, но для лучшей графики, и мы определяем www bbb, это единственное действительное число, функция стоимости (функция стоимости) J (w, b) J (w, b) J (w, b) криволинейная поверхность на горизонтальной оси www и bbb, поэтому высота поверхности равна J (w, b) J (w, b) J ( w , б) значение функции в точке. Что мы делаем, так это находим, что функция стоимости (функция стоимости) J (w, b) J (w, b) J (w, b) является минимальным значением, соответствующим w w w и параметру b b b.
在这里插入图片描述

Как показано на рисунке, функция стоимости (функция стоимости) J ( w , b ) J(w,b) J(w,b) является выпуклой функцией (convex function), как большая чаша.
在这里插入图片描述

Как показано на рисунке, это несколько противоположно предыдущему рисунку, потому что оно невыпуклое и имеет много разных локальных минимумов. Из-за свойства функции стоимости (функции стоимости) J (w, b) J(w,b) J(w,b) логистической регрессии мы должны определить функцию стоимости (функцию стоимости) J (w, b) J (w,b ) J(w,b) — выпуклая функция.
инициализировать w w w и b b b,
在这里插入图片描述

Параметры www и bbb можно инициализировать маленькой красной точкой на рисунке или можно использовать метод случайной инициализации.Почти все методы инициализации для логистической регрессии действительны, поскольку функция является выпуклой функцией, независимо от того, где она инициализирована, он должен достичь той же точки или примерно той же точки.
在这里插入图片描述

Мы инициализируем параметры w w w и b b b координатами маленькой красной точки, как показано на рисунке.

2. Сделайте шаг к самому крутому спуску и продолжайте повторять
在这里插入图片描述

Мы сделали шаг в сторону самого крутого спуска, как показано на картинке, и дошли до второй маленькой красной точки на картинке.
在这里插入图片描述

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

3. Пока вы не достигнете глобального оптимального решения или места, близкого к глобальному оптимальному решению.

Через три вышеуказанных шага мы можем найти глобальное оптимальное решение, то есть точку минимума выпуклой функции функции стоимости (функции стоимости) J (w, b) J(w,b) J(w,b) .

Подробное описание метода градиентного спуска (только один параметр)
在这里插入图片描述

Предполагая, что функция стоимости (функция стоимости) J(w)J(w)J(w) имеет только один параметр www, то есть вместо многомерной кривой используется одномерная кривая, так что изображение может лучше нарисуй.
在这里插入图片描述

在这里插入图片描述

Итерация заключается в повторении формулы, как показано на рисунке:

:= := := означает обновление параметров,

$a$ представляет скорость обучения (learning rate), используется для управления размером шага (step), то есть длина одного шага вниз d J ( w ) dw \frac{dJ(w)}{dw} dwdJ(w)​ есть вывод функции J ( w ) J(w) J(w ) на www (derivative), в коде мы будем использовать d w dw dw для представления этого результата
在这里插入图片描述

Более наглядное понимание производной - это наклон (slope), как показано на рисунке, производная этой точки — это высота, деленная на ширину маленького треугольника, точка которого касается J (w) J(w) J(w). Допустим, за точку инициализации взята точка, знак наклона в этой точке положительный, то есть d J ( w ) dw > 0 \frac{dJ(w)}{dw}>0 dwdJ(w)​ >0, так что следующий шаг будет влево.
在这里插入图片描述

Итеративный процесс всего метода градиентного спуска состоит в том, чтобы продолжать двигаться влево, пока он не приблизится к точке минимума.
在这里插入图片描述

Допустим, за точку инициализации возьмем точку, знак наклона в этой точке отрицательный, то есть d J ( w ) dw 在这里插入图片描述

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

Подробное описание метода градиентного спуска (два параметра)

Функция стоимости (cost function) логистической регрессии J(w,b)J(w,b)J(w,b) содержит два параметра.
在这里插入图片描述

$\partial $ представляет собой символ частной производной, который можно прочитать какround,
∂J (w,b) ∂w\frac{\partialJ(w,b)}{\partialw} ∂w∂J(w,b)​является функцией J(w,b)J(w,b ) J(w,b) берет частную производную от www. В коде мы будем использовать dw dw dw для представления этого результата,
∂ J ( w , b ) ∂ b \ frac {\ partial J (w, b)} {\ partial b} ∂b∂J (w, b)​ — функция J ( w , b ) J (w, b ) J(w,b) берет частную производную bbb. В коде мы будем использовать db db db для представления этого результата,
Строчные буквы d d d используются в производных (derivative), то есть функция имеет только один параметр,
Обозначение частной производной $\partial $ используется для нахождения частных производных (partial derivative), то есть функция имеет более двух параметров.

2.5 Производные

В этом видео я главным образом хочу помочь вам получить интуитивное представление об исчислении и производных. Может быть, вы думаете, что не касались математики со времен колледжа. Это зависит от того, когда вы закончите, может быть, на какое-то время, не волнуйтесь, если вас это беспокоит. Чтобы эффективно применять нейронные сети и глубокое обучение, вам не нужно очень глубокое понимание исчисления. Так что, если вы смотрите это видео или будущие видео и думаете: «Ого, эти знания, эти расчеты для меня очень сложны», мой вам совет: продолжайте изучать видео, лучше делать домашнее задание после занятий, и вы Выполните свои задания по программированию, и тогда вы будете готовы использовать глубокое обучение. После четвертой недели обучения вы увидите множество определенных функций, с помощью исчисления они могут помочь вам объединить все знания, некоторые из них называются прямыми функциями и обратными функциями, поэтому вам не нужно узнавать обо всех тех функциях в исчислении, которые ты используешь. Так что вам не нужно о них беспокоиться, за исключением того, что в наших набегах на глубокое обучение на этой неделе мы собираемся глубже погрузиться во все тонкости исчисления. Все, что вам нужно, — это интуитивное понимание исчисления для построения и успешного применения этих алгоритмов. Наконец, если вы разбираетесь в математических вычислениях и хорошо знакомы с математическими вычислениями, вы можете пропустить эту часть видео. Остальная часть класса давайте начнем с глубокого погружения в деривативы.
在这里插入图片描述

Функция f ( a ) = 3 a f(a)=3a f(a)=3a является прямой линией. Давайте кратко разберем производную ниже. Давайте посмотрим на несколько точек в функции, предположим, что a = 2 a=2 a=2, тогда f ( a ) f(a) f(a) равно 3, умноженному на aaa, равному 6, то есть, если a = 2 a =2 a=2, то функция f ( a ) = 6 f(a)=6 f(a)=6. Предположим, вы немного изменили значение a a, просто немного увеличили его до 2,001, тогда a a a немного сдвинется вправо. Разница в 0,001 слишком мала, чтобы показать ее на картинке, мы сдвинем ее немного вправо, теперь f ( a ) f (a) f (a) равно 3, умноженному на aaa, что равно 6,003, нарисованному на картинке, шкала Не совсем. Посмотрите на этот маленький треугольник, выделенный зеленым цветом, если вы переместитесь на 0,001 вправо, то f ( a ) f (a) f (a) увеличится на 0,003, а значение f ( a ) f (a) f (a) увеличивается в 3 раза при сдвиге ааа вправо, поэтому говорят, что функция f ( а ) f(a) f(a) при а = 2 а=2 а=2, , есть наклон этой производной, или, когда a = 2 a=2 Когда a=2, наклон равен 3. Понятие производной означает наклон, а производная звучит как страшное, страшное слово, но наклон описывает понятие производной по-дружески. Поэтому, когда дело доходит до производной, мы можем просто думать о ней как о наклоне функции. Более формально наклон определяется как высота, деленная на ширину в этом маленьком зеленом треугольнике выше. То есть наклон равен 0,003, деленному на 0,001, что равно 3. Или производная равна 3, что означает, что при сдвиге a a a вправо на 0,001 значение f ( a ) f(a) f(a) увеличивается в 3 раза по горизонтали.

Теперь давайте разберемся с этой функцией с другой точки зрения.
Предположим, что a = 5 a=5 a=5 , тогда f ( a ) = 3 a = 15 f(a)=3a=15 f(a)=3a=15.
Сдвиньте a a a вправо на небольшую величину до 5,001, f ( a ) = 15,003 f (a) = 15,003 f (a) = 15,003.
То есть, когда a = 5 a=5 a=5, наклон равен 3, что означает, что при незначительном изменении значения переменной aaa df ( a ) da = 3 \frac{df(a)}{da} =3 ддф (а)​=3 . Эквивалентное производное выражение может быть записано как ddaf ( a ) \frac{d}{da}f(a) sad​f(a) , независимо от того, поместите ли вы f ( a ) f(a) f(a) неважно, сверху или справа.
В этом видео я объясняю случай, когда при обсуждении производной мы смещаем aaa на 0,001, если вы хотите узнать математическое определение производной, то производная — это значение aaa, на которое вы сдвигаете вправо на небольшую величину (не 0,001, но очень и очень маленькое значение). Обычно производная определяется так, как если бы вы сдвинули вправо a a a (измеримое значение) на бесконечно малую величину, f ( a ) f (a) f (a) увеличилась в 3 раза (на очень маленькое значение). То есть высота правой стороны треугольника.
在这里插入图片描述

Это формальное определение производной. Но ради интуиции мы рассмотрим сдвиг вправо значения a = 0,001 a = 0,001 a = 0,001, даже несмотря на то, что 0,001 не является бесконечно малыми измеримыми данными. Свойство производных состоит в том, что наклон функции всегда равен 3 в любом месте, будь то a = 2 a=2 a=2 или a = 5 a=5 a=5, наклон функции всегда равен 3, то есть независимо от того, как изменится значение ааа, при увеличении на 0,001 значение f(a) f(a) f(a) увеличивается в 3 раза. Наклон этой функции везде одинаков. Один из способов доказать это состоит в том, что где бы вы ни рисовали маленький треугольник, его высота, деленная на ширину, всегда равна 3.

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

2.6 Дополнительные примеры производных

В этом видео я приведу более сложный пример, где наклон функции разный в разных точках, сначала разберем пример:
在这里插入图片描述

[Не удалось передать изображение по внешней ссылке, исходный сайт может иметь механизм защиты от пиявки, рекомендуется сохранить изображение и загрузить его напрямую (img-JaoJoWlo-1616463257102) (…/images/c34ba67cca6cb94c79a2e63cc5749c1f.png)]

Я рисую здесь функцию, f ( a ) = a 2 f (a) = {{\ text {a}} ^ {\ text {2}}} f (a) = a2, если a = 2 a = \ Если text{2} a=2, тогда f ( a ) = 4 f(a)=4 f(a)=4. Сдвинем немного вправо, теперь a = 2 .001 a=\text{2}.\text{001} a=2,001 , тогда f ( a ) ≈ 4,004 f(a)\приблизительно 4,004 f(a) ≈4,004 (если вы пользуетесь калькулятором, точное значение должно быть 4,004. 0,001 Я просто опустил последнюю часть для краткости), если вы нарисуете здесь маленький треугольник, вы обнаружите, что если вы поместите Move aaa вправо на 0,001, тогда f ( a ) f(a) f(a) увеличится в четыре раза, или 0,004. В исчислении мы называем наклон гипотенузы этого треугольника как производную f ( a ) f (a) f (a) в точке a = 2 a = \ text {2} a = 2 (то есть, 4) , или в виде исчисления, когда a = 2 a=\text{2} a=2, ddaf ( a ) = 4 \frac{d}{da}f(a)=4 dad​f(a )= 4 Видно, что функция f ( a ) = a 2 f(a)={{a}^{{2}}} f(a)=a2, когда aaa принимает разные значения, ее наклон отличается, это отличается от примера в последнем видео.

Существует интуитивно понятный способ объяснить, почему наклон точки различен в разных положениях.Если вы нарисуете несколько маленьких треугольников в разных положениях на кривой, вы обнаружите, что отношение высоты и ширины треугольника находится на кривой Разные места, они разные. Таким образом, когда а = 2 а = 2 а = 2, наклон равен 4, а когда а = 5 а = 5 а = 5, наклон равен 10. Если вы посмотрите учебник по математическому анализу, в нем будет сказано, что наклон (то есть производная) функции f ( a ) = a 2 f (a) = {{a}^{{2}}} f (a )=a2 равно 2 a 2a 2a. Это означает, что в любой заданной точке aaa, если вы немного увеличите aaa, на 0,001, то вы увидите, что f ( a ) f(a) f(a) увеличится на 2 a 2a 2a , т.е. производная точки ааа, умноженная на расстояние, которое вы переместите вправо.

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

Чтобы обобщить то, что мы узнали на этом уроке, давайте рассмотрим еще несколько примеров:
在这里插入图片描述

Предположим, что f ( a ) = a 3 f (a) = {{a} ^ {\ text {3}}} f (a) = a3. Если вы посмотрите на таблицу формул производной, вы обнаружите, что производная этой функции равно 3 a 2 3{{a}^{2}} 3a2. Итак, что это значит, опять же для примера: мы снова делаем a = 2 a=2 a=2, поэтому a 3 = 8 {{a}^{3}}=8 a3=8 , и если мы ставим Увеличить aaa немного, вы найдете f ( a ) ≈ 8,012 f (a) \ приблизительно 8,012 f (a) ≈ 8,012, вы можете проверить это сами, если мы возьмем 8,012, вы найдете 2,001 3 {{2,001}^ {3 }} 2,0013 , что очень близко к 8,012, на самом деле, когда a = 2 a=2 a=2, значение производной равно 3 × 2 2 3 × {{2}^{2}} 3 × 22, что равно 3 × 4 = 12 3×4=12 3×4=12. Итак, формула производной говорит, что если вы сдвинете a a a вправо на 0,001, f ( a ) f(a) f(a) сдвинется вправо в 12 раз, что составляет 0,012.

Глядя на последний пример, предположим, что f ( a ) = log ⁡ eaf (a) = {{\ log }_ {e}} af (a) = loge​a, некоторые могут написать ln ⁡ a \ ln a lna, наклон функции log ⁡ a \log a loga должен быть равен 1 a \frac{1}{a} a1​, поэтому мы можем интерпретировать его следующим образом: если aaa принимает любое значение, например a = 2 a=2 a= 2, Затем переместите aaa вправо на 0,001, тогда f ( a ) f(a) f(a) увеличится на 1 a × 0,001 \frac{\text{1}}{a}\times \text{0} \text{ .001} a1​×0,001, если вы воспользуетесь калькулятором, то обнаружите, что когда a = 2 a=2 a=2 f ( a ) ≈ 0,69315 f(a)\приблизительно \text{0}\text {.69315} f(a)≈0,69315 , а когда a = 2,001 a=2,001 a=2,001, f ( a ) ≈ 0,69365 f(a)\приблизительно \text{0}\text{.69365} f(a) ≈0,69365. Таким образом, f ( a ) f (a) f (a) увеличивается на 0,0005, если вы посмотрите на формулу производной, когда a = 2 a = 2 a = 2, значение производной ddaf ( a ) = 1 2 \ frac {d }{da}f(a)=\frac{\text{1}}{\text{2}} папа​f(a)=21​. Это означает, что если вы увеличите на 0,001, f ( a ) f (a) f (a) увеличится только на половину от 0,001 или 0,0005. Если вы нарисуете маленький треугольник, вы обнаружите, что если ось x x x увеличится на 0,001, то функция log ⁡ a \ log a loga на оси y y y увеличится на половину от 0,001 или 0,0005. Итак, 1 a \frac{1}{a} a1​ , когда a = 2 a=2 a=2 здесь равно , что является наклоном линии, когда a = 2 a=2 a=2. Таковы некоторые знания о производных.

В этом видео вам просто нужно помнить две вещи:

Первый момент заключается в том, что производная — это наклон, а наклон функции разный в разных точках. В первом примере f ( a ) = 3 a f(a)=\text{3}a f(a)=3a , то есть прямая линия с одинаковым наклоном 3 в любой точке. Но для функции f ( a ) = a 2 f (a) = {{\ text {a}} ^ {\ text {2}}} f (a) = a2 , или f ( a ) = log ⁡ af ( a )=\log af(a)=loga, их наклоны меняются, поэтому их производные или наклоны различны в разных точках кривой.

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

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

2.7 Расчетный график

Можно сказать, что вычисления нейронной сети организованы по принципу прямого или обратного распространения. Сначала мы вычисляем выход новой сети (прямой процесс), после чего следует обратная операция передачи. Последний мы используем для вычисления соответствующего градиента или производной. Вычислительные графы объясняют, почему мы организуем эти вычисления таким образом. В этом видео мы приведем пример того, что такое вычислительный граф. Давайте возьмем пример более простой или менее формализованной нейронной сети, чем логистическая регрессия.
在这里插入图片描述

Мы пытаемся вычислить функцию JJJ, JJJ — это функция, состоящая из трех переменных a , b , ca,b,ca,b,c, эта функция равна 3(a + bc) \text{3(a}+\text{ bc )} 3(a+bc) . На самом деле есть три разных шага для вычисления этой функции, первый состоит в том, чтобы вычислить b b b, умноженное на c c c, которое мы сохраняем в переменной u u u, поэтому u = b c {u}={bc} u=bc;
Затем вычислите v = a + u v=a+u v=a+u; наконец, выведите J = 3 v J=3v J=3v, это функция, которую необходимо вычислить J J J. Мы можем изобразить эти три шага в следующей диаграмме расчета. Сначала я нарисую здесь три переменные a, b, ca, b, ca, b, c. Первый шаг — вычислить u = bcu=bc u=bc, я положил прямоугольник вокруг него, его входы b , cb,cb,c, затем второй шаг v = a + uv=a+uv=a+u, последний шаг J = 3 v J=3v J=3v .
Например: a = 5 , b = 3 , c = 2 a=5,b=3,c=2 a=5,b=3,c=2 , u = bcu=bc u=bc равно 6, v = a + uv=a+uv=a+u , что равно 5+6=11. J J J в 3 раза, так что. Это 3 × ( 5 + 3 × 2 ) 3 × (5 + 3 × 2) 3 × (5 + 3 × 2). Если вы понимаете это, на самом деле получение 33 является ценностью J J J.
Когда есть разные или некоторые специальные выходные переменные, такие как J J J в этом примере и функция стоимости J J J, которую вы хотите оптимизировать в логистической регрессии, для обработки этих вычислений удобно использовать вычислительный граф. Как мы видим из этого небольшого примера, действуя слева направо, вы можете вычислить значение J J J. Для вычисления производных процесс справа налево (красная стрелка, процесс, обратный синей стрелке) является наиболее естественным способом вычисления производных.
Напомним: вычислительные графы организуют вычисления в виде вычислений слева направо с синими стрелками, давайте посмотрим в следующем видео, как выполняются производные вычисления перевернутых красных стрелок (также известных как справа налево), давайте продолжим обучение в следующем видео.

2.8 Производные с вычислительным графиком

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

Формула, используемая ниже:

d J du = d J dvdvdu \frac{dJ}{du}=\frac{dJ}{dv}\frac{dv}{du} dudJ​=dvdJ​dudv​ , d J db = d J dududb \frac{ dJ}{db}=\frac{dJ}{du}\frac{du}{db} dbdJ​=dudJ​dbdu​ , d J da = d J dududa \frac{dJ}{da}=\frac{dJ }{du}\frac{du}{da} папаJ​= dudJ​dadu​

Вот блок-схема:
在这里插入图片描述

Предположим, вы хотите вычислить d J d v \frac{{dJ}}{{dv}} dvdJ​, как вы это вычислите? Ну, например, мы хотим взять это значение v v v и изменить его, как тогда изменится значение J J J?

Итак, по определению J = 3 v J = 3v J = 3v, теперь v = 11 v = 11 v = 11, поэтому, если немного увеличить vvv, скажем, до 11,001, тогда J = 3 v = 33,003 J = 3v = 33,003 J=3v=33,003, поэтому здесь я увеличил vvv на 0,001, и тогда окончательный результат состоит в том, что JJJ возрастает в 3 раза по сравнению с исходным значением, поэтому d J dv = 3 \frac{{dJ}}{{dv}}=3 dvdJ ​=3 , потому что для любого приращения JJJ vvv будет приращение в 3 раза, и это похоже на наш пример в последнем видео, у нас есть f(a) = 3 af(a)=3a f(a)=3a , то мы получаем df ( a ) da = 3 \frac{{df}(a)}{{da}}= 3 dadf(a)​=3, так что здесь мы имеем J = 3 v J=3v J=3v , Итак, d J dv = 3 \frac{{dJ}}{{dv}} =3 dvdJ​=3, здесь JJJ играет роль fff, пример в предыдущем видео.

С точки зрения алгоритма обратного распространения мы видим, что если вы хотите вычислить производную конечной выходной переменной, используя производную переменной, которая вас больше всего интересует vvv, то мы сделали один шаг обратного распространения, который на этой блок-схеме является обратным. шаг.
在这里插入图片描述

Давайте посмотрим на другой пример, что такое d J d a \frac{{dJ}}{da} sadJ​? Другими словами, если мы увеличим значение a a a, как это повлияет на значение J J J?

Хорошо, давайте посмотрим на этот пример. Переменная a = 5 a=5 a=5, мы увеличиваем ее до 5,001, тогда влияние на v равно a + u a+u a+u, до v = 11 v=11 v=11, теперь оно становится 11,001 , Мы видим сверху, что JJJ теперь составляет 33,003, поэтому мы видим, что если вы увеличите aaa на 0,001, JJJ увеличится на 0,003. Затем добавьте a a a, я имею в виду, что если вы замените это 5 каким-то новым значением, то изменение a a a будет распространяться в крайний правый угол блок-схемы, поэтому J J J в конечном итоге будет равно 33,003. Таким образом, приращение J в 3 раза больше приращения a a a, что означает, что эта производная равна 3.

在这里插入图片描述

Один из способов объяснить этот расчет: если вы измените aaa, вы также измените vvv, и, изменив vvv, вы также измените JJJ, поэтому чистое изменение значения JJJ, когда вы увеличите это значение (0,001), Когда вы немного увеличьте значение aaa, это величина изменения JJJ (0,003).
在这里插入图片描述

Во-первых, когда увеличивается a, увеличивается и v v v. Насколько увеличивается v v v? Это зависит от dvda \frac{{dv}}{da} dav​, тогда изменение vvv также вызывает увеличение JJJ, так что это на самом деле называется цепным правилом в исчислении, если aaa влияет на vvv, vvv влияет на JJJ , тогда когда вы увеличиваете aaa, изменение JJJ происходит при изменении aaa, изменение vvv умножается на изменение JJJ при изменении vvv, что называется цепным правилом в исчислении.
在这里插入图片描述

Из этого расчета видно, что если вы увеличите a a a на 0,001, v v v также изменится на ту же величину, поэтому d v d a = 1 \frac{{dv}}{da}= 1 dav​=1. На самом деле, если вы подключите его, мы вычислили d J dv = 3 до того, как \frac{{dJ}}{{dv}} =3 dvdJ​=3, dvda = 1 \frac{{dv}}{da} = 1 daDV=1, поэтому произведение 3×1 на самом деле дает правильный ответ, d J da = 3 \frac{{dJ}}{da} = 3 daJ=3.

На этом небольшом рисунке показано, как рассчитать d J dv \frac{{dJ}}{{dv}} dvdJ​является производной JJJ по переменной vvv, это может помочь вам рассчитать d J da \frac{{dJ}} {da} папаJ​, так что это еще один шаг обратного распространения.
在这里插入图片描述

Теперь я хочу ввести новое соглашение об обозначениях: когда вы программируете обратное распространение, обычно есть конечное выходное значение, о котором вы заботитесь, конечная выходная переменная, о которой вы действительно хотите заботиться или оптимизировать. В этом случае конечной выходной переменной является J, который является последним символом в блок-схеме, поэтому существует много вычислений, пытающихся вычислить производную выходной переменной, поэтому производная выходной переменной по переменной, мы называем ее dvar dvar dvar, поэтому во многих расчетах вам необходимо вычислить производную конечного выхода, в данном случае JJJ, и различные промежуточные переменные, такие как a, b, c, u, va, b, c, u, va, b, c , u, v, когда вы реализуете это в программном обеспечении, как называется переменная? Одна вещь, которую вы можете сделать, это, вpython, вы можете написать очень длинное имя переменной, например d Final O utputvar _ dvar {dFinalOutputvar}\_{dvar} dFinalOutputvar_dvar, но это имя переменной немного длинное, мы используем d J _ dvar dJ\_dvar dJ_dvar, но Поскольку вы брали производную от d J dJ dJ, возьмите производную от этой конечной выходной переменной. Я собираюсь ввести здесь новый символ.В программе, когда вы программируете, в коде мы используем имя переменной d v a r dvar dvar для представления этой величины.
在这里插入图片描述

Итак, в программе это dvar dvar dvar представляет собой производную, производную конечной переменной JJJ, которая вас интересует, а иногда и LLL, производную различных промежуточных величин в коде, так что эта штука в коде, вы используете dv dv dv для представления этого значения, поэтому dv = 3 dv=3 dv=3, ваше кодовое представление da = 3 da=3 da=3.
在这里插入图片描述

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

Мы очищаем новую блок-схему, давайте рассмотрим, до сих пор мы выполняли обратное распространение и вычисляли dv = 3 dv=3 dv=3, опять же, dv dv dv — это имя переменной в коде, ее реальное определение — d J dv \frac{{dJ}}{{dv}} dvdJ​. Я обнаружил, что da = 3 da=3 da=3, опять же, da da da — это имя переменной в коде, которое на самом деле представляет собой значение d J d a \frac{{dJ}}{da} sadJ​.
在这里插入图片描述

Я, наверное, вычислил вручную, как вычислить обратное распространение двух прямых.

Что ж, продолжим вычислять производную, посмотрим на это значение u u u, тогда что такое d J d u \frac{dJ}{du} dudJ​? Аналогичным расчетом, как и раньше, теперь мы начинаем с u = 6 u=6 u=6, если увеличить uuu до 6,001, то vvv раньше было 11, теперь становится 11,001, а JJJ изменяется с 33 до 33,003, поэтому JJJ приращение в 3 раза, поэтому d J du = 3 \frac{{dJ}}{du}= 3 dudJ​=3. Анализ uuu очень похож на анализ a. Фактически, он рассчитывается как d J dv ⋅ dvdu \ frac{{dJ}}{dv}\cdot \frac{{dv}}{du} dvdJ​⋅ dudv​, Таким образом, мы можем вычислить d J dv = 3 \frac{{dJ}}{dv} =3 dvdJ​=3, dvdu = 1 \frac{{dv}}{du} = 1 dudv​=1 , и, наконец, результат 3 × 1 = 3 3 × 1 = 3 3 × 1 = 3.
在这里插入图片描述

Итак, у нас есть еще один шаг обратного распространения, и мы, наконец, вычисляем d u = 3 du=3 du=3, где d u du du, конечно же, равно d J d u \frac{{dJ}}{du} dudJ​.

Теперь давайте подробнее рассмотрим последний пример, а как насчет d J d b \frac{{dJ}}{db} dbdJ​? Представьте, если вы изменили значение b b b и хотите немного его изменить, чтобы значение J J J достигло максимального или минимального значения, что такое производная? Наклон функции J J J после небольшого изменения значения b b b. На самом деле, используя цепное правило исчисления, это можно записать как произведение двух, которое равно d J du ⋅ dudb \frac{{dJ}}{du}\cdot \frac{{du}}{db} dudJ​⋅dbdu ​, причина в том, что если вы немного измените bbb, так что изменение bbb будет, скажем, 3,001, то, как это повлияет на J, сначала повлияет на uuu, насколько сильно это повлияет на uuu? Ну, определение uuu таково: b ⋅ cb\cdot cb⋅c, так что когда b = 3 b=3 b=3 было 6, теперь становится 6,002, верно, потому что в нашем случае c = 2 c =2 c= 2, так что это говорит нам о том, что dudb = 2 \frac{{du}}{db}= 2 dbdu​=2 Когда вы увеличиваете bbb на 0,001, uuu удваивается. Таким образом, dudb = 2 \frac{{du}}{db} =2 dbdu​=2, теперь я думаю, что увеличение uuu уже вдвое больше, чем bbb, тогда d J du \frac{{dJ}}{du} dudJ Сколько это стоит? Мы выяснили, что это равно 3, поэтому, перемножив две части вместе, мы находим d J d b = 6 \frac{{dJ}}{db}= 6 dbdJ​=6.

Итак, это вывод второй части, где мы хотим знать, какое влияние окажет увеличение u u u на 0,002 на J J J . На самом деле d J d u = 3 \frac{{dJ}}{du}=3 dudJ​=3, что говорит нам о том, что после увеличения u на 0,002 J J J увеличилось в 3 раза, тогда J J J должно увеличиться на 0,006, правильно. Это можно вывести из d J d u = 3 \frac{{dJ}}{du}= 3 dudJ​=3.

Если вы внимательно посмотрите на математику, вы увидите, что если bbb становится 3,001, то uuu становится 6,002, vvv становится 11,002, тогда J = 3 v = 33,006 J = 3v = 33,006 J = 3v = 33,006, да Bar? Вот как получить d J d b = 6 \frac{{dJ}}{db}= 6 dbdJ​=6.
在这里插入图片描述

Чтобы заполнить, если мы пойдем в обратном направлении, db = 6 db=6 db=6, и db db db на самом делеPythonИмя переменной в коде, что означает d J d b \frac{{dJ}}{db} dbdJ​.
在这里插入图片描述

Я не буду вдаваться в подробности последнего примера, но на самом деле, если вы вычислите d J dc = d J du ⋅ dudc = 3 × 3 \frac{{dJ}}{dc} =\frac{{dJ} }{ du}\cdot \frac{{du}}{dc} = 3 \times 3 dcdJ​=dudJ​⋅dcdu​=3×3, результат равен 9.

Я не буду вдаваться в детали этого примера, на последнем шаге мы можем вывести dc = 9 dc=9 dc=9.

在这里插入图片描述

Итак, смысл этого видео в том, что для этого примера при вычислении всех этих производных наиболее эффективным способом является вычисление справа налево, следуя этой красной стрелке. Особенно, когда мы сначала вычисляем производную по v v v, ее можно использовать позже при вычислении производной по a a a. Тогда производные по u u u говорят этот член и здесь этот член:

在这里插入图片描述

может помочь вычислить производную по b b b, а затем производную по c c c.

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

2.9 Градиентный спуск логистической регрессии в логистической регрессии

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

Предполагая, что выборка имеет только два признака x 1 {{x}_{1}} x1​ и x 2 {{x}_{2}} x2​, для вычисления zzz нам нужен входной параметр w 1 { {w}_{ 1}} w1​, w 2 {{w}_{2}} w2​ и bbb, в дополнение к собственным значениям x 1 {{x}_{1}} x1​ и x 2 { {x} _{2}} x2​. Следовательно, формула расчета z z z такова:
z = w 1 x 1 + w 2 x 2 + bz={{w}_{1}}{{x}_{1}}+{{w}_{2}}{{x}_{2} }+bz=w1​x1​+w2​x2​+b
Напомним, что формула логистической регрессии определяется следующим образом:
y ^ = a = σ ( z ) \ hat {y} = a = \ sigma (z) y ^​= a = σ (z)
где z = w T x + b z={{w}^{T}}x+b z=wTx+b
σ ( z ) знак равно 1 1 + e − z \sigma \left( z \right)=\frac{1}{1+{{e}^{-z}}} σ(z)=1+e−z1​
Функция потерь:
L ( y ^ ( я ) , y ( я ) ) знак равно - y ( я ) журнал ⁡ y ^ ( я ) - ( 1 - y ( я ) ) журнал ⁡ ( 1 - y ^ ( я ) ) L ( {{ {\ шляпа {у}}} ^ {(я)}}, {{у} ^ {(я)}}) = - {{у} ^ {(я)}} \ log {{\ шляпа {у} }^{(i)}}-(1-{{y}^{(i)}})\log (1-{{\hat{y}}^{(i)}}) L(y^​ (i),y(i))=−y(i)logy^​(i)−(1−y(i))log(1−y^​(i))
Функция стоимости:
J ( w , b ) знак равно 1 м ∑ im L ( y ^ ( i ) , y ( i ) ) J \ left ( w, b \ right) = \ frac {1} {m} \ sum \ nolimits_ {i} ^{m}{L( {{{\шляпа{y}}}^{(i)}}, {{y}^{(i)}})} J(w,b)=m1​∑im​ L (у ^ (я), у (я))
Предполагая, что сейчас рассматривается только одна выборка, функция стоимости одной выборки определяется следующим образом:
L ( а , y ) знак равно - ( y журнал ⁡ ( а ) + ( 1 - y ) журнал ⁡ ( 1 - а ) ) L (a, y) = - (y \ log (a) + (1-y) \ log (1-a)) L (a, y) = - (ylog (a) + (1-y) log (1-a))
где a a a — результат логистической регрессии, а y y y — значение метки выборки. Теперь давайте нарисуем вычислительный граф, представляющий это вычисление.
Здесь мы сначала рассмотрим метод градиентного спуска, Поправки w w w и b b b могут быть выражены следующим образом:

ш : знак равно ш - а ∂ J ( ш , б ) ∂ ш: = ва \ гидроразрыва {\ парциальное J (ш, б)} {\ парциальное ш} ш: = ш-а∂w∂J (ш, б) ​, б : знак равно б - а ∂ J ( ш , б ) ∂ bb: = ba \ frac {\ partial J (w, b)} {\ partial b} b: = b-a∂b∂J (w, б)​

[Не удалось передать изображение по внешней ссылке, исходный сайт может иметь механизм защиты от пиявки, рекомендуется сохранить изображение и загрузить его напрямую (img-03mMuFgx-1616463257111) (…/images/03f5f96177ab15d5ead8298ba50300ac.jpg)]

Рисунок: Нарисуйте прямоугольник снаружи этой формулы. Затем рассчитайте:
y ^ = a = σ ( z ) \ hat {y} = a = \ sigma (z) y ^​= a = σ (z)
То есть следующий шаг в графе вычислений. Наконец, вычислите функцию потерь L ( a , y ) L (a, y) L (a, y).
С графиком расчета мне больше не нужно выписывать формулу. Следовательно, чтобы минимизировать функцию стоимости L (a, y) L(a,y) L(a,y) в логистической регрессии, все, что нам нужно сделать, это изменить значения параметров w w w и b b b. Ранее мы объяснили, как вычислить шаг вперед функции стоимости на одном обучающем примере. Теперь давайте обсудим вычисление производной в обратном порядке.
Поскольку мы хотим вычислить производную функции стоимости L (a, y) L(a,y) L(a,y), сначала нам нужно обратить вычисление функции стоимости L(a, y) L(a ,y ) Производная L(a,y) относительно aaa, при написании кода вам нужно использовать только da da da для представления d L ( a , y ) da \frac{dL(a,y)}{ da} daL(a,y)​ .
По подсчетам получаем:
d L ( a , y ) da знак равно - y / a + ( 1 - y ) / ( 1 - a ) \ frac {dL (a, y)} {da} = - y / a + (1-y) / ( 1-а) dadL(a,y)​=−y/a+(1−y)/(1−a)
Если вы новичок в исчислении, не беспокойтесь слишком сильно, мы перечислим все формулы вывода, рассмотренные в этом курсе. Затем, если вы хорошо знакомы с исчислением, мы рекомендуем вам активно вывести формулу вывода функции стоимости, представленную ранее, и использовать исчисление, чтобы напрямую найти L ( a , y ) L (a, y) L (a, y) с по переменной aaa производной от . Если вы мало что знаете об исчислении, не беспокойтесь слишком сильно. Теперь мы вычислили d a da da, производную от конечного результата.
Теперь можно пойти другим путем и написатьPythonКогда вы кодируете, вам нужно использовать только dz dz dz для представления производной функции стоимости LLL относительно zzz d L dz \frac{dL}{dz} dzdL​, также может быть записано как d L ( a , y ) dz \frac{dL(a ,y)}{dz} dzdL(a,y)​, оба из которых верны.
d L d z знак равно a − y \frac{dL}{dz}=a-y dzdL​=a−y .
потому что d L ( a , y ) dz = d L dz = ( d L da ) ⋅ ( Dadz ) \ frac {dL (a, y)} {dz} = \ frac {dL} {dz} = (\ frac { dL}{da})\cdot (\frac{da}{dz}) dzdL(a,y)​=dzdL​=(dadL​)⋅(dzda​),
и d a d z = a ⋅ ( 1 − a ) \frac{da}{dz}=a\cdot (1-a) dzda​=a⋅(1−a),
и d L da = ( - ya + ( 1 - y ) ( 1 - a ) ) \ frac {dL} {da} = (- \ frac {y} {a} + \ frac {(1-y)} { (1-a)}) sadL​=(−ay​+(1−a)(1−y)​), поэтому умножение этих двух членов дает:

dz знак равно d L ( а , y ) dz знак равно d L dz знак равно ( d L da ) ⋅ ( дадз ) знак равно ( - ya + ( 1 - y ) ( 1 - а ) ) ⋅ а ( 1 - а ) знак равно а - y {dz} = \frac{{dL}(a,y)}{{dz}} = \frac{{dL}}{{dz}} = \left( \frac{{dL}}{{da} } \right) \cdot \left(\frac{{da}}{{dz}} \right) = ( - \frac{y}{a} + \frac{(1 - y)}{(1 - a )})\cdot a(1 - a) = a - y dz=dzdL(a,y)​=dzdL​=(dadL​)⋅(dzda​)=(−ay​+(1−a)(1 −y)​)⋅a(1−a)=a−y

Чтобы упростить процесс вывода в видео, предполагается, что n x {{n}_{x}} nx​ Этот процесс вывода представляет собой цепное правило, о котором я упоминал ранее. Если вы знакомы с исчислением, не стесняйтесь выводить весь процесс вывода.Если вы не знакомы с исчислением, вам нужно только знать, что dz = (a − y) dz=(ay) рассчитано.

Теперь выполните последний шаг обратного вывода, который заключается в расчете влияния изменений w w w и b b b на функцию стоимости L L L. В частности, вы можете использовать:
dw 1 знак равно 1 м ∑ imx 1 ( я ) ( а ( я ) - y ( я ) ) d {{w}_ {1}} = \ frac {1} {m} \ sum \ limits_ {i} ^ { m}{x_{1}^{(i)}}({{a}^{(i)}}-{{y}^{(i)}}) dw1​=m1​i∑m​x1( я)​(а(я)−у(я))
dw 2 знак равно 1 м ∑ imx 2 ( я ) ( а ( я ) - y ( я ) ) d {{w}_ {2}} = \ frac {1} {m} \ sum \ limits_ {i} ^ { m}{x_{2}^{(i)}}({{a}^{(i)}}-{{y}^{(i)}}) dw2​=m1​i∑m​x2( я)​(а(я)−у(я))
db = 1 м ∑ im ( a ( i ) - y ( i ) ) db = \ frac {1} {m} \ sum \ limits_ {i} ^ {m} {({{a} ^ {(i)} }-{{y}^{(i)}})} db=m1​i∑m​(a(i)−y(i))
В видео
dw 1 d{{w}_{1}} dw1​ означает ∂ L ∂ w 1 = x 1 ⋅ dz \frac{\partial L}{\partial {{w}_{1}}}={{x} _{1}}\cdot dz ∂w1​∂L​=x1​⋅dz,
dw 2 d{{w}_{\text{2}}} dw2​ означает ∂ L ∂ w 2 = x 2 ⋅ dz \frac{\partial L}{\partial {{w}_{2}}}= {{x}_{2}}\cdot dz ∂w2​∂L​=x2​⋅dz,
db = dz db=dz db=dz.
Итак, для алгоритма градиентного спуска для одного образца все, что вам нужно сделать, это следующее:
Рассчитайте d z dz dz по формуле d z = ( a − y ) dz=(a-y) dz=(a−y),
Рассчитайте dw 1 d{{w}_{1}}, используя dw 1 = x 1 ⋅ dzd{{w}_{1}}={{x}_{1}}\cdot dz dw1​=x1​⋅dz dw1​, dw 2 = x 2 ⋅ dzd{{w}_{2}}={{x}_{2}}\cdot dz dw2​=x2​⋅dz Рассчитать dw 2 d{{w}_{2 }} дв2​,
d b = d z db=dz db=dz для расчета d b db db,
Потом:
обновить w 1 = w 1 − a d w 1 {{w}_{1}}={{w}_{1}}-a d{{w}_{1}} w1​=w1​-adw1​,
обновить w 2 = w 2 − a d w 2 {{w}_{2}}={{w}_{2}}-a d{{w}_{2}} w2​=w2​-adw2​,
Обновление b = b − α d b b=b-\alpha db b=b−αdb.
Это шаг, на котором параметры обновляются один раз в алгоритме градиентного спуска по отношению к одному экземпляру выборки.
在这里插入图片描述

Теперь вы знаете, как рассчитать производные и реализовать алгоритм градиентного спуска для логистической регрессии на одном обучающем примере. Однако обучение модели логистической регрессии — это не просто одна обучающая выборка, а весь обучающий набор из m обучающих выборок. Поэтому в следующем видео мы применим эти идеи ко всему набору обучающих образцов, а не только к одному образцу.

2.10 Градиентный спуск на m Примеры

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

[Не удалось передать изображение по внешней ссылке, исходный сайт может иметь механизм защиты от пиявки, рекомендуется сохранить изображение и загрузить его напрямую (img-tLlg0iqq-1616463257112) (…/images/bf930b1f68d8e0726dda5393afc83672.png)]

Во-первых, давайте вспомним определение функции потерь J (w, b) J(w,b) J(w,b).

J ( ш , б ) знак равно 1 м ∑ я знак равно 1 м L ( а ( я ) , у ( я ) ) J ( ш , б ) = \ гидроразрыва {1} {м} \ сумма \ limits_ {я = 1} ^{m}{L({{a}^{(i)}}, {{y}^{(i)}})} J(w,b)=m1​i=1∑m​L(a (я), у (я))

Когда ваш алгоритм выводит a (i) {{a}^{(i)}} a(i) для выборки yyy, a (i) {{a}^{(i)}} a(i) обучает предсказанный значение выборки, то есть: σ ( z ( i ) ) = σ ( w T x ( i ) + b ) \ sigma ( {{z} ^ {(i)}}) = \ sigma ( {{w} ^ {T}}{{x}^{\left(i\right)}}+b) σ(z(i))=σ(wTx(i)+b).
Итак, на предыдущих слайдах мы показали для любого отдельного обучающего примера, как вычислить дифференциал, когда у вас есть только один обучающий пример. Поэтому dw 1 d{{w}_{1}} dw1​, dw 2 d{{w}_{\text{2}}} dw2​ и db db db добавьте верхний индекс iii, чтобы указать соответствующее значение, которое вы получили. Если вы столкнулись с ситуацией, которую мы продемонстрировали на предыдущем слайде, но использовали только одну обучающую выборку ( x ( i ) , y ( i ) ) ({{x}^{(i)}},{ {y}^{ (i)}}) (x(i),y(i)).
Теперь вы знаете глобальную функцию стоимости с суммированием, которая на самом деле является средним значением отдельных потерь для сроков от 1 до мм. Таким образом, это показывает, что дифференциация функции глобальных затрат на w 1 {{w}_{1}} w1​, дифференциация w 1 {{w}_{1}} w1​ также одинакова для каждой потери в w 1 {{ w}_{1}} w1​Среднее значение производных.
在这里插入图片描述

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

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

Мы инициализируем J = 0, dw 1 = 0, dw 2 = 0, db = 0 J=0,d{{w}_{1}}=0,d{{w}_{2}}=0,db =0 J=0,dw1​=0,dw2​=0,db=0

Поток кода:

J=0;dw1=0;dw2=0;db=0;
for i = 1 to m
    z(i) = wx(i)+b;
    a(i) = sigmoid(z(i));
    J += -[y(i)log(a(i))+(1-y(i))log(1-a(i));
    dz(i) = a(i)-y(i);
    dw1 += x1(i)dz(i);
    dw2 += x2(i)dz(i);
    db += dz(i);
J/= m;
dw1/= m;
dw2/= m;
db/= m;
w=w-alpha*dw
b=b-alpha*db

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

Но у этого вычисления есть два недостатка, то есть, чтобы применить этот метод к логистической регрессии, вам нужно написать дваforцикл. ПервыйforЦикл — это небольшой цикл, который проходит m обучающих выборок, второйforЦикл — это цикл, который перебирает все функции.forцикл. В этом примере у нас есть только 2 функции, поэтому n n n равно 2, а n x {{n}_{x}} nx равно 2. Но если у вас больше возможностей и вы начинаете писать так dw 1 d{{w}_{1}} dw1​, dw 2 d{{w}_{2}} dw2​, у вас аналогичный расчет от dw 3 d{{w}_{3}} dw3​Перейти к dwnd{{w}_{n}} dwn​. Так что, похоже, вам нуженforПеребрать все n n n объектов.

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

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

2.11 Векторизация

Справочное видео: 2.11 Векторизация

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

В логистической регрессии вам нужно вычислить z = w T x + b z={{w}^{T}}x+b z=wTx+b, где w w w и x x x — векторы-столбцы. Если у вас много функций, то будет очень большой вектор, поэтому w ∈ R nxw\in {{\mathbb{R}}^{{{n}_{x}}}} w∈Rnx​ , x ∈ R nxx\in{{\mathbb{R}}^{{{n}_{x}}}} x∈Rnx​, поэтому, если вы хотите использовать невекторизованный метод для вычисления w T x {{w }^ {T}}x wTx, вам нужно использовать следующий способ (python)

z=0
for i in range(n_x):
    z += w[i]*x[i]
z += b

Это невекторизованная реализация, вы обнаружите, что она очень медленная, для сравнения, векторизованная реализация будет очень напрямую вычислять w T x {{w}^{T}}x wTx со следующим кодом:

z=np.dot(w,x)+b

Вот как векторизовать w T x {{w}^{T}}x wTx, вы найдете это очень быстро

[Не удалось передать изображение по внешней ссылке, исходный сайт может иметь механизм защиты от пиявки, рекомендуется сохранить изображение и загрузить его напрямую (img-TzeEVj7H-1616463257113) (…/images/e9c7f9f3694453c07fe6b9fe7cf0c4c8.png)]

Проиллюстрируем на небольшом примере, в моем я напишу код (ниже профессор в своемJupyter notebookнаписано наPythonкод,)

import numpy as np #导入numpy库
a = np.array([1,2,3,4]) #创建一个数据a
print(a)
# [1 2 3 4]

import time #导入时间库
a = np.random.rand(1000000)
b = np.random.rand(1000000) #通过round随机得到两个一百万维度的数组
tic = time.time() #现在测量一下当前时间

#向量化的版本
c = np.dot(a,b)
toc = time.time()
print("Vectorized version:" + str(1000*(toc-tic)) +"ms") #打印一下向量化的版本的时间

#继续增加非向量化的版本
c = 0
tic = time.time()
for i in range(1000000):
    c += a[i]*b[i]
toc = time.time()
print(c)
print("For loop:" + str(1000*(toc-tic)) + "ms")#打印for循环的版本的时间

Возвращаемое значение показано на рисунке.

В обоих методах, векторизованный и не векторизованный, вычислялось одно и то же значение, как вы можете видеть, векторизованная версия заняла 1,5 мс, не векторизованная версияforЦикл занял около 500 мс, невекторизованная версия заняла в 300 раз больше времени. Таким образом, в этом примере простая векторизация вашего кода будет работать в 300 раз быстрее. Это означает, что если векторизованному методу требуется минута для работы с данными,forЦикл будет выполняться 5 часов.

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

Вы, наверное, слышали много таких вещей, как «Крупномасштабное глубокое обучение используетGPUили реализация блока обработки изображений", но все случаи, которые я сделал, относятся кjupyter notebookВышеупомянутое реализовано, здесь толькоCPU,CPUиGPUСуществуют распараллеленные инструкции, их иногда называютSIMDИнструкция, это представляет собой одну инструкцию многомерных данных, основной смысл этого в том, что если вы используетеbuilt-inфункция, какnp.functionИли вместо того, чтобы требовать от вас реализации функции цикла, он позволяетpythonиспользовать все преимущества параллельных вычислений, что верно вGPUиCPUРассчитано выше,GPUлучше вSIMDрасчет, ноCPUНа самом деле не так уж и плохо, наверное, нетGPUТак хорошо в этом. В следующем видео вы увидите, как векторизация может ускорить ваш код. Практическое правило: по возможности избегайте использования явныхforцикл.

Скриншоты следующего кода и результаты выполнения:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.12 Дополнительные примеры векторизации

Из предыдущего видео вы знаете, как пройтиnumpyвстроенные функции и избегайте явных циклов (loop) способ векторизации, тем самым эффективно повышая скорость кода.

Опыт напоминает мне, что когда мы пишем нейросетевые программы или пишем логику (logistic) регрессии или других моделей нейронных сетей следует избегать написания циклов (loop) утверждение. Пока иногда пишу циклы(loop) неизбежен, но мы можем использовать, например.numpyвстроенные функции или другие методы расчета. Когда вы используете его таким образом, программа всегда работает быстрее, чем цикл (loop).

Давайте посмотрим на другой пример. Если вы хотите вычислить вектор u = A vu=Av u=Av, то матричное умножение определяется как, определение матричного умножения: ui = ∑ j A ij vi u_{i} =\sum_{j}^{ }{A_ {\text{ij}}v_{i}} ui​=∑j​Aij​vi​, это зависит от того, как вы определяете значение ui u_{i} ui​. Также используя невекторизованную реализацию, u = np.zeros( n , 1 ) u=np.zeros(n,1) u=np.zeros(n,1) и перебираем два слоя for ( i ): for ( j ) : for (i): for (j): for (i): for (j): получить u [i] = u [i] + A [i] [j] ∗ v [j] u [i]=u[i]+A[i][j]*v[j] u[i]=u[i]+A[i][j]∗v[j] . Теперь у нас есть два слоя циклов для i i i и j j j , что не является векторизацией. Метод векторизации может использовать u = np.dot ( A , v ) u=np.dot(A,v) u=np.dot(A,v), реализация векторизации справа устраняет двухслойный цикл. код работает быстрее.
在这里插入图片描述

Давайте продолжим разбираться в векторизации на другом примере. Если у вас уже есть вектор vvv и вы хотите выполнить экспоненциальную операцию над каждым элементом вектора vvv, вектор uuu равен v 1 v_1 v1 от eee, v 2 v_2 v2 от eee, вплоть до vn v_n vn мощности eee. Вот невекторизованная реализация: сначала вы инициализируете вектор u = np.zeros(n, 1) u=np.zeros(n,1) u=np.zeros(n,1) и вычисляете каждый элемент. Но оказывается, чтоpythonизnumpyВстроенные функции, которые помогут вам вычислить такую ​​единственную функцию. Так что я буду импортироватьimport numpy as np, выполните команду u = n p .e x p ( v ) u=np.exp(v) u=np.exp(v). Обратите внимание, что в предыдущем коде с циклом здесь используется только одна строка кода, на входе используется вектор v v v, а на выходе u u u. Вы уже знаете, зачем нужен цикл, и с кодом справа это значительно быстрее, чем цикл.

По факту,numpyВ библиотеке много векторных функций. Напримерu=np.logвычисленная логарифмическая функция ( log log log ),np.abs()Вычислить абсолютное значение данных,np.maximum(v, 0)Вычислить максимальное значение каждого элемента в v v v по сравнению с 0, поэлементно,v**2Представляет для получения квадрата каждого значения элемента v v v,1/vПолучите инверсию каждого элемента в v v v и так далее. Поэтому, когда вы хотите написать цикл, отметьтеnumpyЕсть ли аналогичная встроенная функция, которая позволяет избежать использования циклов (loop)Способ.
在这里插入图片描述

Итак, примените то, что вы только что узнали, к градиентному спуску для логистической регрессии и посмотрите, сможем ли мы упростить одно из двух вычислений. Это код вывода для нашей логистической регрессии с двумя уровнями циклов. В этом примере у нас есть n n n собственных значений. Если у вас более двух функций, вам нужно зациклить d w 1 dw_1 dw1, d w 2 dw_2 dw2, d w 3 dw_3 dw3 и так далее. Таким образом, фактические значения j j j равны 1, 2 и n x n_x nx​, что является значением, которое вы хотите обновить. Итак, мы хотим устранить второй цикл в этой строке, чтобы нам не приходилось инициализировать d w 1 dw_1 dw1​ , d w 2 dw_2 dw2​ равными 0. Избавьтесь от них, вместо этого определите dw dw dw как вектор, установите u = np.zeros(n(x), 1) u=np.zeros(n(x),1) u=np.zeros(n(x) ), 1). Определяет одномерный вектор x x x строк, таким образом заменяя циклы. Мы только что использовали векторную операцию d w = d w + x ( i ) d z ( i ) dw=dw+x^{(i)}dz^{(i)} dw=dw+x(i)dz(i) . Наконец, мы получаем d w = d w / m dw=dw/m dw=dw/m . Теперь у нас все еще есть обучающие образцы этого цикла, превратив двухслойный цикл в однослойный цикл.
在这里插入图片描述

在这里插入图片描述

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

2.13 Векторизация логистической регрессии

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

Давайте начнем, сначала мы рассмотрим этап прямого распространения логистической регрессии. Итак, если у вас есть m обучающих выборок, а затем вы делаете прогнозы на первой выборке, вам нужно вычислить так. Для вычисления zzz я использую знакомую формулу z ( 1 ) = w T x ( 1 ) + bz^{(1)}=w^{T}x^{(1)}+bz(1)=wTx( 1)+б. Затем вычислить функцию активации a ( 1 ) = σ ( z ( 1 ) ) a^{(1)}=\sigma (z^{(1)}) a(1)=σ(z(1)) , вычислить the first Прогнозируемое значение yyy для одной выборки.

Затем, чтобы предсказать вторую выборку, вам нужно вычислить z ( 2 ) = w T x ( 2 ) + bz^{(2)}=w^{T}x^{(2)}+bz(2)= wTx (2)+b , а ( 2 ) знак равно σ ( z ( 2 ) ) а ^ {(2)} = \ сигма (z ^ {(2)}) а (2) = σ (z (2)) . Затем, чтобы предсказать третью выборку, вам нужно вычислить z ( 3 ) = w T x ( 3 ) + bz ^ {(3)} = w ^ {T} x ^ {(3)} + bz (3) = wTx (3)+b , a ( 3 ) = σ ( z ( 3 ) ) a ^ {(3)} = \ sigma (z ^ {(3)}) a (3) = σ (z (3)) , И так далее. Если у вас есть m m обучающих выборок, вам может потребоваться сделать это m m m раз, как вы можете видеть, чтобы завершить шаг прямого прохода, то есть вычислить прогнозы для наших m m выборок. Существует способ, который не требует явногоforцикл. Давайте посмотрим, что вы можете сделать.

Во-первых, вспомните, что мы использовали матрицу X X X в качестве входных данных для обучения (синий X X X на изображении ниже), сложенных вместе в разных столбцах, подобных этому. Это матрица из n x n_x nx строк m m m столбцов. Я сейчас пишу это какPython numpyвида ( nx , m ) (n_{x},m) (nx​,m) , что просто означает, что XXX представляет собой nx n_x nx​, умноженное на матрицу mmm R nx × m R^{n_x \times m} Рнх×м.
在这里插入图片描述

Теперь первое, что я хочу сделать, это рассказать вам, как вычислить z 1 z_1 z1, z 2 z_2 z2, z 3 z_3 z3 и так далее за один шаг. Фактически использовалась только одна строка кода. Итак, я собираюсь сначала построить матрицу 1 × m 1\times m 1 × m, которая на самом деле является вектором-строкой, и я собираюсь вычислить z ( 1 ) z^{(1)} z(1), z ( 2) z^{(2)} z(2) ... вплоть до z ( m ) z^{(m)} z(m) , все одновременно. Оказывается, это можно выразить как транспонирование www, умноженное на прописную матрицу xxx, а затем добавление вектора [ bb . . . b ] [b b...b] [bb...b] , ( [ z ( 1 ) z ( 2 ) . . . z ( m ) ] = w T + [ bb . . . . b ] ) ([z^{(1)} z^{(2)}...z^{(m )}]= w^{T}+[bb...b]) ([z(1)z(2)...z(m)]=wT+[bb...b]) . [ bb . . . b ] [b b...b] [bb...b] является вектором 1 × m 1\times m 1×m или матрицей 1 × m 1\times m 1×m или ммм-мерный вектор-строку. Итак, надеюсь, вы знакомы с умножением матриц, вы найдете транспонирование умножения x ( 1 ) x ^ {(1)} x (1) , x ( 2 ) x ^ {(2)} x (2) вплоть до x ( m ) x^{(m)} x(m) . Таким образом, транспонирование w w w может быть вектором-строкой. Таким образом, первый член w TX w^{T}X wTX будет вычислять транспонирование www, умноженное на x ( 1 ) x^{(1)} x(1), и транспонирование www, умноженное на x ( 2 ) x^{( 2 )} x(2) и так далее. Затем мы добавляем второй член [ b b . . . b ] [b b...b] [bb...b], и в итоге вы добавляете b b b к каждому элементу. Таким образом, вы получите еще один вектор 1 × m 1\times m 1 × m, [ z ( 1 ) z ( 2 ) . . . z ( m ) ] = w TX + [ bb . . . . b ] = [ w T x(1)+b,wTx(2)+b...wTx(m)+b][z^{(1)}z^{(2)}...z^{(m )}]=w^{T}X+[b b...b]=[w^{T}x^{(1)}+b,w^{T}x^{(2)}+ b. ..w^{T}x^{(m)}+b] [z(1)z(2)...z(m)]=wTX+[bb...b]=[wTx(1 )+ b,wTx(2)+b...wTx(m)+b] .

w T x ( 1 ) + bw^{T}x^{(1)}+b wTx(1)+b Это первый элемент, w T x ( 2 ) + bw^{T}x^{( 2 )}+b wTx(2)+b это второй элемент, w T x ( m ) + bw^{T}x^{(m)}+b wTx(m)+b это ммм-й элемент.

Если вы обратитесь к приведенному выше определению, первый элемент в точности соответствует определению z ( 1 ) z^{(1)} z(1), а второй элемент в точности равен z ( 2 ) z^{(2)} z( 2) определение и так далее. Итак, так как XXX получается сразу, когда вы получаете свои обучающие выборки, они укладываются горизонтально одна за другой, здесь я буду [z (1) z (2) . ) } z^{(2)} ... z^{(m)}] [z(1)z(2)...z(m)] определяются как ZZZ в верхнем регистре, вы представляете их в нижнем регистре zzz и бок о бок. Таким образом, когда вы складываете строчные буквы x x x, соответствующие различным обучающим образцам, по горизонтали, вы получаете переменную в верхнем регистре X X X и обрабатываете переменные в нижнем регистре таким же образом, складывая их горизонтально, вы получаете переменную в верхнем регистре Z Z Z . Оказывается, чтобы вычислить W T X + [ b b . . . b ] W^{T}X+[b b ... b] WTX+[bb...b] ,numpyКоманда Z = np.d o t (w.T, X) + b Z=np.dot(w.T,X)+b Z=np.dot(w.T,X)+b. здесь, вPythonЗдесь есть ловкий трюк, где b b b — действительное число, или можно сказать, матрица 1 × 1 1\x 1 1 × 1, просто обычное действительное число. Но когда вы добавляете этот вектор к этому действительному числу,PythonАвтоматически преобразует действительное число b b b в вектор-строку размером 1 × m 1\times m 1 × m. Так что операция в этом случае кажется немного странной, она вPythonизвестный как вещание (brosdcasting), пока не беспокойтесь об этом, мы объясним это подробнее в следующем видео. Опять же, это только одна строка кода, с помощью этой строки кода вы можете вычислить ZZZ в верхнем регистре, а ZZZ в верхнем регистре — это az(1) до $z^{(m, который содержит все строчные буквы z ( 1 ) z^{(1 )} )}$ 1 × m 1\times m 1×m матрица. Вот что такое Z Z Z, а как насчет переменных a a a ?

Все, что нам нужно сделать дальше, это найти метод, который одновременно вычисляет [ a ( 1 ) a ( 2 ) . . . a ( m ) ] [a^{(1)} a^{(2)} ... a ^{( m)}] [a(1)a(2)...a(m)] . Точно так же, как складывание строчных букв x x x для получения прописных X X X и строчных букв z z z по горизонтали для получения прописных Z Z Z, складывание строчных переменных a a a формирует новую переменную, которую мы определяем как прописные A A A. В заданиях по программированию вы увидите, как использовать вектор вsigmoidрасчет в функции. такsigmoidФункция принимает капитал Z Z Z в качестве переменной и очень эффективно выводит капитал A A A. Вы увидите это подробно в заданиях по программированию.

Подводя итог, как мы видели на этом слайде, нет необходимостиforЦикл, используйте m m m обучающие образцы для одновременного вычисления строчных букв z z z и строчных букв a a a a, что можно выполнить с помощью одной строки кода.

Z = np.dot(w.T,X) + b

Эта строка кода: A = [a(1)a(2)...a(m)] = σ(Z)A=[a^{(1)}a^{(2)}...a ^ {(m)}]=\sigma (Z) A=[a(1)a(2)...a(m)]=σ(Z) , правильно применяя σ \sigma σ для вычисления всех aaa в однажды . Вот как вы можете одновременно векторизовать прямой проход всех m обучающих выборок.

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

2.14 Векторизация градиента логистической регрессии

Примечание. Заглавные буквы в этом разделе обозначают векторы, а строчные буквы — элементы.

Как векторизовать вычисления, предсказывая результат a a a a для всего обучающего набора, это то, что мы обсуждали ранее. В этом видео мы узнаем, как векторизовать градиент обучающих данных m. Основное внимание в этом видео уделяется тому, какв то же времяРассчитайте градиент данных m m и реализуйте очень эффективный алгоритм логистической регрессии** (логистическая регрессия**).

Когда мы говорили о вычислении градиента ранее, мы привели несколько примеров: dz (1) = a (1) − y (1) dz^{(1)}=a^{(1)}-y^{(1)} dz(1)=a(1)−y(1), dz(2) = a(2)−y(2) dz^{(2)}=a^{(2)}-y^{(2 )} dz(2)=a(2)−y(2) … и ряд подобных формул. Теперь, делая то же самое для обучающих данных mmm, мы можем определить новую переменную d Z = [dz (1), dz (2)... {(2)} ... dz^{(m)}] dZ=[dz(1),dz(2)...dz(m)]
, все переменные d z dz dz расположены горизонтально, поэтому d Z dZ dZ представляет собой матрицу размера 1 × m 1 \× m 1 × m или вектор-строку размерности m m m. На предыдущих слайдах мы уже знаем, как вычислять AAA, т. е. [a(1), a(2)...a(m)] [a^{(1)},a^{(2)}... .a^{(m)}] [a(1),a(2)...a(m)], нам нужно найти такой вектор-строку Y = [y(1)y(2)... y ( m ) ] Y = [y ^ {(1)} y ^ {(2)} ... y ^ {(m)}] Y = [y (1) y (2) ... y ( m )] , из которого мы можем вычислить d Z = A − Y = [ a ( 1 ) − y ( 1 ) a ( 2 ) − y ( 2 ) ... a ( m ) − y ( m ) ] =[a^{(1)}-y^{(1)} a^{(2)}-y^{(2)} ... a^{(m)}-y^{(m)} ] dZ=A−Y=[a(1)−y(1)a(2)−y(2)...a(m)−y(m)], нетрудно найти первый элемент It это dz ( 1 ) dz ^ {(1)} dz (1), а второй элемент - dz ( 2 ) dz ^ {(2)} dz (2) ... Итак, теперь нам нужна только одна строка кода, мы можем одновременно делать все эти расчеты.

В предыдущей реализации мы удалилиforцикл, но у нас все еще есть цикл, который проходит через тренировочный набор, например:

d w = 0 dw=0 dw=0

d w + = x ( 1 ) * d z ( 1 ) dw + = x ^ {(1)} * {dz} ^ {(1)} dw + = x (1) * dz (1)

d w + = x ( 2 ) * d z ( 2 ) dw + = x ^ {(2)} \ * dz ^ {(2)} dw + = x (2) * dz (2)

………….

d w + = x ( m ) * d z ( m ) dw + = x ^ {(m)} * {dz} ^ {(m)} dw + = x (m) * dz (m)

d w = d w m dw = \frac{{dw}}{m} dw=mdw​

d b = 0 db = 0 db=0

d b + = d z ( 1 ) db + = {dz}^{(1)} db+=dz(1)

d b + = d z ( 2 ) db + = {dz}^{(2)} db+=dz(2)

………….

d b + = d z ( m ) db + = dz^{(m)} db+=dz(m)

d b = d b m db = \frac{{db}}{m} db=mdb​

Приведенный выше (псевдо) код — это то, что мы сделали в предыдущей реализации, мы удалилиforцикл, но вычисление d w dw dw с помощью описанного выше метода по-прежнему требует цикла по обучающему набору, все, что нам нужно сделать, это векторизовать его!

Прежде всего, давайте посмотрим на db db db, нетрудно найти, что db = 1 m ∑ i = 1 mdz ( i ) db=\frac{1}{m}\sum_{i=1}^{m }dz^{(i) } db=m1​i=1∑m​dz(i) ,
В предыдущем объяснении мы знаем, что все d z i ) dz^(i)} dzi) сформировали вектор-строку d Z dZ dZ, поэтому вPython, мы можем легко думать о db = 1 m ∗ np.sum ( d Z ) db=\frac{1}{m}*np.sum(dZ) db=m1​∗np.sum(dZ); тогда Глядя на dw dw dw сначала запишем его формулу dw = 1 m ∗ X ∗ dz T dw=\frac{1}{m}*X*dz^{T} dw=m1​∗X∗dzT
где X X X — вектор-строка. Таким образом, после разложения dw = 1 m * ( x ( 1 ) dz ( 1 ) + x ( 2 ) dz ( 2 ) + ... + xmdzm ) dw = \ frac {1} {m} * (x ^ {(1 )}dz^{(1)}+x^{(2)}dz^{(2)}+...+x^{m}dz^{m}) dw=m1​∗(x(1) dz(1)+x(2)dz(2)+...+xmdzm) . Таким образом, мы можем выполнить вычисление всего двумя строками кода: (dZ ), dw = 1 m ∗ X ∗ dz T dw=\frac{1}{m}*X*dz^{T} dw=m1​∗X∗dzT. Таким образом, мы избегаем использования цикла for на тренировочном наборе.

Теперь давайте оглянемся назад и посмотрим, как мы реализовали логистическую регрессию раньше, Мы видим, что без векторизации она очень неэффективна, как показано в коде ниже:
在这里插入图片描述

Наша цель не использоватьforпетли, но векторы, мы можем сделать это:

Z = w T X + b = n p . d o t ( w . T , X ) + b Z = w^{T}X + b = np.dot( w.T,X)+b Z=wTX+b=np.dot(w.T,X)+b

A = σ ( Z ) A = \ sigma ( Z ) A = σ ( Z )

d Z = A − Y dZ = A - Y dZ=A−Y

d w = 1 m ∗ X ∗ d z T {{dw} = \frac{1}{m}*X*dz^{T}\ } dw=m1​∗X∗dzT

d b = 1 m ∗ n p .s u m ( d Z ) db= \frac{1}{m}*np.sum( dZ)​ db=m1​∗np.sum(dZ)​

w : = w − a ∗ d w w w : = w - a*dw w:=w−a∗dw

b : = b − a ∗ d b b b: = b - a*db b:=b−a∗db

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

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

2.15 Вещание в Python

在这里插入图片描述

Это таблица калорийности различных нутриентов в разных продуктах (на 100 г), таблица состоит из 3 строк и 4 столбцов, столбцы представляют разные виды продуктов, слева направо яблоки, говядина, яйца, картофель. Ряды представляют различные питательные вещества, сверху вниз, углеводы, белки, жиры.

Что ж, теперь мы хотим рассчитать процентное содержание калорий в различных питательных веществах в разных продуктах.

Теперь, чтобы рассчитать процент углеводных калорий в яблоках, сначала рассчитайте сумму калорий трех питательных веществ в яблоке (100 г) 56+1,2+1,8
= 59, затем используйте 56/59 = 94,9%, чтобы вычислить результат.

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

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

Итак, можем ли мы не использоватьforЦикл для завершения такого процесса расчета?

Предположим, что приведенная выше таблица представляет собой матрицу A A A с 4 строками и 3 столбцами, обозначенную как A 3 × 4 A_{3\times 4} A3×4​, тогда нам нужно использоватьPythonизnumpyБиблиотека выполняет такие вычисления. Мы собираемся сделать это с помощью двух строк кода, первая для суммирования каждого столбца, а вторая для расчета процентного содержания каждого питательного вещества для каждого продукта отдельно.

существуетjupyter notebookВведите следующий код в полеshift+Enterзапустить, вывод следующий.
在这里插入图片描述

Следующий код используется для вычисления суммы каждого столбца, и вы можете видеть, что результатом является сумма калорий каждого продукта (100 г).
在这里插入图片描述

вsumпараметрыaxis=0Указывает, что операция суммирования выполняется в столбцах, что будет подробно объяснено позже.

Затем, чтобы вычислить процент, эта инструкция делит матрицу 3 × 4 3\times 4 3×4 AAA на матрицу 1 × 4 1 ​​\times 4 1×4, в результате чего получается 3 × 4 3 \times 4 3× Матрица результата 4, эта матрица результата представляет собой процентное содержание, которое нам требуется.
在这里插入图片描述

Давайте объясним это сноваA.sum(axis = 0)параметры вaxis.Ось используется для указания, по какой оси будет выполняться операция, В numpy ось 0 — вертикальная, то есть столбец, а ось 1 — горизонтальная, то есть строка.

а второйA/cal.reshape(1,4)командные вызовыnumpyмеханизм трансляции в . При этом используется матрица 3 × 4 3 \times 4 3×4 A A A, разделенная на матрицу 1 × 4 1 ​​\times 4 1×4 c a l cal cal. С технической точки зрения на самом деле нет необходимости преобразовывать матрицу c в cal cal.reshape(изменить форму) до 1 × 4 1 ​​\times 4 1×4, потому что сама матрица c a l cal cal уже имеет размер 1 × 4 1 ​​\times 4 1×4. Но когда мы не знаем размеров матрицы при написании кода, мы обычно изменяем форму матрицы, чтобы убедиться, что получаем нужный столбец или вектор-строку. операция изменения формыreshapeявляется операцией с постоянным временем, временная сложность составляет O ( 1 ) O (1) O (1), а стоимость вызова чрезвычайно мала.

Итак, как матрица 3 × 4 3 \× 4 3×4 выполняет деление с матрицей 1 × 4 1 ​​\× 4 1×4? Давайте рассмотрим еще несколько примеров трансляции.
在这里插入图片描述

В numpy, когда к константе добавляется вектор-столбец 4 × 1 4 \times 1 4×1, константа фактически расширяется до вектора-столбца 4 × 1 4 \times 1 4×1, а затем два элемента do element- мудрое дополнение. Результатом является этот вектор справа. Этот широковещательный механизм можно использовать как для векторов строк, так и для векторов столбцов.

Посмотрите на следующий пример.
在这里插入图片描述

Добавление матрицы 2 × 3 2 \times 3 2×3 к матрице 1 × 3 1 \times 3 1×3 приводит к обобщению матрицы m × nm \times nm×n и матрицы 1 × n 1 \times n 1×n добавление матрицы. При выполнении операции сложения матрица размера 1 × n 1 \times n 1×n фактически копируется в матрицу размера m × n m \times n m × n, а затем они складываются поэлементно, чтобы получить результат. Для этого конкретного примера это эквивалентно добавлению 100 к первому столбцу матрицы, 200 ко второму столбцу и 300 к третьему столбцу. Это механизм широковещательной передачи для расчета процентного содержания калорий на предыдущем слайде, за исключением того, что это операция деления (механизм широковещательной передачи не зависит от типа выполняемой операции).

Вот последний пример
在这里插入图片描述

Это эквивалентно матрице m × n m \times n m×n плюс матрица m × 1 m \times 1 m×1. При выполнении операции матрица m × 1 m \times 1 m×1 будет n n n раз по горизонтали скопирована в матрицу m × n m \times n m×n, а затем будет выполнено поэлементное сложение.

Общие принципы механизма трансляции следующие:
在这里插入图片描述

Здесь я сначала скажу, что яnumpyДля понимания механизма вещания объясните приведенный выше PPT.

прежде всегоnumpyшироковещательный механизм

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

Длина вала по задней кромке:A.shape[-1]то есть значение в последней позиции в кортеже измерения матрицы

Для примера расчета калорий в видео длина оси размера заднего края матрицы A 3 , 4 A_{3,4} A3,4​ равна 4, а размер заднего края матрицы cal 1 , 4 cal_ {1,4} cal1,4​ Размер края также равен 4, тогда они соответствуют длине размера заднего края и могут транслироваться. Вещание будет осуществляться в измерении, длина оси которого равна 1, а измерение, длина оси которого равна 1, соответствуетaxis=0, то есть вертикальное направление, матрица cal 1 , 4 \text{cal}_{1,4} cal1,4​ вдольaxis=0(Вертикальная) копия как ошибка синтаксического анализа KaTeX: ожидается '}', получено '_' в позиции 10: \text{cal_̲temp}_{3,4} , после чего два выполняют поэлементное деление.

Теперь объясните пример на изображении выше.

Матрица A m , n A_{m,n} Am,n​ и матрица B 1 , n B_{1,n} B1,n​ выполняют четыре арифметических операции, размерность заднего фронта согласована, может транслироваться, транслируется по длине оси Для оси 1, то есть B 1 , n B_{1,n} B1,n​ транслируется в B m , n ′ {B_{m,n}}' Bm,n​ , а затем выполнить поэлементно четыре арифметических операции.

Матрица A m , n A_{m,n} Am,n​ и матрица B m , 1 B_{m,1} Bm,1​ выполняют четыре арифметических операции, длина размерности заднего фронта не совпадает, но одна из оси имеет длину 1 , может транслировать, транслировать вдоль оси длину оси 1, т.е. B m , 1 B_{m,1} Bm,1​ трансляция становится B m , n ′ {B_{m,n}} ' Bm,n​ ' , а затем выполните поэлементно четыре арифметических операции.

Матрица Am , 1 A_{m,1} Am,1​ и константа $R$ выполняют четыре арифметических операции, длина размерности заднего фронта не совпадает, но одна из осей имеет длину 1, что может транслироваться, и транслироваться по недостающему измерению и оси. Ось длины 1 проводится, а недостающее измерениеaxis=0, ось длины оси 1 равнаaxis=1, то есть R R R широковещательная передача становится B m , 1 ′ {B_{m,1}}' Bm,1​′ , а затем выполняет поэлементно четыре арифметических операции.

Наконец, дляMatlab/Octaveфункции с аналогичным функционаломbsxfun.

в заключенииbroadcasting, вы можете увидеть следующий рисунок:
在这里插入图片描述

2.16 Примечание о векторах python или numpy (Примечание о векторах python или numpy), справочное видео:

В этом разделе в основном говорится оPythonсерединаnumpyХарактеристики одномерных массивов и их отличие от векторов строк или столбцов. И ввел некоторые небольшие навыки в практическое применение учителей, чтобы избежатьcodingблагодаря этим характеристикамbug.

PythonЭта функция позволяет использовать широковещательную передачу (broadcasting) функция, котораяPythonизnumpyСамое гибкое место в библиотеке языка программирования. И я думаю, что это одновременно и преимущество, и недостаток языков программирования. Причина преимущества в том, что они создают выразительность языка,PythonОгромная гибкость языка позволяет вам делать многое с помощью всего одной строки кода. Но это и недостаток.Из-за огромной гибкости вещания, иногда, если вы не знакомы с деталями характеристик вещания и как работает вещание, у вас могут быть очень тонкие или странные на видbug. Например, если вы добавите вектор-столбец к вектору-строке, вы подумаете, что он сообщит об ошибках, таких как несоответствие размеров или неправильный тип, но на самом деле вы получите сумму векторов-строк и столбцов.

существуетPythonНа самом деле между этими странными влияниями существует неотъемлемая логическая связь. Но если правильноPythonЕсли вы не знакомы, некоторые из студентов, которых я видел, очень прямолинейны, и их очень трудно найти.bug. Итак, что я пытаюсь здесь сделать, так это поделиться с вами некоторыми советами, которые были очень полезны для меня, чтобы устранить или упростить все странно выглядящие вещи в моем коде.bug. В то же время я также надеюсь, что с этими советами вам будет легче писать безbugизPythonиnumpyкод.

для демонстрацииPython-numpyлегко упускаемый из виду эффектPython-numpyПостроение векторов в , позвольте мне сделать быструю демонстрацию. Сначала установите a = n p.r a n d o m .r a n d n (5) a=np.random.randn(5) a=np.random.randn(5), что генерирует 5 гауссовых случайных величин, хранящихся в массиве a a a . Затем выведите a a a, на экране видно, что в это время значение a a ashape(форма) является структурой ( 5 , ) (5,) (5,). это вPythonизвестный какодномерный массив. Это не вектор-строка и не вектор-столбец, что также приводит к некоторым неинтуитивным эффектам. Например, если я выведу транспонирование, конечный результат будет выглядеть так же, как a a a a, поэтому конечный результат a a a и a a a будет выглядеть одинаково. И если я выведу внутренний продукт a a a и транспонирование a a a, вы можете подумать: a a a, умноженное на транспонирование a a a, может дать вам матрицу. Но если я сделаю это, ты получишь только число.

在这里插入图片描述

Поэтому при написании нейронной сети рекомендуется не использовать форму в качестве(5,),(n,)Или другие структуры данных одномерного массива. И наоборот, если вы установите a a a равным ( 5 , 1 ) (5,1) (5,1), то это будет помещено в 5-строчный вектор с 1 столбцом. Там, где транспонирование a a a и a a a выглядело одинаково в предыдущей операции, теперь такое a a становится новым транспонированием a a a и является вектором-строкой. Обратите внимание на тонкую разницу: в этой структуре данных есть две квадратные скобки, когда мы выводим транспонирование a a a , тогда как раньше была только одна квадратная скобка, так что это разница между матрицей из 1 строки и 5 столбцов и одномерным массивом.
在这里插入图片描述

Если вы выведете произведение a a a и транспонирование a a a , то это вернет вам внешнее произведение вектора, верно? Таким образом, внешнее произведение этих двух векторов возвращает вам матрицу.
在这里插入图片描述

Давайте немного продолжим то, что мы только что видели. Сначала мы только что запустили команду (a = np.random.randn(5)) (a=np.random.randn(5)) (a=np.random.randn(5)) которая генерирует структуру данных aaa , где а.форма а.форма а.форма есть ( 5 , ) (5,) (5,). Это называется одномерным массивом a a a, и это очень интересная структура данных. Он ведет себя не так хорошо, как векторы строк и столбцов, что делает его неинтуитивным. Поэтому я предлагаю вам не использовать эти одномерные массивы, когда вы выполняете упражнения по программированию или выполняете логистическую регрессию и нейронные сети.
在这里插入图片描述

И наоборот, если вы создаете массив каждый раз, когда вам нужно сделать его вектор-столбцом, получить вектор (5, 1) (5,1) (5,1) или сделать его вектором-строкой, то ваше поведение векторов может быть легче понять. Таким образом, в этом случае a.s h a p e a.shape a.shape эквивалентна ( 5 , 1 ) (5,1) (5,1). Это ведет себя так же, как a a a, но на самом деле является вектором-столбцом. И именно поэтому, когда это вектор-столбец, вы можете думать о нем как о матрице ( 5 , 1 ) (5,1) (5,1), и здесь .shape a.shape a.shape станет ( 1 , 5 ) (1,5) (1,5), что похоже на вектор-строку. Поэтому, когда вам нужен вектор, я бы сказал, используйте тот или иной (column vector or row vector), но никогда не одномерный массив.

在这里插入图片描述

Еще одна вещь, которую я часто делаю при написании кода, — это если я не совсем уверен в размерах вектора (dimension), я часто добавляю оператор assert (assertion statement). Вот так, чтобы убедиться, что это вектор ( 5 , 1 ) (5,1) (5,1) в данном случае или вектор-столбец. Эти операторы Assert фактически будут выполняться, и они также помогут информировать ваш код. Итак, что бы вы ни хотели сделать, не стесняйтесь вставлять оператор assert напрямую. Если вы случайно выполнили одномерный массив, вы также можете изменить размер массива a = reshapea=reshape a=reshape, чтобы указать массив ( 5 , 1 ) (5,1) (5,1) или ( 1 , 5 ) (1,5) (1,5) массив, чтобы он вел себя больше как столбец или вектор-строка.
在这里插入图片描述

Иногда я вижу, как у студентов возникают проблемы с поиском ошибок из-за неинтуитивных эффектов одномерных массивов. Благодаря очистке одномерного массива в исходном коде мой код стал более лаконичным. И на самом деле я никогда не использую одномерные массивы, насколько это показано в моем коде. Итак, упростите свой код и не используйте одномерные массивы. Всегда используйте размерные матрицы n × 1 n \times 1 n×1 (в основном векторы-столбцы) или 1 × n 1 \times n 1×n размерные матрицы (в основном векторы-строки), таким образом вы можете значительно уменьшитьassertоператор, чтобы сэкономить время на размерности матриц и массивов ядра. Кроме того, не стесняйтесь убедиться, что ваша матрица или вектор имеют необходимое количество измерений.reshapeработать.

В общем, я надеюсь, что эти советы помогут вам решитьPythonчтобы вам было легче выполнять упражнения.

2.17 Краткий обзор ноутбуков Jupyter/iPython

К настоящему времени вы собираетесь начать работу над своим первым заданием по программированию. Но перед этим позвольте мне быстро представить вамCourseraВверхiPython Notebooksинструмент.
在这里插入图片描述

ЭтоJupyter iPython Notebooksинтерфейс, через который вы можете подключиться кCoursera. Позвольте мне быстро объяснить некоторые из его особенностей. Описание об этом было написано в этомNotebookсередина.
在这里插入图片描述

Вот несколько блоков кода с пустым пространством, где вы можете писать код. Иногда вы также увидите некоторые функциональные блоки. И объяснения этому уже есть вiPython Notebookв тексте. существуетiPython Notebook, в этих более длинных серых областях находятся кодовые блоки.
在这里插入图片描述

Иногда вы увидите такие коды начала и окончания в блоке кода. При выполнении упражнений по программированию убедитесь, что ваш код написан между начальным и конечным кодами.
在这里插入图片描述

Например, написать распечаткуHello Worldкод, затем выполните этот блок кода (вы можете нажатьshift +enterдля выполнения этого блока кода). В конце концов, он выведет то, что мы хотимHello World.
在这里插入图片描述

управление ячейкойcell, вы также можете запустить в нем блок кода. кликнувCellменюRun CellsВыполните эту часть кода.

Может быть, на вашем компьютере запуститеcellСочетание клавиш для может не бытьshift enter. Тем не менее, Mac должен иметь возможность использовать то же, что и мой ПК.shift + enterбежатьcell.
在这里插入图片描述

Когда вы читаете руководство, если вы случайно дважды щелкнете по нему, область в точке станетmarkdownязыковая форма. Если вы случайно попали в такое текстовое поле, просто запустите следующую ячейкуcell, вы можете вернуться к исходной форме. Итак, нажмитеcellменюRun Cellsили использоватьshift + enter, вы можете вернуть его в исходное состояние.
在这里插入图片描述

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

Итак, если вы выполняете относительно небольшие задания и только началиipadИли ноутбуки, этого никогда не должно быть. Однако, если вы видите сообщение об ошибке, напримерKernelБыла прервана или другая информация, вы можете попробовать перезапуститьKernel.
在这里插入图片描述

когда я используюiPython NotebookКогда имеется несколько блоков кодовой области. Несмотря на то, что я не добавлял свой собственный код в предыдущий блок кода, обязательно сначала выполните этот блок. Поскольку в этом примере он импортируетnumpyпакет и назван иначеnpetc, и объявляет некоторые переменные, которые могут вам понадобиться. Чтобы успешно выполнить приведенный ниже код, вы должны убедиться, что приведенный выше код выполняется первым, даже если вам не требуется писать другой код.
在这里插入图片描述

Наконец, когда вы закончите свою домашнюю работу, вы можете щелкнуть синююSubmit Assignmentкнопку, чтобы отправить задание.

Я нашел этот интерактивshellкоманда, вiPython NotebooksЭто очень полезно и позволяет вам быстро реализовать код и увидеть результат для легкого обучения. Поэтому я надеюсь, что эти упражнения иJupyter iPython NotebooksЭто поможет вам учиться и практиковаться быстрее, а также поможет вам понять, как реализовать эти алгоритмы обучения. Следующее видео является факультативным видео, которое в основном объясняет функцию стоимости в логистической регрессии. Вы можете выбрать, смотреть его или нет. В любом случае желаю вам пройти эти два задания по программированию. Жду вас на новой неделе занятий.

2.18 (Необязательно) Объяснение функции стоимости логистической регрессии

В предыдущем видео мы проанализировали выражение функции потерь логистической регрессии, в этом факультативном видео я приведу краткое доказательство, объясняющее, почему функция потерь логистической регрессии имеет такую ​​форму.
在这里插入图片描述

Напомним, что в логистической регрессии результат, который необходимо предсказать y ^ \hat{y} y^​, может быть выражен как y ^ = σ ( w T x + b ) \hat{y}=\sigma(w^ {T }x+b) y^​=σ(wTx+b), σ \sigma σ — известная функция типа SSS σ ( z ) = σ ( w T x + b ) = 1 1 + e − z \ sigma ( z)=\sigma(w^{T}x+b)=\frac{1}{1+e^{-z}} σ(z)=σ(wTx+b)=1+e−z1 . Условимся, что y ^ = p ( y = 1 ∣ x ) \hat{y}=p(y=1|x) y^​=p(y=1∣x) , то есть результат работы алгоритма y ^ \hat{y } y^​ — вероятность того, что yyy равно 1 для обучающей выборки xxx. Другими словами, если y = 1 y=1 y=1, y = y ^ y=\hat{y} y=y^​ для данной обучающей выборки xxx, и наоборот, если y = 0 y= 0 y=0 , yyy равно 1 минус y ^ ( y = 1 − y ^ ) \hat{y}(y=1-\hat{y}) y^​(y= 1−y^​), поэтому, если y ^ \hat{y} y^​ представляет вероятность y = 1 y=1 y=1, тогда 1 − y ^ 1-\hat{y} 1−y^​ представляет собой вероятность того, что y = 0 y=0 y =0. Далее мы анализируем эти две формулы условной вероятности.
在这里插入图片描述

Две формулы условной вероятности определены в виде p (y ∣ x) p(y|x) p(y∣x) и представляют y = 0 y=0 y=0 или y = 1 y=1 y=1 In В обоих случаях мы можем объединить эти две формулы в одну формулу. Следует отметить, что речь идет о функции потерь задачи бинарной классификации, поэтому значение y y y может быть только 0 или 1. Приведенные выше две формулы условной вероятности можно объединить в следующую формулу:

п ( y ∣ Икс ) знак равно y ^ y ( 1 - y ^ ) ( 1 - y ) p (y | x) = {\ hat {y}} ^ {y} {(1- \ hat {y})} ^{(1-y)} p(y∣x)=y^​y(1−y^​)(1−y)

Далее я объясню, почему его можно объединить в выражения вида: ( 1 − y ^ ) (1-\hat{y}) (1−y^​) of ( 1 − y ) (1-y) ( 1−y) power Эта строка выражения содержит две приведенные выше формулы условной вероятности, позвольте мне объяснить, почему.
在这里插入图片描述

В первом случае предположим, что y = 1 y=1 y=1, поскольку y = 1 y=1 y=1, тогда ( y ^ ) y = y ^ {(\hat{y})}^{y}= \hat{y} (y^​)y=y^​, так как y ^ \hat{y} y^​ в степени 1 равно y ^ \hat{y} y^​, 1 − ( 1 − y ^ ) ( 1 − y ) 1-{(1-\hat{y})}^{(1-y)} 1−(1−y^​)(1−y) экспоненциальный член ( 1 − y ) ( 1-y) (1−y) равно 0. Поскольку любое число, возведенное в степень 0, равно 1, y ^ \hat{y} y^​, умноженное на 1, равно y ^ \hat{y} y^ . Итак, когда y = 1 y=1 y=1 p ( y ∣ x ) = y ^ p(y|x)=\hat{y} p(y∣x)=y^​ (зеленая часть на рисунке).

Во втором случае, когда y = 0 y=0 y=0, чему равно p ( y ∣ x ) p(y|x) p(y∣x)?
Предполагая, что y = 0 y=0 y=0, yyy степень y ^ \hat{y} y^​ является 0-й степенью y ^ \hat{y} y^​, а 0-я степень любого числа равна к 1 , так что p ( y ∣ x ) = 1 × ( 1 − y ^ ) 1 − yp(y|x)=1×{(1-\hat{y})}^{1-y} p(y ∣x )=1×(1−y^​)1−y , предполагая, что y = 0 y=0 y=0, поэтому ( 1 − y ) (1-y) (1−y) равно 1, поэтому p ( y ∣ x ) = 1 × ( 1 − y ^ ) p(y|x)=1×(1-\hat{y}) p(y∣x)=1×(1−y^​). Итак, здесь, когда y = 0 y=0 y=0, p ( y ∣ x ) = 1 − y ^ p(y|x)=1-\hat{y} p(y∣x)=1−y ^ . Это результат этой формулы (вторая формула, показанная на рисунке фиолетовым цветом).

Таким образом, вывод только что показывает, что p ( y ∣ x ) = y ^ ( y ) ( 1 - y ^ ) ( 1 - y ) p (y | x) = {\ hat {y}} ^ {(y) }{ (1-\hat{y})}^{(1-y)} p(y∣x)=y^​(y)(1−y^​)(1−y), что равно p ( y ∣ x ) p(y|x) полное определение p(y∣x). Поскольку логарифмическая функция строго монотонно возрастает, максимизация log ( p ( y ∣ x ) ) log (p (y | x)) log (p (y ∣ x )) эквивалентна максимизации p ( y ∣ x ) p (y |x) p(y∣x) и вычисление логарифма p ( y ∣ x ) p(y|x) p(y∣x) , состоит в вычислении log ( y ^ ( y ) ( 1 − y ^ ) ( 1 − y ) ) log({\hat{y}}^{(y)}{(1-\hat{y})}^{(1-y)}) log(y^​(y)(1 −y^​)(1−y)) (фактически это замена p(y∣x)p(y|x)p(y∣x)), которая упрощается логарифмической функцией:

ylogy ^ + ( 1 − y ) log ( 1 − y ^ ) ylog\hat{y}+(1-y)log(1-\hat{y}) ylogy^​+(1−y)log(1− у^)

И это отрицательное значение функции потерь, о которой мы упоминали ранее ( − L ( y ^ , y ) ) (-L(\hat{y},y)) (−L(y^​,y)) , существует Причина отрицательного знака заключается в том, что при обучении алгоритма обучения вам нужен алгоритм для вывода значения с наибольшей вероятностью (чтобы предсказать это значение с наибольшей вероятностью), однако в логистической регрессии нам нужно минимизировать функцию потерь, поэтому минимизация функции потерь аналогична максимизации. Логарифм условной вероятности функциональное выражение для одного обучающего примера.
在这里插入图片描述

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

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

P (метки в обучающем наборе) = ∏ i = 1 m P (y (i) ∣ x (i) ) P\left(\text{метки в обучающем наборе} \right) = \prod_{i =1}^{ m}{P(y^{(i)}|x^{(i)})} P(метки в обучающем наборе)=∏i=1m​P(y(i)∣x(i)).
在这里插入图片描述

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

logp (метки в обучающем наборе) = log ∏ i = 1 м P (y (i) ∣ x (i)) = ∑ i = 1 mlog P (y (i) ∣ x (i)) = ∑ i = 1 m − L ( y ^ ( i ) , y ( i ) ) logp\left( \text{метки в обучающем наборе} \right) = log\prod_{i =1}^{m}{P(y^{(i )}|x^{(i)})} = \sum_{i = 1}^{m}{logP(y^{(i)}|x^{(i)})} = \sum_{i = 1}^{m}{- L(\hat y^{(i)},y^{(i)})} logp(метки в обучающем наборе)=log∏i=1m​P(y(i)∣ x(i))=∑i=1m​logP(y(i)∣x(i))=∑i=1m​−L(y^​(i),y(i))

В статистике есть метод, называемый оценкой максимального правдоподобия, то есть найти набор параметров, чтобы это выражение приняло максимальное значение, то есть чтобы это выражение приняло максимальное значение, ∑ i = 1 m − L ( y ^ ( i ) , y ( i ) ) \sum_{i= 1}^{m}{- L(\hat y^{(i)},y^{(i)})} ∑i=1m − L(y^​(i),y(i)), можно переместить знак минус за знак суммы, − ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) - \sum_{ i = 1} ^ {m} {L (\ шляпа y ^ {(i)}, y ^ {(i)})} −∑i = 1m​L (y ^​(i), y (i)) , так что мы получаем ранее заданноеlogisticФункция стоимости регрессии J ( w , b ) = ∑ i = 1 m L ( y ^ ( i ) , y ( ^ i ) ) J (w, b) = \ sum_ {i = 1} ^ {m} {L ( \шляпа y^{(i)},y^{\шляпа(i)})} J(w,b)=∑i=1m​L(y^​(i),y(^​i)) .
在这里插入图片描述

Поскольку целью обучения модели является минимизация функции стоимости, мы не используем вероятность максимального правдоподобия напрямую, а убираем здесь отрицательный знак Наконец, для удобства функция стоимости может быть соответствующим образом масштабирована, и мы добавляем дополнительную в Постоянный множитель 1 m \frac{1}{m} m1​, а именно: J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ), y ( i ) ) J (w,b )= \frac{1}{m}\sum_{i = 1}^{m}{L(\hat y^{(i)},y^{(i)})} J(w ,b)= m1​∑i=1mL​L(y^​(i),y(i)).

Подводя итог, чтобы минимизировать функцию стоимости J ( w , b ) J (w, b) J (w, b), мы начинаем сlogisticС точки зрения оценки максимального правдоподобия регрессионной модели предполагается, что все выборки в обучающей выборке независимы и одинаково распределены. Хотя этот класс является факультативным, спасибо за просмотр этого видео. Я надеюсь, что с помощью этого класса вы сможете лучше понять функцию потерь логистической регрессии, почему она в такой форме, и понять принцип функции потерь, Я надеюсь, что вы сможете продолжать выполнять упражнения после урока, упражнения в предыдущие курсы и викторина на этой неделе, и удачи с викторинами и упражнениями по программированию после занятий.

Но максимизация этой вероятности эквивалентна максимизации ее логарифма, логарифмируя обе части уравнения:

logp (метки в обучающем наборе) = log ∏ i = 1 м P (y (i) ∣ x (i)) = ∑ i = 1 mlog P (y (i) ∣ x (i)) = ∑ i = 1 m − L ( y ^ ( i ) , y ( i ) ) logp\left( \text{метки в обучающем наборе} \right) = log\prod_{i =1}^{m}{P(y^{(i )}|x^{(i)})} = \sum_{i = 1}^{m}{logP(y^{(i)}|x^{(i)})} = \sum_{i = 1}^{m}{- L(\hat y^{(i)},y^{(i)})} logp(метки в обучающем наборе)=log∏i=1m​P(y(i)∣ x(i))=∑i=1m​logP(y(i)∣x(i))=∑i=1m​−L(y^​(i),y(i))

В статистике есть метод, называемый оценкой максимального правдоподобия, то есть найти набор параметров, чтобы это выражение приняло максимальное значение, то есть чтобы это выражение приняло максимальное значение, ∑ i = 1 m − L ( y ^ ( i ) , y ( i ) ) \sum_{i= 1}^{m}{- L(\hat y^{(i)},y^{(i)})} ∑i=1m − L(y^​(i),y(i)), можно переместить знак минус за знак суммы, − ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) - \sum_{ i = 1} ^ {m} {L (\ шляпа y ^ {(i)}, y ^ {(i)})} −∑i = 1m​L (y ^​(i), y (i)) , так что мы получаем ранее заданноеlogisticФункция стоимости регрессии J ( w , b ) = ∑ i = 1 m L ( y ^ ( i ) , y ( ^ i ) ) J (w, b) = \ sum_ {i = 1} ^ {m} {L ( \шляпа y^{(i)},y^{\шляпа(i)})} J(w,b)=∑i=1m​L(y^​(i),y(^​i)) .

[Дамп изображения внешней ссылки...(img-3H3t0XQ2-1616463257131)]

Поскольку целью обучения модели является минимизация функции стоимости, мы не используем вероятность максимального правдоподобия напрямую, а убираем здесь отрицательный знак Наконец, для удобства функция стоимости может быть соответствующим образом масштабирована, и мы добавляем дополнительную в Постоянный множитель 1 m \frac{1}{m} m1​, а именно: J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ), y ( i ) ) J (w,b )= \frac{1}{m}\sum_{i = 1}^{m}{L(\hat y^{(i)},y^{(i)})} J(w ,b)= m1​∑i=1mL​L(y^​(i),y(i)).

Подводя итог, чтобы минимизировать функцию стоимости J ( w , b ) J (w, b) J (w, b), мы начинаем сlogisticС точки зрения оценки максимального правдоподобия регрессионной модели предполагается, что все выборки в обучающей выборке независимы и одинаково распределены. Хотя этот класс является факультативным, спасибо за просмотр этого видео. Я надеюсь, что с помощью этого класса вы сможете лучше понять функцию потерь логистической регрессии, почему она в такой форме, и понять принцип функции потерь, Я надеюсь, что вы сможете продолжать выполнять упражнения после урока, упражнения в предыдущие курсы и викторина на этой неделе, и удачи с викторинами и упражнениями по программированию после занятий.