Lua: как последовательно загружать данные в каталог? - PullRequest
0 голосов
/ 29 мая 2020

Я новичок в Lua :) и работаю над проектом Lua Torch7. Здесь я хотел бы загрузить данные из каталога в пакеты последовательно:

--main_get_data.lua
local input_txt_raw1 = torch.zeros(opt.batchSize, opt.doc_length, alphabet_size)
local input_txt_emb1 = torch.Tensor(opt.batchSize, opt.txtSize)
local save_files_raw1 = {}
local isCOMPLETE = false
local PICKNOW_ALREADY = 0
local wholesize = 0

local DataLoader = paths.dofile('data_load_in_series.lua')
local data = DataLoader.new(opt.nThreads, opt.dataset, opt)

local sample = function()
  print("now starting sample, picknow = ", PICKNOW_ALREADY)
  real_txt, save_files_raw1, isCOMPLETE, PICKNOW_ALREADY, wholesize = data:getBatch()
  input_txt_raw1:copy(real_txt)
  print("finish a batch, picknow = ", PICKNOW_ALREADY)
end

while isCOMPLETE == false do
  sample()
    input_txt_emb1:copy(netT:forward(input_txt_raw1))
  for n = 1, opt.batchSize do
     matio.save(save_files_raw1[n], input_txt_emb1[n])
  end

где в data_load_in_series.lua:

local FROM_INDEX = 1
local FROM_INDEX_last = 1
local FETCH_LOCK = false

function data.new(n, dataset_name, opt_)
  -- .......
  local donkey_file = 'donkey_folder_get.lua'

  if n > 0 do
    self.threads = Threads(n,
                           function() require 'torch' end,
                           function(idx)
                             opt = options
                             tid = idx
                             local seed = (opt.manualSeed and opt.manualSeed or 0) + idx
                             torch.manualSeed(seed)
                             torch.setnumthreads(1)
                             print(string.format('Starting donkey with id: %d seed: %d', tid, seed))
                             assert(options, 'options not found')
                             assert(opt, 'opt not given')
                             paths.dofile(donkey_file)
                           end)
  end

  local nSamples = 0
  self.threads:addjob(function() return trainLoader:size() end,
        function(c) nSamples = c end)
  self.threads:synchronize()
  self._size = nSamples

  for i = 1, n do
    self.threads:addjob(self._getFromThreads,
                        self._pushResult)
  end

  return self
end

-- .......

function data._getFromThreads()
  assert(opt.batchSize, 'opt.batchSize not found')
  while FETCH_LOCK do
  end
  FETCH_LOCK = true
  FROM_INDEX_last = FROM_INDEX
  FROM_INDEX = FROM_INDEX + opt.batchSize
  FETCH_LOCK = false
  return trainLoader:sample(opt.batchSize, FROM_INDEX_last)
end

function data._pushResult(...)
  local res = {...}
  if res == nil then
    self.threads:synchronize()
  end
  result[1] = res
end

function data:getBatch()
  -- queue another job
  self.threads:addjob(self._getFromThreads, self._pushResult)
  self.threads:dojob()
  local res = result[1]
  result[1] = nil
  if torch.type(res) == 'table' then
    return unpack(res)
  end
  return res
end

где файл осла donkey_folder_get.lua равен

function trainLoader:sample(quantity, from_index)
  local ix_file1 = torch.Tensor(quantity)
  local file_ix1 = from_index
  print('-------')
  for n = 1, quantity do
    print(file_ix1)
    if file_ix1 < #cur_files then
      ix_file1[n] = file_ix1
      file_ix1 = file_ix1 + 1
    else
      ix_file1[n] = #cur_files
      COMPLETE = true
    end
  end
  print('-------')

  local data_txt1 = torch.zeros(quantity, opt.doc_length, alphabet_size) -- real
  local save_files = {}

  for n = 1, quantity do
    -- ........
  end
  collectgarbage(); collectgarbage()
  return data_txt1, save_files, COMPLETE, file_ix1, size
end

function trainLoader:size()
  return size
end

Как показано в data_load_in_series.lua, я попытался добавить блокировку переменной, чтобы разные потоки не получали одинаковые FROM_INDEX. Однако это оказывается бесполезным: все n потоки извлекают один и тот же пакет (например, первые 64 файла в каталоге) и работают повторно, что означает, что все данные в каталоге выполняются n раз. Я ожидаю, что поток №1 получит данные № [1:64], а поток №1 получит данные № [65: 125] ...

Кто-нибудь знает, как загружать данные в каталог последовательно в Lua? Большое спасибо за любую возможную помощь!

...