2016-11-09 3 views
0

Возможно ли установить метод __index для классов факела? Я пытался реализовать простой dataset класс, как указано в глубоком обучении с факелом tutoral: (ipynb here)Настройка __index для факельных классов

trainset = { 
    inputs = {0, 1, 1, 0}, 
    targets = {1, 1, 1, 0} 
} 

index = function(t, i) 
    return {t.inputs[i], t.targets[i]} 
end 

setmetatable(trainset, { 
    __index = index 
) 

Что позволяет делать trainset[1]], который возвращает {0, 1}.

Однако выполнение этого как класса факела не работает.

local torch = require("torch") 

do 
    Dataset = torch.class("Dataset") 

    function Dataset:__init(i, t) 
     self.inputs = i 
     self.targets = t 
    end 

    function Dataset.__index(t, v) 
     print("inside index") 
     return { 
      rawget(t, inputs)[v], 
      rawget(t, targets)[v] 
     } 
    end 
end 

Dataset({0, 1, 1, 0}, {1, 1, 1, 0}) -- fails 

кажется, что при создании объекта, __index() называется и не так index и targets еще не созданы. Если rawget не используется, это вызывает переполнение стека.

Мое понимание Lua ограничено, но я с удивлением вижу, что во время создания объекта вызывается __index(): Я думаю, что происходит кое-что за кулисами, которое я не совсем понимаю.

+1

Имеет смысл подражать только числовым клавишам с использованием метаданных '__index'. Я думаю, это решит проблему: 'if type (v) == 'number', а затем return {t.inputs [v], t.targets [v]} end' –

+0

Спасибо, это полезно. Это не совсем вся история, есть некоторые проблемы, связанные с факелом (см. Мой ответ). – mgperry

ответ

1

Факельные классы все реализуют __index, которые будут искать __index__ в метатете, которая предназначена для перегрузки.

От docs:

Если один хочет, чтобы обеспечить индекс или NewIndex в метаклассе, эти операторы должны придерживаться определенной схемы:

индекса должен либо возвращать значение и true или только false. В первом случае это означает, что индекс смог обработать данный аргумент (например, тип был прав). Второй случай означает, что не смог ничего сделать, поэтому __index в корневой метатете может затем попытаться определить, содержит ли метакласс требуемое значение.

Что означает для примера, метод __index__ (не __index!) Должны проверить, если type(v) == "number" и если нет, то вернуть false так, что __index может искать значение в объекте метатаблицы.

local torch = require("torch") 

do 
    Dataset = torch.class("Dataset") 

    function Dataset:__init(i, t) 
     self.inputs = i 
     self.targets = t 
    end 

function Dataset.__index__(t, v) 
    if type(v) == "number" then 
     local tbl = { 
      t.inputs[v], 
      t.targets[v] 
     } 
     return tbl, true 
    else 
     return false 
    end 
end 

local dset = Dataset({0, 1, 1, 0}, {1, 1, 1, 0}) 
dset[1] --> {0, 1} 
Смежные вопросы