Визуализация сверточной нейронной сети — ядро ​​изображения

Идентификация изображения

предисловие

В области глубокого обучения для решения задачи классификации изображений наиболее часто используется сверточная нейронная сеть (Convolutional Neural Network), сокращенно CNN. Причина, по которой ее называют сверточной нейронной сетью, заключается в том, что она использует сверточный слой в скрытом слое для обработки данных двумерного (оттенки серого) или трехмерного (RGB) изображения. Каждый сверточный слой состоит из множества фильтров (Filter), каждому фильтру соответствует небольшая матрица (количество строк и столбцов обычно 2 или 3), матрица строится по строкам и столбцам изображения, умножается и суммируются последовательно в соответствии с определенным размером шага. , получают новые данные изображения, этот процесс является процессом свертки изображения.

В применении сверточной нейронной сети изображение свертывается для получения нового изображения (если размер шага больше 1, новое изображение будет уменьшено), которое обычно используется для извлечения признаков изображения, и каждый фильтр также называется картой признаков. Однако свертка изображений используется не только в глубоких нейронных сетях для извлечения признаков.До приложений глубокого обучения свертка изображений широко использовалась в области обработки изображений. Например, в известном программном обеспечении для обработки изображений, таком как PhotoShop, размытие, повышение резкости, тиснение, контур и обнаружение краев также реализуются посредством свертки изображения. Отличие в том, что значение матрицы свертки глубокого обучения обучается моделью и не имеет правил, в то время как при обработке изображений значение матрицы регулярное, а форма обычно 3 строки и 3 столбца. Мы также называем эту матрицу ядром изображения (фактически, параметры сверточного слоя в Keras также используют ядро ​​для обозначения размера фильтра).

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

1. Импортируйте библиотеку

from PIL import Image, ImageDraw
import numpy as np
import matplotlib.pyplot as plt
# %matplotlib inline

2. Реализовать операцию ядра изображения

2.1 Вспомогательные функции

Укажите путь к изображению и используйте PIL.Image для чтения цветного изображения или изображения в градациях серого.

def read_img(imgpath, gray=True):
    img = Image.open(imgpath)
    if gray:
        img = img.convert("L")
    return img

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

def resize_width(img, width):
    w, h = img.size
    height = int(width * h / w)
    return img.resize((width, height))

Вырежьте квадратное изображение из середины по самой короткой стороне изображения.

def crop_center(img):
    w, h = img.size
    c_x, c_y = w/2, h/2
    offset = min(w, h) / 2
    crop_box = (c_x-offset, c_y-offset, c_x+offset, c_y+offset)
    return img.crop(crop_box)

2.2 Указываем ядро ​​для обработки изображений

img — это объект Image; kernel — матрица для операции свертки; strides — размер одного шага преобразования операции свертки; когда mean имеет значение False, вычисляется сумма, а когда True — вычисляется среднее значение.

def apply_img_kernel(img, kernel, strides=1, mean=False):
    img = np.asarray(img)

    h, w = img.shape[:2]
    k_h, k_w = kernel.shape[:2]
    x_range = range(0, w - k_w + 1, strides)
    y_range = range(0, h - k_h + 1, strides)

    if mean:
        prosum = lambda a,b: min((a*b).mean(), 255)
    else:
        prosum = lambda a,b: min((a*b).sum(), 255)

    cal = lambda img: np.array([[prosum(img[i:i+k_h, j:j+k_w], kernel)
                                 for j in x_range]
                                    for i in y_range]).astype(np.uint8)

    if len(img.shape) == 2:
        data = cal(img)
        return Image.fromarray(data)
    elif len(img.shape) == 3:
        r, g, b = np.transpose(img, (2, 0, 1))
        _r, _g, _b = cal(r), cal(g), cal(b)
        return Image.merge('RGB', [Image.fromarray(d) for d in [_r, _g, _b]])

3. Ядро изображения с различными эффектами

Осветление, Резкость, Размытие, Тиснение, Контур, Граница. Каждое ядро ​​представляет собой функцию, параметры можно настраивать, параметры по умолчанию взяты с сайтаЦвет для разбрызгивания. IO/EV/image-can…

3.1 Осветление

def identity_kernel(iden=1.0):
    return np.array([[0, 0,    0],
                     [0, iden, 0],
                     [0, 0,    0]])

3.2 Заточка

def sharpen_kernel(inner=5.0,  edge=-1.0):
    return np.array([[0,    edge,  0],
                     [edge, inner, edge],
                     [0,    edge,  0]])

3.3 Размытие

def blur_kernel(inner=0.25,  edge=0.125, corner=0.0625):
    return np.array([[corner, edge,  corner],
                     [edge,   inner, edge],
                     [corner, edge,  corner]])

3.4 Рельеф

def emboss_kernel(diag=2.0, iden=1.0):
    return np.array([[-diag, -iden, 0],
                     [-iden, iden,  iden],
                     [0,     iden,  diag]])

3.5 Схема

def outline_kernel(inner=8.0, outer=-1.0):
    return np.array([[outer, outer, outer],
                     [outer, inner, outer],
                     [outer, outer, outer]])

3.6 Обнаружение края

def sobel_kernel(direction, base=None, edge=2.0, corner=1.0):
    if base is not None:
        edge = base
        corner = base / 2
    if direction == 'top':
        return np.array([[corner, edge, corner], [0, 0, 0], [-corner, -edge, -corner]])
    elif direction == 'bottom':
        return np.array([[-corner, -edge, -corner], [0, 0, 0], [corner, edge, corner]])
    elif direction == 'left':
        return np.array([[corner, 0, -corner], [edge, 0, -edge], [corner, 0, -corner]])
    elif direction == 'right':
        return np.array([[-corner, 0, corner], [-edge, 0, edge], [-corner, 0, corner]])

    return identity_kernel()

4. Используйте эффект

Считайте изображение и выполните масштабирование и обрезку. (Снимок, сделанный мобильным телефоном, слишком велик, время расчета велико, а отображение изображения также занимает много места)

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

img = read_img('yuki.jpeg', gray=False)

img = crop_center(resize_width(img, 320))

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

def show2imgs(img1, img2, title=None):
    fig = plt.figure(figsize=(10, 5))

    if title is not None:
        fig.suptitle(title)

    plt.subplot(121)
    plt.axis('off')
    plt.imshow(img1)

    plt.subplot(122)
    plt.axis('off')
    plt.imshow(img2)

    plt.show()

4.1 Осветление

img_identity = apply_img_kernel(img, identity_kernel(1.6))

show2imgs(img, img_identity)

4.2 Заточка

img_sharpen = apply_img_kernel(img, sharpen_kernel(inner=1.7,  edge=-0.08))

show2imgs(img, img_sharpen)

4.3 Размытие

img_blur = apply_img_kernel(img, blur_kernel())

show2imgs(img, img_blur)

4.4 Рельеф

img_emboss = apply_img_kernel(img, emboss_kernel())

show2imgs(img, img_emboss)

4.5 Схема

img_outline = apply_img_kernel(img, outline_kernel(inner=8.9, outer=-1.29), mean=True)

show2imgs(img, img_outline)

4.6 Обнаружение границ

img_sobel_top = apply_img_kernel(img, sobel_kernel('top', 0.03))
img_sobel_bottom = apply_img_kernel(img, sobel_kernel('bottom', 0.03))
img_sobel_left = apply_img_kernel(img, sobel_kernel('left', 0.03))
img_sobel_right = apply_img_kernel(img, sobel_kernel('right', 0.03))

show2imgs(img_sobel_top, img_sobel_bottom)
show2imgs(img_sobel_left, img_sobel_right)

5. Открытый исходный код

Код этой статьи является открытым исходным кодом и может быть загружен с github:GitHub.com/Ken Ratio в порядке...

Вы также можете использовать pip для прямой установки (использование см. на домашней странице github):

pip install imgkernel


Отсканируйте QR-код в WeChat, чтобы получить оригиналы новейших технологий