Сверточные нейронные сети для компьютерного зрения [0.2] Инструкция по использованию Python/Numpy

Оригинал инструкции был составлен Джастином Джонсоном.

Мы будем использовать язык программирования Python для всех заданий этого курса. Python это отличный универсальный язык программирования сам по себе, но с помощью некоторых популярных библиотек (numpy, scipy, matplotlib) он становиться мощным окружением для научных вычислений.

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

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

Вы также можете найти эту инструкцию в формате IPython notebook здесь созданную  Владимиром Кулешовым and Исааком Касвеллом для CS 228 и Google Сolaboratory версию созданную нами.

Python

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

Версии Python

На данный момент существует две различные поддерживаемые версии Python, 2.7 и 3.x. Несколько сбивает то, что Python 3.0 представил много обратно-несовместимых изменений в языке, поэтому код написанный для 2.7 может не работать на версии >3.5 и наоборот. Для этого занятия все строки кода написаны на Python 3.6.

Вы можете проверить свою версию Python, выполнив в командной строке: python —version.

Базовые типы данных

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

Числа

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

Заметьте, что в отличие от многих языков, Python не имеет унарных операторов инкремента (x++) и декремента(x—). 

Python также имеет встроенные типы для комплексных чисел; все детали вы можете найти в  документации.

Булевы (логические)

Python реализует все привычные операторы булевой логики, но использует английские слова вместо символов (&&, ||, и т.д..):

Строковые

Python имеет отличную поддержку для строковых значений:

Строковые объекты имеют массу полезных методов; например:

Вы можете найти список всех строковых методов в документации.

Контейнеры

Python включает несколько встроенных типов контейнеров: списки, словари, множества и кортежи.

Списки (List)

Список в Python используется, как массив, но он способен изменять свой размер и содержать элементы разных типов:

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

Срез: В дополнение к традиционному способу доступа к элементам списка по одному за раз, Python обеспечивает краткий синтаксис для доступа к подспискам; Это называется срез:

Как вы заметили, отрицательные индексы обозначают номер элемента с конца списка.

Мы еще встретимся со срезами в контексте массивов numpy.

Циклы: Вы можете перебирать элементы списка следующим образом:

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

Генератор списка (List comprehensions): Во время написания кода часто необходимо трансформировать один тип данных в другой. В качестве простого примера рассмотрим следующий код который вычисляет квадраты чисел:

Вы можете сделать этот код проще используя генератор списков:

Генераторы списков также могут содержать условия:

Словари

Словарь хранит пары (ключ, значение), он схож с Map в Java или Object в Javascript. Вы можете использовать его следующим образом:

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

Циклы: С их помощью легко проходить по всем ключам в словаре:

Если необходимо получить доступ к ключам и их соответствующим значениям, можно воспользоваться методом items:

Генератор словарей (Dictionary comprehensions): Схож  с генератором списков, но позволяет вам с легкостью создавать словари. К примеру:

Множества (Set)

Множество — это неупорядоченная коллекция определенных элементов. Простой пример множества приведен в коде ниже:

Всю необходимую информацию о множествах вы можете найти в документации.

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

Генератор множеств (Set comprehensions): Подобно Спискам и словарям, множества могут быть легко созданы с помощью генератора множеств:

Кортежи (Tuples)

Кортеж — это упорядоченный (неизменяемый) список  значений. Во многом кортеж похож на контейнер типа список; Одно из важнейших отличий кортежа от списка заключается в том, что элементы первого могут быть использованы в качестве ключей в словарях, а также являться элементами множества. Ниже приведен простейший пример:

В документации вы сможете найти более подробную информацию о кортежах.

Функции

В Python все функции определяются ключевым словом def. Пример:

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

Более подробную информацию о функциях в Python вы можете найти в документации.

Классы

Синтаксис определения класса выглядит следующим образом:

Подробнее о классах в Python вы можете узнать в документации.

Numpy

Numpy — это ключевая библиотека для научных вычислений в Python. Она реализует высокопроизводительные многомерные массивы и инструменты для работы с этими массивами. Если вы уже знакомы с MATLAB, то для начала работы с Numpy вам будет полезно ознакомиться с этим руководством.

Для использования Numpy необходимо импортировать модуль numpy. Традиционно (по соглашению) это делается следующим образом:

Массивы

Массивы в numpy представляют собой наборы значений одного типа, проиндексированные с помощью кортежа неотрицательных целых чисел. Количество измерений — это ранг массива; форма массива — это кортеж целых чисел задающих размер каждого измерения массива.

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

Numpy также предоставляет множество функций для создания массивов:

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

Индексирование массивов

Numpy предлагает несколько способов индексирования массивов.

Срез: Подобно спискам Python, для массивов numpy может быть получен срез. Поскольку массивы многомерны необходимо определять срез для каждого измерения:

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

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

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

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

Булевая индексация массивов: Логическое индексирование массива позволяет выбирать произвольные элементы массива. Часто этот тип индексирования используется для выбора элементов массива, удовлетворяющих некоторому условию. Ниже приведен пример:

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

Типы данных

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

Всю дополнительную информацию о типах данных вы можете найти в документации.

Математика массивов

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

Заметьте, что в отличие от  MATLAB, * — это поэлементное умножение, а не матричное. Для вычисления внутренних произведений векторов, умножения матриц и умножения векторов на матрицы, используется функция dot, доступная как в качестве модуля numpy, так и в качестве встроенного метода объектов типа массив:

Numpy предоставляет множество полезных функций для выполнения вычислений над массивами; одна из самых полезных это функция sum:

Полный список математических функций, предоставляемых  numpy, вы можете найти в документации.

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

Заметьте что попытка транспонировать массив 1 ранга ни к чему не приводит:

Numpy поддерживает гораздо больше функций для манипуляций с массивами; полный список вы можете посмотреть в документации.

Транслирование (Broadcasting)

Транслирование (Broadcasting) —  это мощный механизм, который позволяет numpy работать с массивами различных форм при выполнении арифметических операций. Часто имеется один малый и один большой массивы, и возникает необходимость использовать малый массив несколько раз, чтобы выполнить некоторые операции над большим массивом.

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

Это работает; однако когда матрица x очень большая, вычисления в явном цикле в Python может быть медленным. Заметьте, что добавление вектора v к каждой строке матрицы x, эквивалентно формированию матрицы vv путем укладки нескольких копий v вертикально, затем выполняется поэлементное сложение  x и vv. Мы можем применить данный подход следующим образом:

Транслирование numpy позволяет выполнять такие вычисления без создания дополнительных копий v. Рассмотрим версию, использующую broadcasting:

Строка y = x + v работает несмотря на то, что x имеет форму (4, 3), а v имеет форму (3,) благодаря транслированию. Причем работает так, как если бы v имел форму (4, 3), где каждая строка была бы копией v, а суммирование выполнялось поэлементно.

Транслирование двух массивов следует следующим правилам:

  1. Если массивы не имеют одинаковый ранг, дополняет форму массива низшего ранга единицами, пока обе формы не будут иметь одинаковую длину.
  2. Два массива считаются совместными в одном измерении, если они имеют одинаковый размер в этом измерении или если один из массивов имеет размер равный 1 в этом измерении.
  3. Массивы могут транслироваться вместе, если они совместны во всех измерениях.
  4. После транслирования каждый массив ведет себя так, как если бы он имел форму равную элементному максимуму форм двух входных массивов.
  5. В любом измерении, где один массив имеет размер равный 1, и другой имеет размер больший чем 1, первый массив ведет себя так, как если бы был скопирован на все измерение.

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

Функции, которые поддерживают транслирование называют  универсальными функциями. Список всех универсальных функций вы можете найти в документации.

Вот немного примеров применения транслирования:

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

Документация numpy

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

SciPy

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

Лучший способ познакомиться с SciPy это просмотреть в документации.

Файлы MATLAB

Функции scipy.io.loadmat и scipy.io.savemat позволяют читать и записывать MATLAB файлы. Вы можете прочитать о них в документации.

Расстояние между точками

SciPy определяет некоторые полезные функции для вычисления расстояний между наборами точек.

Функция scipy.spatial.distance.pdist вычисляет расстояние между всеми парами точек в заданном наборе:

Вы можете прочитать об этой функции более детально в документации.

Похожая функция (scipy.spatial.distance.cdist) вычисляет расстояние между всеми парами в двух наборах точек; Вы можете прочитать о ней в документации.

Matplotlib

Matplotlib — это библиотека построения графиков. В этом разделе дано краткое введение в модуль matplotlib.pyplot, который обеспечивает систему для построения графиков схожую той, что предоставляет MATLAB.

Построение графика

Важнейшая функция в matplotlib это — plot, которая позволяет создавать двумерные графики данных. Ниже приведен простой пример:

Выполнение кода выше, приводит к формированию следующего графика:

После небольшой доработки, мы легко сможем строить сразу несколько линий на одном графике, а также добавить заголовок, легенду, и названия осей:

Больше информации о функции plot вы сможете найти в документации.

Построение подграфиков (subplots)

С помощью функции subplot можно построить несколько графиков на одном. Ниже приведен пример:

Вы можете прочитать больше о функции subplot в документации.

Изображения

Чтобы показать изображения можно использовать функцию imshow. Ниже приведен пример:

Сверточные нейронные сети для компьютерного зрения [0.2] Инструкция по использованию Python/Numpy: 1 комментарий

  1. Уведомление: [0.1] Введение и установка | Digiratory

Добавить комментарий