AvgPool1D

Описание

Info

Родительский класс: Pool1D

Производные классы: -

Этот модуль реализует операцию одномерного усредняющего пулинга (одномерного усредняющего объединения). Подробное теоретическое описание см. в Pool1D.

Для входного тензора с размерами (N, C, L_{in}) и выходного с размерами (N, C, L{out}) операция проводится следующим образом (рассматриваем i-й элемент батча, j-ую карту выходного тензора):

out(N_i, C_j, l) = \frac{1}{k}\sum_{m=0}^{k-1}(input(N_i, C_j, stride \times l + m))

где

N - размер батча;
C - количество карт в тензоре;
L - размер последовательности;
stride - шаг пулинга;
k - размер окна пулинга.

Инициализация

def __init__(self, size=2, stride=2, pad=0, includePad=True, name=None):

Параметры

Параметр Возможные типы Описание По умолчанию
size int Размер ядра. 2
stride int Шаг пулинга. 2
pad int Паддинг входных карт. 0
includePad bool Флаг учета значений заполнения краёв при подсчете среднего значения. True
name str Имя слоя. None

Пояснения

pad - возможна передача только единой величины отступа для всех сторон карт. Возможности создания асимметричного паддинга (заполнение дополнительными элементами только с одной стороны тензора) для данного модуля не предусмотрено, используйте Pad1D;


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

Примеры


Базовый пример пулинга


Необходимые импорты.

>>> import numpy as np
>>> from PuzzleLib.Backend import gpuarray
>>> from PuzzleLib.Modules import AvgPool1D

Info

gpuarray необходим для правильного размещения тензора на GPU

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

>>> batchsize, maps, insize = 1, 1, 10
>>> data = gpuarray.to_gpu(np.arange(batchsize * maps * insize).reshape((batchsize, maps, insize)).astype(np.float32))
>>> data

[[[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]]]

Инициализируем модуль со стандартными параметрами (size=2, stride=2, pad=0, includePad=True):

>>> pool = AvgPool1D()
>>> pool(data)
[[[0.5 2.5 4.5 6.5 8.5]]]

Параметр size


Оставим все параметры такими же, кроме size:

>>> pool = AvgPool1D(size=4)
>>> pool(data)
[[[1.5 3.5 5.5 7.5]]]

Параметр stride


Установим значение stride равным 1:

>>> pool = AvgPool1D(stride=1)
>>> pool(data)
[[[0.5 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5]]]

Изменим теперь и stride, и size:

>>> pool = AvgPool1D(size=4, stride=4)
>>> pool(data)

[[[1.5 5.5]]]

Как видно, последние два элемента исходного тензора не были включены в расчёты, так как субтензор из них был по размеру меньше окна пулинга.


Параметр pad


Чтобы включить последние элементы из предыдущего примера, инициализируем паддинг:

>>> pool = AvgPool1D(size=4, stride=4, pad=1)
>>> pool(data)
[[[0.75 4.5  6.  ]]]
Обратите внимание, что паддинг в модуле всегда симметричный - по одному новому элементу было добавлено с каждой стороны исходного тензора, т.е. его вид после паддинга:
[[[0. 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 0.]]]


Параметр includePad


В предыдущих примерах параметр includePad оставался тем же, что и по умолчанию, т.е. периферийные элементы паддинга включались в расчёты. Теперь посмотрим, что будет, если отключить этот флаг для последнего примера:

>>> pool = AvgPool1D(size=4, stride=4, pad=1, includePad=False)
>>> pool(data)
[[[1.  4.5 8. ]]]
Как видно, окно пулинга шло с учётом наличия дополнительных элементов, но их наличие никак не учитывалось при подсчёте среднего значения субтензора.