Сверточные нейронные сети (CNN) - это глубокие искусственные нейронные сети, которые используются в первую очередь для классификации изображений, их группировки по сходству и распознавания объектов.
Существует множество различных руководств, в которых показано, как реализовать вашу собственную модель CNN с использованием различных нейросетевых библиотек (Keras, TensorFlow, PyTorch и т. Д.) С вашей собственной сетевой архитектурой. Однако нет исчерпывающего объяснения того, что происходит внутри сети и ее скрытых слоев.
В этом уроке я хотел бы показать, как легко визуализировать и управлять глубокими скрытыми слоями CNN и как их анализировать с помощью нейронных сетей ConX.
Распознавание изображений с помощью CNN и дальнейший анализ
В этом уроке я буду:
- Постройте модель CNN
- Модель поезда на наборе данных STL-10
- Визуализируйте сетевую архитектуру и вывод скрытых слоев
Как я уже упоминал, я буду использовать модуль ConX для Python3, который можно легко установить с помощью команды pip.
Что такое ConX?
ConX - это доступный и мощный способ создания и понимания нейронных сетей глубокого обучения. Он разработан на Python 3 и Keras 2.
Зайдите в свой терминал и введите:
pip install conx
Начиная
Импортировать пакеты
import numpy as np import tensorflow as tf import conx as cx
Импортировать набор данных
Для этой статьи вы можете использовать хороший пакет STL-10 Utils, который содержит все методы для загрузки и чтения данных, а также тестовую основную функцию для отображения изображения.
# url of the binary data DATA_URL=‘http://ai.stanford.edu/~acoates/stl10/stl10_binary.tar.gz' # path to the binary train file with image data DATA_PATH = ‘./data/stl10_binary/train_X.bin’ # path to the binary train file with labels LABEL_PATH = ‘./data/stl10_binary/train_y.bin’ # test to check if the whole dataset is read correctly images = read_all_images(DATA_PATH) labels = read_labels(LABEL_PATH) print('Image shape: ', images.shape) print('Labels shape: ', labels.shape) Image shape: (5000, 96, 96, 3) Labels shape: (5000,)
Таким образом, набор данных содержит 5000 изображений (96 x 96 пикселей и 3 цветовых каналов) с ярлыками, принадлежащими один из следующих 10 классов: самолет, птица, машина, кошка, олень, собака, лошадь, обезьяна, корабль, грузовик.
Предварительная обработка данных
Поскольку я хочу построить и проанализировать CNN с помощью модуля ConX, в первую очередь я подготовлю данные для сетевого ввода и вывода. В этом случае входом сети является изображение формы 96x96x3, а на выходе - горячий вектор формы 10x1, имеющий 1 на месте метки.
target = [] labels_array = np.zeros(10, dtype=int) for label in labels: labels_array[label-1] = 1 target.append(labels_array) labels_array = np.zeros(10, dtype=int)
Давайте проверим изображение и цель для первого элемента в наборе данных:
plot_image(images[0]) print('Target: ', target[0])
Target: [0 1 0 0 0 0 0 0 0 0]
Теперь, когда мы знаем, как выглядят входы и цели, мы можем построить сетевую модель.
Модель CNN
Назначение сети
Первым делом я создаю сеть с ее названием:
net = cx.Network(‘STL-10ImageClasses’) net.dataset.clear()
Создайте набор данных
Затем я могу загрузить набор данных в формате (изображение, цель) (строка 4 следующего кода). Позже он будет использоваться для обучения и тестирования модели CCN. Я использую только 1000 записей, чтобы ускорить процесс обучения, если хотите, можете использовать все 5000 изображений.
for i in range(0, 1000): inputs = images[i] targets = target[i] net.dataset.append(inputs, targets)
Затем я могу проверить информацию о сети, чтобы убедиться, что набор данных загружен правильно:
net.dataset.info()
Исследование набора данных
Также возможно изучить набор данных с помощью некоторых методов ConX:
- просмотрите первое изображение в наборе данных:
cx.view(net.dataset.inputs[0])
- просмотрите первые десять изображений в наборе данных:
cx.view(net.dataset.inputs[0:10], layout=(1,10))
- просматривать только изображения «птиц» в наборе данных:
bird = [i for i in range(40) if net.dataset.targets[i][1] == 1] cx.view([cx.array_to_image(v) for v in net.dataset.inputs[bird]])
Определение наборов данных для обучения и тестирования
В качестве хорошей практики я разделю набор данных на обучение и тестирование, чтобы построить и протестировать модель на разных данных:
net.dataset.split(300) net.dataset.split() (700, 300)
Теперь у меня есть прямой доступ к обоим наборам данных:
print(len(net.dataset.inputs), 'total images') print(len(net.dataset.train_inputs), 'images for training') print(len(net.dataset.test_inputs), 'images for testing') 1000 total images 700 images for training 300 images for testing
Конструкция модели
Теперь я готов добавить слои в свою модель CCN. Существует несколько правил построения и компиляции сети. Все слои в сети имеют свои имена. Название слоя связано с его функциональностью. Также важно отметить, что каждая сеть должна иметь «входной» и «выходной» слой с определенными характеристиками размера.
Модуль conx.layers содержит код всех слоев. Чтобы добавить слои в модель, мы можем просто вызвать метод add.
Сначала я добавляю слой ввода с произвольным именем «input», где указываю размер изображения:
net.add(cx.Layer("input", (96,96,3)))
Теперь я построю простую модель CCN, которая содержит два сверточных слоя, за которыми следуют слой объединения, плоский слой и три скрытых слоя (включая один выходной слой).
После входного слоя должен быть добавлен сверточный слой. Это делается в третьей строке следующего кода; инструкция conx.layers.Conv2DLayer (name, * args, ** params) добавляет сверточный слой. Здесь можно указать количество фильтров, размер ядра, шаги, стороны заполнения и функцию активации.
net.add(cx.Conv2DLayer(“conv2D_1”, 32, (5,5), strides=1, padding=’same’, activation=”relu”), cx.Conv2DLayer(“conv2D_2”, 32, (5,5), strides=1, padding=’same’, activation=”relu”))
Для обоих слоев я использовал:
- название: ‘conv2D_1’ (или conv2D_2)
- фильтр, размерность выходного пространства: 32
- размер_ядра: (5, 5)
- шагов: 1
- отступ: такой же
- функция активации: relu
Давайте теперь добавим слой объединения:
net.add(cx.MaxPool2DLayer("maxpool_1", (2,2), strides=2, padding='same', dropout=0.25))
Я указал для слоя:
- name: ‘maxpool_1’
- pool_size: (2, 2)
- шагов: 2
- отступ: такой же
- выпадение (доля единиц, которые нужно отбросить при линейном преобразовании входных данных): 0,25
В конце добавляется сплющенный слой. Этот вид слоя не требует никаких параметров:
net.add(cx.FlattenLayer("flat"))
Последние три скрытых слоя добавляются к сети для постепенного уменьшения размера изображения:
net.add(cx.Layer("hidden", 512, activation='relu', vshape=(16, 32), dropout=0.5), cx.Layer("hidden2", 50, activation='relu', vshape=(10, 5), dropout=0.5), cx.Layer("output", 10, activation='softmax'))
- размер: 512 (это потому, что 16 x 32 = 512)
- vshape: (16, 32) (визуальная форма, как будет представлен слой)
- функция активации: relu
Все слои добавляются по порядку; таким образом, все они должны быть связаны вместе.
net.connect()
Одна из самых мощных возможностей ConX - это визуализация. Таким образом, построенную сеть можно представить:
net.picture()
Начиная снизу, мы можем наблюдать за всеми добавленными слоями: input, conv2D_1, conv2D_2, maxpool_1, flat, hidden, hidden2, output.
Когда сеть спроектирована, следующим шагом является ее компиляция:
net.compile(error='categorical_crossentropy', optimizer='rmsprop', lr=0.0001, decay=1e-6)
- функция потерь: «категориальная_ кроссентропия» (требуется при использовании softmax в качестве функции активации выходного слоя)
Визуализация сети
Теперь сеть готова к обучению:
net.train(100, batch_size=100, record=1)
- эпоха: 100
- batch_size: 100
ConX позволяет нам отслеживать этап обучения. Здесь после 100 эпох точность прогноза составляет 11%. Однако я хочу подчеркнуть, что 100 эпох обычно недостаточно для обучения модели CCN решению задачи мультиклассовой классификации.
Основное преимущество, которое дает ConX, - это поддержка визуализации и анализа нейронных сетей. Используя метод панели мониторинга, можно проанализировать все слои.
net.dashboard()
Используя приборную панель, каждое изображение можно распространять, и мы можем исследовать, как сеть узнала особенности различных объектов. Можно изучить, что произошло на каждом слое и как определенная метка была присвоена изображению.
В конце я хотел бы упомянуть, что ConX дает возможность производить распространение по функциям, поэтому каждую функцию можно изучать отдельно от других.
net.propagate_to_features(“conv2D_1”, net.dataset.inputs[1], scale=2)
В ConX доступно множество других полезных методов; вы можете найти их все на официальной странице сайта: Начало работы с ConX.