From f3380df9ee9a15ae107bf66bc24fd62669a88eda Mon Sep 17 00:00:00 2001 From: txh18 Date: Sun, 1 Nov 2015 23:01:33 +0800 Subject: still working on the tdag layer --- nerv/examples/lmptb/m-tests/dagl_test.lua | 20 ++--- nerv/examples/lmptb/rnn/layer_tdag.lua | 134 +++++++++++++++--------------- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/nerv/examples/lmptb/m-tests/dagl_test.lua b/nerv/examples/lmptb/m-tests/dagl_test.lua index 02e9c49..9f45b6a 100644 --- a/nerv/examples/lmptb/m-tests/dagl_test.lua +++ b/nerv/examples/lmptb/m-tests/dagl_test.lua @@ -98,7 +98,7 @@ end --global_conf: table --layerRepo: nerv.LayerRepo ---Returns: a nerv.DAGLayer +--Returns: a nerv.TDAGLayer function prepare_dagLayer(global_conf, layerRepo) printf("%s Initing daglayer ...\n", global_conf.sche_log_pre) @@ -107,14 +107,14 @@ function prepare_dagLayer(global_conf, layerRepo) dim_in_t[1] = 1 --input to select_linear layer dim_in_t[2] = global_conf.vocab:size() --input to softmax label local connections_t = { - ["[1]"] = "selectL1[1],0", - ["selectL1[1]"] = "recurrentL1[1],0", - ["recurrentL1[1]"] = "sigmoidL1[1],0", - ["sigmoidL1[1]"] = "outputL[1],0", - ["sigmoidL1[1]"] = "recurrentL1[2],1", - ["outputL[1]"] = "softmaxL[1],0", - ["[2]"] = "softmaxL[2],0", - ["softmaxL[1]"] = "[1],0" + {"[1]", "selectL1[1]", 0}, + {"selectL1[1]", "recurrentL1[1]", 0}, + {"recurrentL1[1]", "sigmoidL1[1]", 0}, + {"sigmoidL1[1]", "outputL[1]", 0}, + {"sigmoidL1[1]", "recurrentL1[2]", 1}, + {"outputL[1]", "softmaxL[1]", 0}, + {"[2]", "softmaxL[2]", 0}, + {"softmaxL[1]", "[1]", 0} } --[[ @@ -127,7 +127,6 @@ function prepare_dagLayer(global_conf, layerRepo) local dagL = nerv.TDAGLayer("dagL", global_conf, {["dim_in"] = dim_in_t, ["dim_out"] = {1}, ["sub_layers"] = layerRepo, ["connections"] = connections_t, }) - dagL:init(global_conf.batch_size) printf("%s Initing DAGLayer end.\n", global_conf.sche_log_pre) return dagL end @@ -162,3 +161,4 @@ global_conf.vocab:build_file(global_conf.train_fn, false) local paramRepo = prepare_parameters(global_conf, true) local layerRepo = prepare_layers(global_conf, paramRepo) local dagL = prepare_dagLayer(global_conf, layerRepo) +--dagL:init(global_conf.batch_size) diff --git a/nerv/examples/lmptb/rnn/layer_tdag.lua b/nerv/examples/lmptb/rnn/layer_tdag.lua index 296e2e6..f417f91 100644 --- a/nerv/examples/lmptb/rnn/layer_tdag.lua +++ b/nerv/examples/lmptb/rnn/layer_tdag.lua @@ -1,6 +1,7 @@ local DAGLayer = nerv.class("nerv.TDAGLayer", "nerv.Layer") local function parse_id(str) + --used to parse layerid[portid],time local id, port, time, _ _, _, id, port, time = string.find(str, "([a-zA-Z0-9_]+)%[([0-9]+)%][,]*([0-9]*)") if id == nil or port == nil then @@ -9,14 +10,15 @@ local function parse_id(str) nerv.error("wrong format of connection id") end end - print(str, id, port, time) + --print(str, id, port, time) port = tonumber(port) if (time == nil) then time = 0 else time = tonumber(time) end - return id, port, time + --now time don't need to be parsed + return id, port end local function discover(id, layers, layer_repo) @@ -29,105 +31,103 @@ local function discover(id, layers, layer_repo) local dim_in, dim_out = layer:get_dim() ref = { layer = layer, - inputs = {}, - outputs = {}, - err_inputs = {}, - err_outputs = {}, + inputs_m = {}, --storage for computation + outputs_m = {}, + err_inputs_m = {}, + err_outputs_m = {}, next_layers = {}, - input_len = #dim_in, - output_len = #dim_out, - in_deg = 0, - visited = false + conns_i = {}, --list of inputing connections + conns_o = {}, --list of outputing connections + dim_in = dim_in, --list of dimensions of ports + dim_out = dim_out, } layers[id] = ref end return ref end +local function makeInitialStore(dim, batch_size, global_conf) + st = {} + for i = 1 - batch_size, batch_size * 2 do + st[i] = global_conf.cumat_type(batch_size, dim) + end +end + function DAGLayer:__init(id, global_conf, layer_conf) local layers = {} - local inputs = {} - local outputs = {} + local inputs_p = {} --map:port of the TDAGLayer to layer ref and port + local outputs_p = {} local dim_in = layer_conf.dim_in local dim_out = layer_conf.dim_out - local parsed_conn = {} + local parsed_conns = {} local _ - local time_to - for from, to in pairs(layer_conf.connections) do - - local id_from, port_from, _ = parse_id(from) - local id_to, port_to, time_to = parse_id(to) - + for _, ll in pairs(layer_conf.connections) do + local id_from, port_from = parse_id(ll[1]) + local id_to, port_to = parse_id(ll[2]) + local time_to = ll[3] + + print(id_from, id_to, time_to) + local ref_from = discover(id_from, layers, layer_conf.sub_layers) local ref_to = discover(id_to, layers, layer_conf.sub_layers) - local input_dim, output_dim, _ - - if ref_from and ref_from.outputs[port_from] ~= nil then - nerv.error("%s has already been attached", from) - end - if ref_to and ref_to.inputs[port_to] ~= nil then - nerv.error("%s has already been attached", to) - end - if id_from == "" then - input_dim, _ = ref_to.layer:get_dim() - if dim_in[port_from] ~= input_dim[port_to] then - nerv.error("mismatching data dimension between %s and %s", from, to) + if (id_from == "") then + if (dim_in[port_from] ~= ref_to.dim_in[port_to] or time_to ~= 0) then + nerv.error("mismatch dimension or wrong time %s,%s,%d", ll[1], ll[2], ll[3]) end - inputs[port_from] = {ref_to, port_to} - ref_to.inputs[port_to] = inputs -- just a place holder - elseif id_to == "" then - _, output_dim = ref_from.layer:get_dim() - if output_dim[port_from] ~= dim_out[port_to] then - nerv.error("mismatching data dimension between %s and %s", from, to) + inputs_p[port_from] = {["ref"] = ref_to, ["port"] = port_to} + elseif (id_to == "") then + if (dim_out[port_to] ~= ref_from.dim_out[port_from] or time_to ~= 0) then + nerv.error("mismatch dimension or wrong time %s,%s,%d", ll[1], ll[2], ll[3]) end - outputs[port_to] = {ref_from, port_from} - ref_from.outputs[port_from] = outputs -- just a place holder + outputs_p[port_to] = {["ref"] = ref_from, ["port"] = port_from} else - _, output_dim = ref_from.layer:get_dim() - input_dim, _ = ref_to.layer:get_dim() - if output_dim[port_from] ~= input_dim[port_to] then - nerv.error("mismatching data dimension between %s and %s", from, to) + conn_now = { + ["src"] = {["ref"] = ref_from, ["port"] = port_from}, + ["dst"] = {["ref"] = ref_to, ["port"] = port_to}, + ["time"] = time_to + } + if (ref_to.dim_in[port_to] ~= ref_from.dim_out[port_from]) then + nerv.error("mismatch dimension or wrong time %s,%s,%d", ll[1], ll[2], ll[3]) end - - table.insert(parsed_conn, - {{ref_from, port_from}, {ref_to, port_to}}) - table.insert(ref_from.next_layers, ref_to) -- add edge - ref_to.in_deg = ref_to.in_deg + 1 -- increase the in-degree of the target layer + table.insert(parsed_conns, conn_now) + table.insert(ref_to.conns_i, conn_now) + table.insert(ref_from.conns_o, conn_now) end end self.layers = layers - self.inputs = inputs - self.outputs = outputs + self.inputs_p = inputs_p + self.outputs_p = outputs_p self.id = id self.dim_in = dim_in self.dim_out = dim_out - self.parsed_conn = parsed_conn - self.queue = queue + self.parsed_conns = parsed_conns self.gconf = global_conf end -function DAGLayer:init(batch_size) - for i, conn in ipairs(self.parsed_conn) do +function DAGLayer:init(seq_size) + for i, conn in ipairs(self.parsed_conn) do local _, output_dim local ref_from, port_from, ref_to, port_to - ref_from, port_from = unpack(conn[1]) - ref_to, port_to = unpack(conn[2]) - _, output_dim = ref_from.layer:get_dim() - local dim = 1 - if output_dim[port_from] > 0 then - dim = output_dim[port_from] + ref_from, port_from = conn.src.ref, conn.src.port + ref_to, port_to = conn.dst.ref, conn.dst.port + local dim = ref_from.dim_out[port_from] + if (dim == 0) then + nerv.error("layer %s has a zero dim port", ref_from.layer.id) end - local mid = self.gconf.cumat_type(batch_size, dim) - local err_mid = mid:create() - ref_from.outputs[port_from] = mid - ref_to.inputs[port_to] = mid + local mid = makeInitialStore(dim, seq_size, global_conf) + local err_mid = makeInitialStore(dim, seq_size, global_conf) + + print(ref_from.layer.id, "->", ref_to.layer.id) + + ref_from.outputs_m[port_from] = mid + ref_to.inputs_m[port_to] = mid - ref_from.err_inputs[port_from] = err_mid - ref_to.err_outputs[port_to] = err_mid + ref_from.err_outputs_m[port_from] = err_mid + ref_to.err_inputs_m[port_to] = err_mid end for id, ref in pairs(self.layers) do for i = 1, ref.input_len do @@ -189,7 +189,7 @@ function DAGLayer:set_inputs(input) end local layer = self.inputs[i][1] local port = self.inputs[i][2] - layer.inputs[port] = input[i] + layer.inputs[port] = input[i] --TODO: should be inputs_m end end -- cgit v1.2.3-70-g09d2