2016-08-15 8 views
1

Ich habe eine Lusty (Framework für OpenResty) API, die einen Torch-Klassifikator umschließt. Bisher habe ich in der Lage gewesen, eine einzige Anforderung an die Arbeit, aber jede nachfolgende Anforderung an die API löst den folgenden Fehler ohne detaillierte Stack-Trace:Lua Torch7 & OpenResty: Versuch, einen Nullwert zu indexieren

attempt to index a nil value 

Der Fehler erscheint geworfen zu werden, wenn ich rufe:

Das Verhalten des erfolgreichen Abschlusses der ersten Anforderung bei fehlgeschlagener zusätzlicher Anforderung ist ein Hinweis auf das Problem.

Ich habe den vollständigen Code unten für app/requests/classify.lua eingefügt. Dies scheint eine Art Problem mit Variablen-Caching/Initialisierung zu sein, obwohl mein begrenztes Wissen über Lua mir nicht hilft, das Problem zu beheben. Ich habe versucht, mehrere Dinge zu tun, einschließlich der Änderung meiner Importe in lokalisierte Variablen wie local torch = require('torch') und auch diese Importe in die classifyImage() Funktion zu verschieben.

torch = require 'torch' 
nn = require 'nn' 
image = require 'image' 
ParamBank = require 'ParamBank' 
label  = require 'classifier_label' 
torch.setdefaulttensortype('torch.FloatTensor') 

function classifyImage() 

    local opt = { 
    inplace = false, 
    network = "big", 
    backend = "nn", 
    save = "model.t7", 
    img = context.input.image, 
    spatial = false, 
    threads = 4 
    } 
    torch.setnumthreads(opt.threads) 

    require(opt.backend) 
    local SpatialConvolution = nn.SpatialConvolutionMM 
    local SpatialMaxPooling = nn.SpatialMaxPooling 
    local ReLU = nn.ReLU 
    local SpatialSoftMax = nn.SpatialSoftMax 

    local net = nn.Sequential() 

    print('==> init a big overfeat network') 
    net:add(SpatialConvolution(3, 96, 7, 7, 2, 2)) 
    net:add(ReLU(opt.inplace)) 
    net:add(SpatialMaxPooling(3, 3, 3, 3)) 
    net:add(SpatialConvolution(96, 256, 7, 7, 1, 1)) 
    net:add(ReLU(opt.inplace)) 
    net:add(SpatialMaxPooling(2, 2, 2, 2)) 
    net:add(SpatialConvolution(256, 512, 3, 3, 1, 1, 1, 1)) 
    net:add(ReLU(opt.inplace)) 
    net:add(SpatialConvolution(512, 512, 3, 3, 1, 1, 1, 1)) 
    net:add(ReLU(opt.inplace)) 
    net:add(SpatialConvolution(512, 1024, 3, 3, 1, 1, 1, 1)) 
    net:add(ReLU(opt.inplace)) 
    net:add(SpatialConvolution(1024, 1024, 3, 3, 1, 1, 1, 1)) 
    net:add(ReLU(opt.inplace)) 
    net:add(SpatialMaxPooling(3, 3, 3, 3)) 
    net:add(SpatialConvolution(1024, 4096, 5, 5, 1, 1)) 
    net:add(ReLU(opt.inplace)) 
    net:add(SpatialConvolution(4096, 4096, 1, 1, 1, 1)) 
    net:add(ReLU(opt.inplace)) 
    net:add(SpatialConvolution(4096, 1000, 1, 1, 1, 1)) 
    net:add(nn.View(1000)) 
    net:add(SpatialSoftMax()) 
    -- print(net) 

    -- init file pointer 
    print('==> overwrite network parameters with pre-trained weigts') 
    ParamBank:init("net_weight_1") 
    ParamBank:read(  0, {96,3,7,7},  net:get(1).weight) 
    ParamBank:read( 14112, {96},   net:get(1).bias) 
    ParamBank:read( 14208, {256,96,7,7}, net:get(4).weight) 
    ParamBank:read( 1218432, {256},   net:get(4).bias) 
    ParamBank:read( 1218688, {512,256,3,3}, net:get(7).weight) 
    ParamBank:read( 2398336, {512},   net:get(7).bias) 
    ParamBank:read( 2398848, {512,512,3,3}, net:get(9).weight) 
    ParamBank:read( 4758144, {512},   net:get(9).bias) 
    ParamBank:read( 4758656, {1024,512,3,3}, net:get(11).weight) 
    ParamBank:read( 9477248, {1024},   net:get(11).bias) 
    ParamBank:read( 9478272, {1024,1024,3,3}, net:get(13).weight) 
    ParamBank:read(18915456, {1024},   net:get(13).bias) 
    ParamBank:read(18916480, {4096,1024,5,5}, net:get(16).weight) 
    ParamBank:read(123774080, {4096},   net:get(16).bias) 
    ParamBank:read(123778176, {4096,4096,1,1}, net:get(18).weight) 
    ParamBank:read(140555392, {4096},   net:get(18).bias) 
    ParamBank:read(140559488, {1000,4096,1,1}, net:get(20).weight) 
    ParamBank:read(144655488, {1000},   net:get(20).bias) 

    ParamBank:close() 

    -- load and preprocess image 
    print('==> prepare an input image') 
    local img = image.load(opt.img):mul(255) 

    -- use image larger than the eye size in spatial mode 
    if not opt.spatial then 
    local dim = (opt.network == 'small') and 231 or 221 
    local img_scale = image.scale(img, '^'..dim) 
    local h = math.ceil((img_scale:size(2) - dim)/2) 
    local w = math.ceil((img_scale:size(3) - dim)/2) 
    img = image.crop(img_scale, w, h, w + dim, h + dim):floor() 
    end 

    -- memcpy from system RAM to GPU RAM if cuda enabled 
    if opt.backend == 'cunn' or opt.backend == 'cudnn' then 
    net:cuda() 
    img = img:cuda() 
    end 

    -- save bare network (before its buffer filled with temp results) 
    print('==> save model to:', opt.save) 
    torch.save(opt.save, net) 

    -- feedforward network 
    print('==> feed the input image') 
    timer = torch.Timer() 
    img:add(-118.380948):div(61.896913) 
    local out = net:forward(img) 

    -- find output class name in non-spatial mode 
    local results = {} 
    local topN = 10 
    local probs, idxs = torch.topk(out, topN, 1, true) 

    for i=1,topN do 
    print(label[idxs[i]], probs[i]) 
    local r = {} 
    r.label = label[idxs[i]] 
    r.prob = probs[i] 
    results[i] = r 
    end 

    return results 
end 

function errorHandler(err) 
    return tostring(err) 
end 

local success, result = xpcall(classifyImage, errorHandler) 


context.template = { 
    type = "mustache", 
    name = "app/templates/layout", 

    partials = { 
    content = "app/templates/classify", 
    } 
} 


context.output = { 
    success = success, 
    result = result, 
    request = context.input 
} 

context.response.status = 200 

Schätzen Sie Ihre Hilfe!

Update 1

Added print(net) vor und nach local net und auch nachdem ich net:add nennen. Jedes Mal, bevor local net initialisiert wird, wird der Wert nil angezeigt. Wie erwartet zeigt es nach der Initialisierung net ein Fackelobjekt als Wert an. Es scheint etwas in der :add Aufruf, um den Fehler zu schaffen, so fügte ich die folgende sofort nach meiner classifyImage Funktion erklärt:

print(tostring(torch)) 
print(tostring(nn)) 
print(tostring(net)) 

Nach dieser neuen Druckanweisungen hinzufügen, ich folgendes auf der ersten Anfrage erhalten:

nil 
nil 
nil 

Und dann auf der zweiten Anfrage:

table: 0x41448a08 
table: 0x413bdb10 
nil 

Und auf der dritten Anfrage:

table: 0x41448a08 
table: 0x413bdb10 
nil 

Diese sehen wie Zeiger auf ein Objekt im Speicher aus, also ist es sicher hier anzunehmen, dass Torch ein eigenes globales Objekt erstellt?

+0

Versuchen Sie, 'print (net)' vor und nach den Anrufen zu setzen. – hjpotter92

+0

Fertig und Details in der Frage in Kürze hinzufügen. Bevor ich 'local net' im ersten/zweiten Aufruf dekletiere, bekomme ich im Wesentlichen' nil'. Nach der Initialisierung von 'net' bekomme ich auch ein neues Objekt. Nur wenn ich 'add' anrufe, schlägt es fehl.Du denkst, dass es etwas mit 'Fackel' oder' nn' zu tun hat? – crockpotveggies

+0

@ hjpotter92 hinzugefügt weitere Informationen, es sieht aus wie 'Fackel' selbst erstellt globale Objekte im Speicher, die den Code stören? – crockpotveggies

Antwort

0

Wenn torch und seine Module erforderlich sind, wird eine globale Instanz erstellt, die für die gesamte Lebensdauer des Prozesses im Speicher verbleibt. Das Update, das für mich gearbeitet wurde Fackel in der Haupt app.lua Datei in Lusty und fügen Sie den folgenden an der Spitze zu verweisen:

require 'torch' 
require 'nn' 

image = require 'image' 
ParamBank = require 'ParamBank' 
label  = require 'classifier_label' 
torch.setdefaulttensortype('torch.FloatTensor') 
torch.setnumthreads(4) 

SpatialConvolution = nn.SpatialConvolutionMM 
SpatialMaxPooling = nn.SpatialMaxPooling 
ReLU = nn.ReLU 
SpatialSoftMax = nn.SpatialSoftMax 

Die Variablen sind in Rahmen für classifyImage und jetzt gelingt es mit jeder Anfrage. Es ist eine schmutzige Lösung, aber da Torch seine eigenen globalen Objekte pflegt, kann ich keinen Weg um mich herum finden.

Verwandte Themen