Сверточная нейронная сеть — функция im2col

искусственный интеллект Нейронные сети

Прежде чем объяснять, сначала определите размеры матрицы в операции свертки.
N, C, H и W представляют размер пакета входных данных, количество каналов каждых данных, высоту каждого канала и ширину каждого канала соответственно. Таким образом, размерность входных данных (N, C, H, W)
FN представляет количество фильтров
FH представляет собой высоту фильтра
FW представляет ширину фильтра
Итак, размерность фильтра (FN, C, FH, FW)
Без учета смещения размерность выходных данных должна быть (N, FN, OH, OW)
Среди них OH и OW представляют количество раз, которое фильтр может скользить по высоте и ширине входных данных соответственно (здесь есть формула расчета, просто используйте ее напрямую)
这里写图片描述
В качестве примера на приведенном выше рисунке рассмотрим, что входные данные представляют собой данные (1,1,3,4), то есть количество данных равно 1, и это один канал. Поскольку спереди все 1, то здесь двумерная матрица.
Ядро свертки является ядром свертки (1,1,2,2), то есть число ядер свертки равно 1, второе 1 и второе 1 выше соответствуют (оба относятся к количеству каналов), ядро Это 2 на 2.
Можно найти, что размерность выходных данных равна (1,1,2,3), первая 1 — это количество данных, а вторая 1 — это количество ядер свертки.

При вычислении первого элемента выходных данных можно обнаружить, что это умножение соответствующих элементов numpy (поэлементно), но если присмотреться, можно обнаружить, что на самом деле это то же самое, что и обычная матрица умножение.
这里写图片描述
Как показано на рисунке выше, разверните abef в строку, разверните wxyz в столбец и умножьте на матричное умножение, чтобы получить матрицу 1*1, которая является первым элементом выходных данных. Согласно этому логическому анализу, ядро ​​свертки может скользить по входным данным в общей сложности 6 раз, и каждый раз часть входных данных будет расширяться до одномерных данных (размер измерения равен (FH, FW), поэтому это должно быть 2 раза 2, чтобы получить 4), поэтому входные данные становятся (6,4) размерными данными для облегчения матричного умножения. Ядро свертки будет преобразовано в одномерные данные (размер равен 4). Итак, в конце концов, входные данные размерности (6,4) умножаются на (4,) одномерную матрицу столбца ядра свертки, и результатом будет (6,), что составляет ровно 6 элементов выходных данных. .

Вышеупомянутое является лишь самым простым случаем анализа, код будет приведен ниже (изНачало работы с глубоким обучением):

def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
    """

    Parameters
    ----------
    input_data : 由(数据量, 通道, 高, 长)的4维数组构成的输入数据
    filter_h : 滤波器的高
    filter_w : 滤波器的长
    stride : 步幅
    pad : 填充

    Returns
    -------
    col : 2维数组
    """
    N, C, H, W = input_data.shape
    out_h = (H + 2*pad - filter_h)//stride + 1#输出图的计算公式
    out_w = (W + 2*pad - filter_w)//stride + 1

    img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
    #在通道的之后维度,长和宽的纬度进行填充
    col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))

    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]#
            #确定下来了后4个纬度,col的前两个冒号和img的前两个冒号对应,
            #y:y_max:stride, x:x_max:stride是赋值给y, x, :, :后面的两个冒号
            #这里可以理解为卷积核的每个元素(filter_h, filter_w确定一个卷积核元素)能在图中滑动的范围,
            #y_max-y/stride就是out_h,也就是输出图的高,也就是滑动范围

    col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
    #-1表示第二个维度需要程序进行推理,即总个数除以N*out_h*out_w
    return col

Объяснение кода:
Во-первых, обратите внимание, что этот код принимает количество ядер свертки равным 1. То есть FN равно 1.
col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))В переменной col хранятся данные после «преобразования столбца» входных данных (принцип такой же, как на рисунке выше). Но заметьте, что здесь 6 измерений,C, filter_h, filter_wЭти три измерения определяются, а элементы ядра свертки канала определяются в соответствии со строкой и столбцом.
Причина, по которой последние два измеренияout_h, out_w, потому что количество раз, которое каждый элемент ядра свертки может скользить по двум измерениям высоты и ширины, равноout_h, out_w. Глядя на первое изображение, каждый элемент ядра свертки может скользить только 3 раза по горизонтальной оси и только 2 раза по вертикальной оси.
Затем посмотрите на двухслойный цикл for, это предложениеcol[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]Это кажется трудным для понимания. Первый взглядy:y_max:stride, что относится к операции сегментирования в третьем измерении, причина та же, что и в диапазоне, поэтому здесь вы можете думать об этом какy_maxминусyРазделить наstride, результат такой операции в точностиout_h, то есть количество раз, которое каждый элемент ядра свертки может скользить в измерении высоты.
Сложнее всего понять, что означает общее присваивание, сначала посмотрите на следующий пример:
这里写图片描述
Было обнаружено, что подсказка не может транслировать входной массив из формы (2,3) в форму (3,5), форма (2,3) означает, что данные справа от знака равенства имеют (2,3) форму, но почему в форму (3,5), потому чтоcol[:,2,:]Второе измерение было определено, и то, что нужно назначить, это первое измерение и третье измерение, а первое измерение и третье измерение - это просто 3 и 5, поэтому входные данные должны транслироваться как (3 ,5) форма .

Вернитесь после прочтения примера, первые два измерения col и img — это N и C, поэтому их можно сопоставить без трансляции, а последние два двоеточия col передаются черезy:y_max:stride, x:x_max:strideбыть уверенным.

transpose(0, 4, 5, 1, 2, 3)Наконец, преобразуйте ось, и первые три измерения после преобразования точноN*out_h*out_wэти три числа.
reshape(N*out_h*out_w, -1)Это означает, что второе измерение определяется степенью.
Процесс рассуждений следующий, всего в матрице 6 элементов, первое измерение равно 3, поэтому второе измерение естественно равно 2:
这里写图片描述