Масштабирование обратного распространения
Я следую этому уроку по NN и обратному распространению.
Я новичок в Python, и я пытаюсь преобразовать код в MATLAB. Может кто-нибудь любезно объяснить следующую строку кода (из учебника):
delta3[range(num_examples), y] -= 1
Короче, и если я не ошибаюсь, delta3
а также y
векторы и num_examples
является целым числом
Я понимаю, что delta3=probs-y
как в этой записи обмена математикой(спасибо @rayryeng). Почему и когда я должен вычесть 1?
Иначе кто-нибудь может направить меня на онлайн-сайт, который я могу просто запустить и следовать коду? Я получал ошибки везде, где пытался запустить (включая мой домашний компьютер):
"NameError: имя 'sklearn' не определено" (вероятно, импорт, который мне не хватает)
1 ответ
Эта строка: delta3[range(num_examples), y] -= 1
является частью вычисления градиента функции потерь softmax. Я отсылаю вас к этой замечательной ссылке, которая дает вам больше информации о том, как сформулирована эта функция потерь, и об интуиции, стоящей за ней: http://peterroelants.github.io/posts/neural_network_implementation_intermezzo02/.
Кроме того, я отсылаю вас к этому посту по обмену стеками математики, который показывает, как получается градиент потерь softmax: https://math.stackexchange.com/questions/945871/derivative-of-softmax-loss-function. Рассмотрим первую ссылку как глубокое погружение, тогда как вторая ссылка tl;dr
первой ссылки.
Градиент функции потерь softmax - это градиент выходного слоя, который необходимо распространить назад в слой перед выходным слоем, чтобы продолжить алгоритм обратного распространения.
Подводя итог посту, который я связал выше, если вы вычисляете градиент потерь softmax для учебного примера, то для каждого класса градиент потерь представляет собой просто значение softmax, оцененное для этого класса. Кроме того, вам необходимо вычесть значение потери на 1 для класса, к которому относится данный пример обучения. Помните, что градиент примера для класса i
равно p_i - y_i
где p_i
это оценка Softmax класса i
для примера и y_i
классификационная метка, использующая схему горячего кодирования. конкретно y_i = 0
если i
не истинный класс примера и y_i = 1
если это. delta3
содержит градиент функции потерь softmax для каждого примера в вашей мини-партии. В частности, это 2D-матрица, в которой общее количество строк равно количеству обучающих примеров, или num_examples
в то время как количество столбцов - это общее количество классов.
Сначала мы рассчитываем баллы softmax для каждого примера обучения и для каждого класса. Далее для каждой строки градиента мы определяем местоположение столбца, которое соответствует истинному классу, которому принадлежит пример, и вычитаем баллы на 1. range(num_examples)
будет генерировать список из 0
вплоть до num_examples - 1
а также y
содержит истинные метки классов для каждого примера. Поэтому для каждой пары range(num_examples)
а также y
это позволяет получить доступ к правой строке и столбцу, чтобы вычесть 1, чтобы завершить градиент функции потерь.
Теперь в посте Математического стека обмена, а также ваше понимание, градиент delta3 = probs - y
, Это предполагает, что y
является закодированной матрицей, означающей, что y
имеет тот же размер, что и probs
и для каждого ряда y
все это ноль, за исключением индекса столбца, который содержит правильный класс, который установлен в 1. Поэтому, если вы думаете об этом правильно, если вы сгенерировали матрицу y
где для каждой строки все столбцы равны нулю, за исключением номера класса, которому принадлежит пример, это эквивалентно простому доступу к правому столбцу для каждой строки и вычитанию балла на 1.
В MATLAB вам действительно нужно создать линейные индексы, чтобы облегчить это вычитание. В частности, вам нужно использовать sub2ind
чтобы преобразовать эти строки и столбцы в линейные индексы, мы можем получить доступ к матрице градиента и вычесть значения на 1.
Следовательно:
ind = sub2ind(size(delta3), 1 : num_examples, y + 1);
delta3(ind) = delta3(ind) - 1;
В уроке по Python, который вы связали, предполагается, что метки классов 0
вплоть до N-1
где N
общее количество классов. Вы должны быть осторожны в MATLAB, где мы начинаем индексировать массивы, начиная с 1
Итак, я добавил 1
в y
в приведенном выше коде, чтобы убедиться, что ваши ярлыки начинаются с 1
вместо 0
, ind
содержит линейные индексы местоположений строк и столбцов, к которым нам нужно получить доступ, и таким образом мы завершаем вычитание, используя эти индексы.
Если бы вы сформулировали это, используя знания, полученные от редактирования, вы бы сделали это вместо этого:
ymatrix = full(sparse(1 : num_examples, y + 1, 1, size(delta3, 1), size(delta3, 2));
delta3 = probs - ymatrix;
ymatrix
содержит матрицу, о которой я говорил, где каждая строка соответствует примеру со всеми нулями, кроме столбца, который относится к классу, к которому принадлежит пример, а именно 1. Что вы, возможно, не видели раньше, так это sparse
а также full
функции. sparse
позволяет создать нулевую матрицу, и вы можете указать ненулевые местоположения строк и столбцов, а также значения, принимаемые каждым из этих местоположений. В этом случае я точно получаю доступ к одному элементу в строке и использую идентификатор класса для примера, чтобы получить доступ к столбцам, и устанавливаю для каждого из этих местоположений значение 1. Также помните, что я добавляю на 1, поскольку я предполагаю, что ваш класс Идентификаторы начинаются с 0. Потому что это sparse
матрица, я затем преобразовать это в full
чтобы дать вам числовую матрицу, а не представлять ее в sparse
форма. Следовательно, этот код в действии эквивалентен предыдущему фрагменту кода, который я показал. Однако более эффективно сделать это первым способом, поскольку вы не создаете дополнительную матрицу для облегчения вычисления градиента. Вместо этого вы изменяете градиент на месте.
Как знак, sklearn
пакет машинного обучения Python для обучения NameError
указывает на то, что у вас не установлен фактический пакет. Чтобы установить его, используйте pip
или же easy_install
установить пакет Python на ваш компьютер.... так что в вашей командной строке это так же просто, как:
pip install sklearn
или же:
easy_install sklearn
Тем не менее, scikit-learn не требуется для запуска вышеуказанного кода вычитания. Тем не менее, вам нужен NumPy, поэтому убедитесь, что у вас установлен этот пакет.
За pip
:
pip install numpy
... и для easy_install
:
easy_install numpy