Создавайте свертки и выполняйте объединение

1. Прежде чем начать

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

В предыдущей кодовой лаборатории вы создали простую глубокую нейронную сеть (DNN) для компьютерного зрения на модные предметы. Это было ограничено, потому что требовалось, чтобы предмет одежды был единственным на картинке, и он должен был быть в центре.

Конечно, это не реальный сценарий. Вам нужно, чтобы ваш DNN мог идентифицировать предмет одежды на изображениях с другими объектами или там, где он не расположен спереди и по центру. Для этого вам нужно использовать свертки.

Предпосылки

Эта лаборатория кода основана на работе, выполненной в двух предыдущих частях: «Привет, мир» машинного обучения и « Создание модели компьютерного зрения» . Пожалуйста, завершите эти кодовые лаборатории, прежде чем продолжить.

Что вы узнаете

  • Что такое свертки
  • Как создать карту объектов
  • Что такое объединение

Что вы будете строить

  • Карта характеристик изображения

Что вам понадобится

Вы можете найти код остальной кодлабы , работающей в Colab .

Вам также потребуется установленный TensorFlow и библиотеки, которые вы установили в предыдущей лаборатории кода.

2. Что такое свертки?

Свертка — это фильтр, который проходит через изображение, обрабатывает его и извлекает важные функции.

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

Процесс картирования объектов теоретически прост. Вы будете сканировать каждый пиксель изображения, а затем смотреть на соседние с ним пиксели. Вы умножаете значения этих пикселей на эквивалентные веса в фильтре.

Например:

Свертка на изображении

В этом случае указывается матрица свертки 3x3, или ядро ​​изображения.

Текущее значение пикселя — 192. Вы можете рассчитать значение нового пикселя, просмотрев соседние значения, умножив их на значения, указанные в фильтре, и сделав новое значение пикселя окончательным значением.

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

Вы продемонстрируете это на изображении восхождения из SciPy . Это красивая встроенная картинка с большим количеством ракурсов и линий.

3. Начните программировать

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

import cv2
import numpy as np
from scipy import misc
i = misc.ascent()

Затем используйте библиотеку matplotlib , чтобы нарисовать изображение, чтобы вы знали, как оно выглядит:

import matplotlib.pyplot as plt
plt.grid(False)
plt.gray()
plt.axis('off')
plt.imshow(i)
plt.show()

edb460dd5397f7f4.png

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

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

i_transformed = np.copy(i)
size_x = i_transformed.shape[0]
size_y = i_transformed.shape[1]

4. Создайте матрицу свертки

Сначала создайте матрицу свертки (или ядро) в виде массива 3x3:

# This filter detects edges nicely
# It creates a filter that only passes through sharp edges and straight lines. 
# Experiment with different values for fun effects.
#filter = [ [0, 1, 0], [1, -4, 1], [0, 1, 0]] 
# A couple more filters to try for fun!
filter = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]
#filter = [ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]
 # If all the digits in the filter don't add up to 0 or 1, you 
# should probably do a weight to get it to do so
# so, for example, if your weights are 1,1,1 1,2,1 1,1,1
# They add up to 10, so you would set a weight of .1 if you want to normalize them
weight  = 1

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

Это означает, что сосед текущего пикселя над ним и слева от него будет умножен на верхний левый элемент в фильтре. Затем умножьте результат на вес и убедитесь, что результат находится в диапазоне от 0 до 255.

Наконец, загрузите новое значение в преобразованное изображение:

for x in range(1,size_x-1):
  for y in range(1,size_y-1):
      output_pixel = 0.0
      output_pixel = output_pixel + (i[x - 1, y-1] * filter[0][0])
      output_pixel = output_pixel + (i[x, y-1] * filter[0][1])
      output_pixel = output_pixel + (i[x + 1, y-1] * filter[0][2])
      output_pixel = output_pixel + (i[x-1, y] * filter[1][0])
      output_pixel = output_pixel + (i[x, y] * filter[1][1])
      output_pixel = output_pixel + (i[x+1, y] * filter[1][2])
      output_pixel = output_pixel + (i[x-1, y+1] * filter[2][0])
      output_pixel = output_pixel + (i[x, y+1] * filter[2][1])
      output_pixel = output_pixel + (i[x+1, y+1] * filter[2][2])
      output_pixel = output_pixel * weight
      if(output_pixel<0):
        output_pixel=0
      if(output_pixel>255):
        output_pixel=255
      i_transformed[x, y] = output_pixel

5. Изучите результаты

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

# Plot the image. Note the size of the axes -- they are 512 by 512
plt.gray()
plt.grid(False)
plt.imshow(i_transformed)
#plt.axis('off')
plt.show()   

48ff667b2df812ad.png

Рассмотрите следующие значения фильтров и их влияние на изображение.

Использование [-1,0,1,-2,0,2,-1,0,1] дает очень сильный набор вертикальных линий:

Обнаружение фильтра вертикальных линий

Использование [-1,-2,-1,0,0,0,1,2,1] дает вам горизонтальные линии:

Обнаружение горизонтальных линий

Исследуйте разные ценности! Кроме того, попробуйте фильтры разного размера, например 5x5 или 7x7.

6. Понимание объединения

Теперь, когда вы определили основные черты изображения, что вы делаете? Как вы используете полученную карту признаков для классификации изображений?

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

Существует несколько различных типов объединения, но вы будете использовать тот, который называется максимальным (максимальным) объединением.

Проведите итерацию по изображению и в каждой точке рассмотрите пиксель и его непосредственных соседей справа, снизу и справа внизу. Возьмите самый большой из них (отсюда максимальный пул) и загрузите его в новый образ. Таким образом, новое изображение будет в четыре раза меньше старого. Максимальное объединение

7. Напишите код для объединения

Следующий код покажет пул (2, 2). Запустите его, чтобы увидеть результат.

Вы увидите, что хотя изображение в четыре раза меньше оригинала, оно сохранило все функции.

new_x = int(size_x/2)
new_y = int(size_y/2)
newImage = np.zeros((new_x, new_y))
for x in range(0, size_x, 2):
  for y in range(0, size_y, 2):
    pixels = []
    pixels.append(i_transformed[x, y])
    pixels.append(i_transformed[x+1, y])
    pixels.append(i_transformed[x, y+1])
    pixels.append(i_transformed[x+1, y+1])
    pixels.sort(reverse=True)
    newImage[int(x/2),int(y/2)] = pixels[0]
 
# Plot the image. Note the size of the axes -- now 256 pixels instead of 512
plt.gray()
plt.grid(False)
plt.imshow(newImage)
#plt.axis('off')
plt.show()

1f5ebdafd1db2595.png

Обратите внимание на оси этого графика. Изображение теперь имеет размер 256x256, что составляет одну четвертую от исходного размера, и обнаруженные функции были улучшены, несмотря на то, что теперь на изображении меньше данных.

8. Поздравления

Вы создали свою первую модель компьютерного зрения! Чтобы узнать, как еще больше улучшить модели компьютерного зрения, перейдите к разделу Создание сверточных нейронных сетей (CNN) для улучшения компьютерного зрения .