Учитывая следующий тензор (который является результатом работы сети [обратите внимание на grad_fn]):
tensor([121., 241., 125., 1., 108., 238., 125., 121., 13., 117., 121., 229.,
161., 13., 0., 202., 161., 121., 121., 0., 121., 121., 242., 125.],
grad_fn=<MvBackward>)
, который мы определим как:
xx = torch.tensor([121., 241., 125., 1., 108., 238., 125., 121., 13., 117., 121., 229.,
161., 13., 0., 202., 161., 121., 121., 0., 121., 121., 242., 125.]).requires_grad_(True)
Я хотел быопределить операцию, которая подсчитывает количество вхождений каждого значения таким образом, что операция выведет следующий тензор:
tensor([2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 7, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 1, 1])
, то есть есть 2 нуля, 1 один, 2 трети и т. д. общее количество возможных значений установлено в восходящем направлении, но в этом примере это 243
. До сих пор я пробовал следующие подходы, которые успешно производят желаемый тензор, но не делают это таким образом, который позволяет вычислять градиентыобратно по сети:
Попытка 1
tt = []
for i in range(243):
tt.append((xx == i).unsqueeze(0))
torch.cat(tt,dim=0).sum(dim=1)
Попытка 2
tvtensor = torch.tensor([i for i in range(243)]).unsqueeze(1).repeat(1,xx.shape[0]).float().requires_grad_(True)
(xx==tvtensor).sum(dim=1)
РЕДАКТИРОВАНИЕ: добавлена попытка
Попытка 3
- На самом деле не ожидал, что это поддержит пропеллер, но решил, что я все равно попробую
ll = torch.zeros((1,243))
for x in xx:
ll[0,x.long()] += 1
Любая помощь приветствуется
РЕДАКТИРОВАТЬ: В соответствии с просьбой конечной цели этогоэто следующее:
Я использую техникудля расчета структурного сходства между двумя временными последовательностями. Одно реально, а другое генерируется. Техника описана в этой статье (https://link.springer.com/chapter/10.1007/978-3-642-02279-1_33), где временной ряд преобразуется в последовательность кодовых слов, а распределение кодовых слов (аналогично тому, как Bag of Words используется в НЛП) используется для представлениявременные ряды. Две серии считаются похожими, когда два распределения сигналов одинаковы. Вот для чего нужен тензор статистики подсчета.
Желательно, чтобы была возможность построить функцию потерь, которая потребляет этот тензор иизмеряет расстояние между реальным и генерируемым сигналом (евклидова норма на данных во временной области напрямую не работает, и этот подход требует лучших результатов), чтобы он мог соответствующим образом обновить генератор.