# Класс CPositionalEmbeddingLayer

<!-- TOC -->

- [Класс CPositionalEmbeddingLayer](#класс-cpositionalembeddinglayer)
    - [Настройки](#настройки)
        - [Типы векторов](#типы-векторов)
    - [Обучаемые параметры](#обучаемые-параметры)
        - [Прибавляемые представления позиций](#прибавляемые-представления-позиций)
    - [Входы](#входы)
    - [Выходы](#выходы)

<!-- /TOC -->

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

## Настройки

### Типы векторов

```c++
// Тип векторов
enum TPositionalEmbeddingType {
    // Обучаемые, прибавляемые к входам Y = X + embedding
    PET_LearnableAddition = 0,
    // Необучаемые (используются в трансформерах https://arxiv.org/abs/1807.03819).
    // Дополнительное ограничение на размер входа: Depth == Height == Width == 1.
    PET_Transformers,

    PET_EnumCount
};

void SetType( TPositionalEmbeddingType newType );
```

## Обучаемые параметры

### Прибавляемые представления позиций

```c++
CPtr<CDnnBlob> GetAddends() const;
```

Векторные представления позиций в последовательности, прибавляемые к векторам входа. Обучаются если `GetType()` равен `PET_LearnableAddition`<!-- или `PET_LearnableMultAddition`-->.

Представляют собой [блоб](../DnnBlob.md) размера

- `BatchLength` и `BatchWidth` равны `1`;
- остальные размерности равны аналогичным размерностям у входа.

## Входы

На единственный вход подается блоб, который содержит набор последовательностей векторов следующего размера:

- `BatchLength` должен быть равен `1`;
- `BatchWidth` - количество последовательностей в наборе;
- `ListSize` - длина последовательностей;
- `Height * Width * Depth * Channels` - длина векторов в наборе;
  - если `GetType() == PET_Transformers`, то `Height`, `Width` и `Depth` должны быть равны `1`.

## Выходы

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

Если `GetType() == PET_Transformers`, то результат считается по формуле

```c++
result[i][j][k] = input[i][j][k] + sin( j / pow( 10000, ( k / vectorSize ) ) )
```

где:

- `i` - индекс последовательности в батче (от `0` до `BatchWidth - 1`)
- `j` - позиция вектора в последовательности (от `0` до `ListSize - 1`)
- `vectorSize` - длина векторов (`Height * Width * Depth * Channels`)
- `k` - индекс элемента в векторе (от `0` до `vectorSize - 1`)

Если `GetType() == PET_LearnableAddition`, то результат считается по формуле:

```c++
result[i][j] = input[i][j] + GetAddend()[j]
```

где:

- `i` - индекс последовательности в батче (от `0` до `BatchWidth - 1`)
- `j` - позиция вектора в последовательности (от `0` до `ListSize - 1`).
