Главная страница
Навигация по странице:

  • Использование примеров кода

  • Математическое представление

  • Рис. 1.2.

  • Примечание № 1. NumPy Библиотека NumPy для Python содержит реализации вычислительных алгоритмов, по большей части написанные на языке C и оптимизиро- Функции 19

  • Простые функции в библиотеке NumPy

  • Курсовая работа. Глубокое обучение


    Скачать 4.97 Mb.
    НазваниеГлубокое обучение
    АнкорКурсовая работа
    Дата26.06.2022
    Размер4.97 Mb.
    Формат файлаpdf
    Имя файлаVeydman_S_Glubokoe_obuchenie_Legkaya_razrabotka_proektov_na_Pyth.pdf
    ТипДокументы
    #615357
    страница2 из 22
    1   2   3   4   5   6   7   8   9   ...   22
    12
    Предисловие возможности пошагового подхода для определения моделей глубо- кого обучения. И тут на сцену выходит глава 3.
    3. В главе 3 мы возьмем строительные блоки из подхода «сначала суть» из первых двух глав и используем их для построения компонентов более высокого уровня, которые составляют все модели глубокого обучения: слои, модели, оптимизаторы и т. д. Мы закончим эту главу обучением модели глубокого обучения, заданной с нуля, на наборе данных из главы 2 и покажем, что она работает лучше, чем простая нейронная сеть.
    4. Как выясняется, существует несколько теоретических предпосылок того, что нейронная сеть с заданной архитектурой действительно найдет хорошее решение для данного набора данных при обучении с использованием стандартных методов обучения, которые мы будем использовать в этой книге. В главе 4 мы поговорим о хитростях, при- меняемых в процессе обучения, которые обычно увеличивают веро- ятность того, что нейронная сеть найдет хорошее решение, и по воз- можности дадим математическое описание, почему они работают.
    5. В главе 5 мы обсудим фундаментальные идеи, лежащие в основе сверточных нейронных сетей (CNN), разновидности архитектуры нейронных сетей, специализирующихся на распознавании изобра- жений. Существует множество объяснений принципов работы CNN, поэтому я сосредоточусь на самых основных понятиях о CNN и их отличиях от обычных нейронных сетей: в частности, как CNN делают так, что каждый слой нейронов превращается в «карты признаков», и как два из этих слоев (каждый из которых состоит из нескольких карт объектов) связываются друг с другом посредством сверточных фильтров. Кроме того, что мы будем писать обычные слои в нейрон- ной сети с нуля, а также сверточные слои с нуля, чтобы укрепить понимание того, как они работают.
    6. В первых пяти главах мы создадим миниатюрную библиотеку ней- ронных сетей, которая определяет нейронные сети как серию слоев, которые сами состоят из серии операций, которые передают вход- ные данные вперед и градиенты назад. Но большинство нейронных сетей реализуются на практике не так. Вместо этого используется техника, называемая автоматическим дифференцированием. Я при- веду краткий обзор автоматического дифференцирования в начале главы 6 и далее использую его для основной темы главы: рекур-

    Условные обозначения
    13
    рентных нейронных сетей (RNN), архитектуры нейронных сетей, обычно используемых для анализа данных, в которых точки данных появляются последовательно, например временнˆых данных или естественного языка. Я объясню работу «классических RNN» и двух вариантов: GRU и LSTM (и конечно, мы реализуем все их с нуля).
    Далее мы опишем элементы, которые являются общими для всех этих вариантов RNN, и некоторые различия между этими вариантами.
    7. В заключение, в главе 7, я покажу, как все, что мы делали с нуля в главах 1–6, может быть реализовано с использованием высокопро- изводительной библиотеки с открытым исходным кодом PyTorch.
    Изучение такой структуры очень важно для развития вашего знания нейронных сетей; но погружение и изучение структуры без пред- варительного понимания того, как и почему работают нейронные сети, серьезно ограничит ваше обучение в долгосрочной перспекти- ве. Цель такого порядка глав в этой книге — дать вам возможность писать чрезвычайно высокопроизводительные нейронные сети
    (с помощью PyTorch), настраивая при этом вас на долгосрочное об- учение и успех (через изучение основ). В конце мы приведем крат- кую иллюстрацию того, как нейронные сети могут использоваться для обучения без учителя.
    Моя идея состояла в том, чтобы написать книгу, которую я сам бы хотел почитать, когда только начинал изучать эту тему несколько лет назад.
    Надеюсь, книга будем вам полезна. Вперед!
    Условные обозначения
    В книге используются следующие типографские обозначения:
    Курсив
    Используется для обозначения новых терминов.
    Моноширинный шрифт
    Применяется для оформления листингов программ и программных элементов внутри обычного текста, таких как имена переменных и функций, баз данных, типов данных, переменных среды, операторов и ключевых слов.

    14
    Предисловие
    Моноширинный
    жирный
    Обозначает команды или другой текст, который должен вводиться пользователем.
    Моноширинный
    курсив
    Обозначает текст, который должен замещаться фактическими значе- ниями, вводимыми пользователем или определяемыми из контекста.
    Теорема Пифагора: a
    2
    + b
    2
    = c
    2
    Так обозначаются советы, предложения и примечания общего ха- рактера.
    Использование примеров кода
    Дополнительный материал (примеры кода, упражнения и т. д.) можно скачать по адресу репозитория книги на GitHub по адресу oreil.ly/deep- learning-github
    Благодарности
    Благодарю своего редактора Мелиссу Поттер вместе с командой из
    O'Reilly, которые были внимательны и отвечали на мои вопросы на про- тяжении всего процесса.
    Выражаю особую благодарность нескольким людям, чья работа по созданию технических концепций в области машинного обучения, до- ступная для более широкой аудитории, вдохновила меня, и тем, кого мне посчастливилось узнать лично: это, в частности, Брэндон Рорер, Джоэл
    Грус, Джереми Уотт и Эндрю Траск.
    Благодарю своего босса в Metis и директора в Facebook, которые под- держивали меня, когда я пытался выкроить время на работу над этим проектом.
    Благодарю Мэта Леонарда, который недолгое время был моим соавтором, после чего наши пути разошлись. Мэт помог организовать код в мини-

    От издательства
    15
    малистичном стиле — lincoln — и дал очень полезную обратную связь по поводу сырых вариантов первых двух глав, написав свои собственные версии больших разделов этих глав.
    Наконец, благодарю своих друзей Еву и Джона, которые вдохновили меня на решительный шаг и фактически заставили меня начать писать. Я также хотел бы поблагодарить моих многочисленных друзей в Сан-Франциско, которые терпели мое волнение, переживали вместе со мной по поводу книги и оказывали всяческую поддержку, хотя в течение многих месяцев я не мог найти время потусоваться с ними.
    От издательства
    Некоторые иллюстрации снабжены QR-кодом. Перейдя по ссылке, вы сможете посмотреть их цветную версию.
    Ваши замечания, предложения, вопросы отправляйте по адресу comp@
    piter.com
    (издательство «Питер», компьютерная редакция).
    Мы будем рады узнать ваше мнение!
    На веб-сайте издательства www.piter.com вы найдете подробную информа- цию о наших книгах.

    ГЛАВА 1
    Математическая база
    Не нужно запоминать эти формулы. Если вы поймете прин- ципы, по которым они строятся, то сможете придумать соб- ственную систему обозначений.
    Джон Кохран, методическое пособие
    Investments Notes, 2006
    В этой главе будет заложен фундамент для понимания работы нейронных сетей — вложенные математические функции и их производные. Мы пройдем весь путь от простейших строительных блоков до «цепочек» со- ставных функций, вплоть до функции многих переменных, внутри которой происходит умножение матриц. Умение находить частные производные таких функций поможет вам понять принципы работы нейронных сетей, речь о которых пойдет в следующей главе.
    Каждую концепцию мы будем рассматривать с трех сторон:
    y математическое представление в виде формулы или набора урав- нений;
    y код, по возможности содержащий минимальное количество до- полнительного синтаксиса (для этой цели идеально подходит язык
    Python);
    y рисунок или схема, иллюстрирующие происходящий процесс.
    Благодаря такому подходу мы сможем исчерпывающе понять, как и по- чему работают вложенные математические функции. С моей точки зрения, любая попытка объяснить, из чего состоят нейронные сети, не раскрывая все три аспекта, будет неудачной.
    И начнем мы с такой простой, но очень важной математической концеп- ции, как функция.

    Функции
    17
    Функции
    Как описать, что такое функция? Разумеется, я мог бы ограничиться фор- мальным определением, но давайте рассмотрим эту концепцию с разных сторон, как ощупывающие слона слепцы из притчи.
    Математическое представление
    Вот два примера функций в математической форме записи: y
    y
    Записи означают, что функция f
    1
    преобразует входное значение x в x
    2
    , а функция f
    2
    возвращает наибольшее значение из набора (x, 0).
    Визуализация
    Вот еще один способ представления функций:
    1. Нарисовать плоскость xy (где x соответствует горизонтальной оси, а y — вертикальной).
    2. Нарисовать на этой плоскости набор точек, x-координаты которых
    (обычно равномерно распределенные) соответствуют входным зна- чениям функции, а y-координаты — ее выходным значениям.
    3. Соединить эти точки друг с другом.
    Французский философ и математик Рене Декарт первым использовал подобное представление, и его начали активно применять во многих областях математики, в частности в математическом анализе. Пример графиков функций показан на рис. 1.1.
    Есть и другой способ графического представления функций, который почти не используется в матанализе, но удобен, когда речь заходит о мо- делях глубокого обучения. Функцию можно сравнить с черным ящиком, который принимает значение на вход, преобразует его внутри по каким- то правилам и возвращает новое значение. На рис. 1.2 показаны две уже знакомые нам функции как в общем виде, так и для отдельных входных значений.

    18
    Глава 1. Математическая база
    Квадратичная функция
    Активационная функция ReLU
    Входные данные
    Входные данные
    Вы хо дные данны е
    Вы хо дные данны е
    Рис. 1.1. Две непрерывные дифференцируемые функции
    Квадра- тичная n
    n
    2
    ReLU
    x max(x, 0)
    2 4
    ReLU
    2 2
    -3 9
    ReLU
    -3 0
    Квадра- тичная
    Квадра- тичная
    Определение
    Рис. 1.2. Другой способ представления тех же функций
    Код
    Наконец, можно описать наши функции с помощью программного кода.
    Но для начала я скажу пару слов о библиотеке NumPy, которой мы вос- пользуемся.
    Примечание № 1. NumPy
    Библиотека NumPy для Python содержит реализации вычислительных алгоритмов, по большей части написанные на языке C и оптимизиро-

    Функции
    19
    ванные для работы с многомерными массивами. Данные, с которыми работают нейронные сети, всегда хранятся в многомерных массивах, чаще всего в дву- или трехмерных. Объекты ndarray из библиотеки NumPy дают возможность интуитивно и быстро работать с этими массивами. Напри- мер, если сохранить данные в виде обычного или многомерного списка, обычный синтаксис языка Python не позволит выполнить поэлементное сложение или умножение списков, зато эти операции прекрасно реали- зуются с помощью объектов ndarray
    :
    print("операции со списками на языке Python:")
    a = [1,2,3]
    b = [4,5,6]
    print("a+b:", a+b)
    try:
    print(a*b)
    except TypeError:
    print("a*b не имеет смысла для списков в языке Python")
    print()
    print("операции с массивами из библиотеки numpy:")
    a = np.array([1,2,3])
    b = np.array([4,5,6])
    print("a+b:", a+b)
    print("a*b:", a*b)
    операции со списками на языке Python:
    a+b: [1, 2, 3, 4, 5, 6]
    a*b не имеет смысла для списков в языке Python операции с массивами из библиотеки numpy:
    a+b: [5 7 9]
    a*b: [ 4 10 18]
    Объект ndarray обладает и таким важным для работы с многомерными массивами атрибутом, как количество измерений. Измерения еще на- зывают осями. Их нумерация начинается с 0, соответственно первая ось будет иметь индекс 0, вторая — 1 и т. д. В частном случае двумерного массива нулевую ось можно сопоставить строкам, а первую — столбцам, как показано на рис. 1.3.
    Эти объекты позволяют интуитивно понятным способом совершать различные операции с элементами осей. Например, суммирование строки или столбца двумерного массива приводит к «свертке» вдоль

    20
    Глава 1. Математическая база соответствующей оси, возвращая массив на одно измерение меньше исходного:
    print('a:')
    print(a)
    print('a.sum(axis=0):', a.sum(axis=0))
    print('a.sum(axis=1):', a.sum(axis=1))
    a:
    [[1 2]
    [3 4]]
    a.sum(axis=0): [4 6]
    a.sum(axis=1): [3 7]
    Ось 1
    Ось 0
    Рис. 1.3. Двумерный массив из библиотеки NumPy, в котором ось с индексом 0 соответствует строкам, а ось с индексом 1 — столбцам
    Наконец, объект ndarray поддерживает такую операцию, как сложение с одномерным массивом. Например, к двумерному массиву a, состоящему из R строк и C столбцов, можно прибавить одномерный массив b дли- ной C, и библиотека NumPy выполнит сложение для элементов каждой строки массива a
    1
    :
    a = np.array([[1,2,3],
    [4,5,6]])
    b = np.array([10,20,30])
    print("a+b:\n", a+b)
    a+b:
    [[11 22 33]
    [14 25 36]]
    1
    Позднее это позволит нам легко добавлять смещение к результатам умножения матриц.

    Функции
    21
    Примечание № 2. Функции с аннотациями типов
    Как я уже упоминал, код в этой книге приводится как дополнительная иллюстрация, позволяющая более наглядно представить объясняемые концепции. Постепенно эта задача будет усложняться, так как функции с несколькими аргументами придется писать как часть сложных клас- сов. Для повышения информативности такого кода мы будем добавлять в определение функций аннотации типов; например, в главе 3 нейронные сети будут инициализироваться вот так:
    def __init__(self, layers: List[Layer], loss: Loss, learning_rate: float = 0.01) -> None:
    Такое определение сразу дает представление о назначении класса. Вот для сравнения функция operation
    :
    def operation(x1, x2):
    Чтобы понять назначение этой функции, потребуется вывести тип каждо- го объекта и посмотреть, какие операции с ними выполняются. А теперь переопределим эту функцию следующим образом:
    def operation(x1: ndarray, x2: ndarray) -> ndarray:
    Сразу понятно, что функция берет два объекта ndarray
    , вероятно, каким-то способом комбинирует и выводит результат этой комбинации. В дальней- шем мы будем снабжать аннотациями типов все определения функций.
    Простые функции в библиотеке NumPy
    Теперь мы готовы написать код определенных нами функций средствами библиотеки NumPy:
    def square(x: ndarray) -> ndarray:
    '''
    Возведение в квадрат каждого элемента объекта ndarray.
    '''
    return np.power(x, 2)
    def leaky_relu(x: ndarray) -> ndarray:
    '''
    Применение функции "Leaky ReLU" к каждому элементу ndarray.
    '''
    return np.maximum(0.2 * x, x)

    22
    Глава 1. Математическая база
    Библиотека NumPy позволяет применять многие функции к объ- ектам ndarray двумя способами: np.function_name
    (ndarray)
    или ndarray.function_name
    . Например, функцию relu можно было на- писать как x.clip
    (min
    =
    0)
    . В дальнейшем мы будем пользоваться записью вида np.function_name
    (ndarray)
    . И даже когда альтерна- тивная запись короче, как, например, в случае транспонирования двумерного объекта ndarray
    , мы будем писать не ndarray.T
    , а np.
    trans pose
    (ndarray,
    (
    1,
    0))
    Постепенно вы привыкнете к трем способам представления концепций, и это поможет по-настоящему понять, как происходит глубокое обучение.
    Производные
    Понятие производной функции, скорее всего, многим из вас уже знако- мо. Производную можно определить как скорость изменения функции в рассматриваемой точке. Мы подробно рассмотрим это понятие с разных сторон.
    Математическое представление
    Математически производная определяется как предел отношения прира- щения функции к приращению ее аргумента при стремлении приращения аргумента к нулю:
    Можно численно оценить этот предел, присвоив переменной
    Δ маленькое значение, например 0.001:
    Теперь посмотрим на графическое представление нашей производной.

    Производные
    23
    Визуализация
    Начнем с общеизвестного способа: если нарисовать касательную к де- картову представлению функции f, производная функции в точке каса- ния будет равна угловому коэффициенту касательной. Вычислить этот коэффициент, или тангенс угла наклона прямой, можно, взяв разность значений функции f при a – 0.001 и a + 0.001 и поделив на величину при- ращения, как показано на рис. 1.4.
    a a + 0.001
    f(a + 0.001)
    f(a – 0.001)
    f(a)
    a – 0.001
    Наклон =
    f(a + 0.001) – f(a – 0.001)
    (0.002)
    Рис. 1.4. Производная как угловой коэффициент
    На рисунке производную можно представить в виде множителя, кратно которому меняется выходное значение функции при небольшом изме- нении подаваемого на вход значения. Фактически мы меняем значение входного параметра на очень маленькую величину и смотрим, как при этом поменялось значение на выходе. Схематично это представлено на рис. 1.5.
    Квадрат.
    функция
    2 0.001 4
    ?
    Рис. 1.5. Альтернативный способ визуализации концепции производной
    Со временем вы увидите, что для понимания глубокого обучения второе представление оказывается важнее первого.

    24
    Глава 1. Математическая база
    Код
    И наконец, код для вычисления приблизительного значения производной:
    from typing import Callable def deriv(func: Callable[[ndarray], ndarray], input_: ndarray, delta: float = 0.001) -> ndarray:
    '''
    Вычисление производной функции "func" в каждом элементе массива "input_".
    '''
    return (func(input_ + delta) — func(input_ — delta)) / (2 * delta)
    Выражение «P — это функция E» (я намеренно использую тут случай- ные символы) означает, что некая функция f берет объекты E и пре- вращает в объекты P, как показано на рисунке. Другими словами,
    P — это результат применения функции f к объектам E:
    f
    E
    P
    А вот так выглядит соответствующий код:
    def f(input_: ndarray) -> ndarray:
    # Какое-то преобразование return output
    P = f(E)
    Вложенные функции
    Вот мы и дошли до концепции, которая станет фундаментом для пони- мания нейронных сетей. Это вложенные, или составные, функции. Дело в том, что две функции f
    1
    и f
    2
    можно связать друг с другом таким образом, что выходные данные одной функции станут входными для другой.
    1   2   3   4   5   6   7   8   9   ...   22


    написать администратору сайта