На этом шаге мы рассмотрим создание и использование массивов.
Массивы - это не более чем таблицы значений, и они действительно оказываются очень кстати. Как и в случае таблиц, вы можете ссылаться на конкретные ячейки по номерам строк и столбцов. Наверное, вам известно, что именно таким способом можно ссылаться на ячейки в электронных таблицах (например, В1 или С5) и производить над ними вычисления (например, C3+D7).
Рис.1. Электронная таблица MSExcel
Когда дело дойдет до написания кода нашей нейронной сети, мы используем массивы для представления матриц входных сигналов, весовых коэффициентов и выходных сигналов. Но не только этих, а также матриц, представляющих сигналы внутри нейронной сети и их распространение в прямом направлении, и матриц, представляющих обратное распространение ошибок. Поэтому давайте познакомимся с массивами. Введите и выполните следующий код:
import numpy
Что делает этот код? Команда import сообщает Python о необходимости привлечения дополнительных вычислительных ресурсов из другого источника для расширения круга имеющихся инструментов.
В некоторых случаях эти дополнительные инструменты являются частью Python, но они не находятся в состоянии готовности к немедленному использованию, чтобы без надобности не отягощать Python. Чаще всего расширения не относятся к основному инструментарию Python, но создаются сторонними разработчиками в качестве вспомогательных ресурсов, доступных для всеобщего использования. В данном случае мы импортируем дополнительный набор инструментов, объединенных в единый модуль под названием numpy. Пакет numpy очень популярен и предоставляет ряд полезных средств, включая массивы и операции над ними.
Введите в следующей ячейке приведенный ниже код.
a = numpy.zeros([3, 2]) print(a)
В этом коде импортированный модуль numpy используется для создания массива размерностью 3x2, во всех ячейках которого содержатся нулевые значения. Мы сохраняем весь массив в переменной а, после чего выводим ее на экран. Результат подтверждает, что массив действительно состоит из нулей, хранящихся в виде таблицы с тремя строками и двумя столбцами.
Рис.2. Созданный массив
А теперь модифицируем содержимое этого массива и заменим некоторые из его нулей другими значениями. В приведенном ниже коде показано, как сослаться на конкретные ячейки для того, чтобы заменить хранящиеся в них значения новыми. Это напоминает обращение к нужным ячейкам электронной таблицы.
а[0, 0] = 1 а[0, 1] = 2 а[1, 0] = 9 а[2, 1] = 12 print(а)
Первая строка обновляет ячейку, находящуюся в строке 0 и столбце 0, заменяя все, что в ней до этого хранилось, значением 1. В остальных строках другие ячейки аналогичным образом обновляются, а последняя строка выводит массив на экран с помощью инструкции print(а). На приведенной ниже иллюстрации показано, что собой представляет массив после всех изменений.
Рис.3. Измененный массив
Теперь, когда вам известно, как присваивать значения элементам массива, вас, вероятно, интересует, каким образом можно узнать значение отдельного элемента, не выводя на экран весь массив? Это делается очень просто. Чтобы сослаться на содержимое ячейки массива, которое мы хотим вывести на экран или присвоить другой переменной, достаточно воспользоваться выражением наподобие а[0, 1] или а[1, 0]. Именно это демонстрирует приведенный ниже фрагмент кода.
print(a[0, 1]) v = a[1, 0] print(v)
Запустив этот пример, вы увидите, что первая инструкция print выводит значение 2,0, т.е. содержимое ячейки [0,1]. Следующая инструкция присваивает значение элемента массива а[1, 0] переменной v и выводит значение этой переменной. Как и ожидалось, выводится значение 9,0.
Рис.4. Присваивание переменным значений элементов массива
Нумерация столбцов и строк начинается с 0, а не с 1. Верхний левый элемент обозначается как [0, 0], а не как [1, 1]. Отсюда следует, что правому нижнему элементу соответствует обозначение [2, 1], а не [3, 2]. Если мы попытаемся, к примеру, обратиться к элементу массива а[0, 2], то получим сообщение об ошибке.
Рис.5. Неправильное значение индекса
Массивы, или матрицы, пригодятся нам для нейронных сетей, поскольку позволят упростить инструкции при выполнении интенсивных вычислений, связанных с распространением сигналов и обратным распространением ошибок в сети, что обсуждалось в первом разделе.
На следующем шаге мы рассмотрим графическое представление массивов.