Это в основном сводится к простой математике и поиску нескольких функций в руководстве по горелке.
Хорошо, мне скучно, поэтому ...
replicate(x,batch_size)
как определено в https://github.com/wojzaremba/lstm/blob/master/data.lua
-- Stacks replicated, shifted versions of x_inp
-- into a single matrix of size x_inp:size(1) x batch_size.
local function replicate(x_inp, batch_size)
local s = x_inp:size(1)
local x = torch.zeros(torch.floor(s / batch_size), batch_size)
for i = 1, batch_size do
local start = torch.round((i - 1) * s / batch_size) + 1
local finish = start + x:size(1) - 1
x:sub(1, x:size(1), i, i):copy(x_inp:sub(start, finish))
end
return x
end
В этом коде используется структура Torch .
x_inp:size(1)
возвращает размер 1 размера Тензор факела (потенциально многомерная матрица) x_inp
.
См. https://cornebise.com/torch-doc-template/tensor.html#toc_18
Итак, x_inp:size(1)
дает вам количество строк в x_inp
. x_inp:size(2)
, даст вам количество столбцов ...
local x = torch.zeros(torch.floor(s / batch_size), batch_size)
создает новый двумерный тензор, заполненный нулями, и создает локальную ссылку на него с именем x
Количество строк равно рассчитывается на основе количества строк s
, x_inp
и batch_size
. Итак, для вашего примера ввода это оказывается floor(11/2) = floor(5.5) = 5
.
Количество столбцов в вашем примере равно 2, так как batch_size
равно 2.
torch.
Таким образом, просто x
- это матрица 5x2
0 0
0 0
0 0
0 0
0 0
Следующие строки копируют содержимое x_inp
в x
.
for i = 1, batch_size do
local start = torch.round((i - 1) * s / batch_size) + 1
local finish = start + x:size(1) - 1
x:sub(1, x:size(1), i, i):copy(x_inp:sub(start, finish))
end
При первом запуске start
оценивается как 1 и finish
до 5
, поскольку x:size(1)
, конечно, количество строк x
, что составляет 5
. 1+5-1=5
Во втором прогоне start
оценивается как 6, а finish
до 10
Таким образом, первые 5 строк x_inp
(ваш первый пакет) копируются в первый столбец x
, а второй пакет копируется во второй столбец x
x:sub(1, x:size(1), i, i)
- это суб-тензор x
, строки с 1 по 5, столбцы с 1 по 1 и во второй строке выполнения С 1 по 5, столбцы со 2 по 2 (в вашем примере). Таким образом, это не что иное, как первый и второй столбцы x
См. https://cornebise.com/torch-doc-template/tensor.html#toc_42
:copy(x_inp:sub(start, finish))
копирует элементы из x_inp
в столбцы x
.
Итак, чтобы подвести итог, вы берете входной тензор и разбиваете его на партии, которые хранятся в тензоре с одним столбцом для каждой партии.
Итак, с x_inp
0
1
2
3
4
5
6
7
8
9
10
и batch_size = 2
x
это
0 5
1 6
2 7
3 8
4 9
Далее:
local function testdataset(batch_size)
local x = load_data(ptb_path .. "ptb.test.txt")
x = x:resize(x:size(1), 1):expand(x:size(1), batch_size)
return x
end
Это еще одна функция, которая загружает некоторые данные из файл. Этот x
не связан с x
выше, кроме того, что оба являются тензором.
Давайте воспользуемся простым примером:
x
будет
1
2
3
4
и batch_size = 4
x = x:resize(x:size(1), 1):expand(x:size(1), batch_size)
Сначала x
будет изменен до 4x1, читается https://cornebise.com/torch-doc-template/tensor.html#toc_36
А затем он расширяется до 4x4 путем дублирования первая строка 3 раза.
Результатом x
является тензор
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
читать https://cornebise.com/torch-doc-template/tensor.html#toc_49