TreeLSTM de StanfordNLP , cuando se usa con un conjunto de datos con más de 30 000 instancias, hace que LuaJit emita un error con "Memoria insuficiente". Estoy resolviendo esto usando LuaJit Data Structures . Para obtener el conjunto de datos fuera del montón de lua, los árboles deben colocarse en un LDS.Vector.
Dado que LDS.Vector contiene cdata, el primer paso fue convertir el tipo de árbol en un objeto cdata:
local ffi = require('ffi') ffi.cdef([[ typedef struct CTree { struct CTree* parent; int num_children; struct CTree* children [25]; int idx; int gold_label; int leaf_idx; } CTree; ]])
También hay pequeños cambios que deben realizarse en read_data.lua para manejar el nuevo tipo cdata CTree. Usar LDS parecía un enfoque razonable para resolver el límite de memoria hasta ahora; sin embargo, CTree requiere un campo llamado 'compositor'.
Composer es del tipo nn.gModule. Continuar con esta solución implicaría crear un typedef de nn.gModule como cdata, incluida la creación de un typedef para sus miembros. Antes de continuar, ¿parece esta la dirección correcta a seguir? ¿Alguien tiene experiencia con este problema?
Como ha descubierto, representar datos estructurados de una manera compatible con el montón de LuaJIT es un poco complicado en este momento.
En la implementación de Tree-LSTM, cada una de las tablas de árbol contiene un puntero a una instancia de compositor, principalmente por conveniencia en la implementación.
Una solución para evitar nn.gModule
sería usar el campo idx
existente para indexar en una tabla de instancias de compositor. En este enfoque, el par ( sentence_idx
, node_idx
) se puede usar para identificar de manera única a un compositor en una tabla global de instancias de compositores de dos niveles. Para evitar problemas de memoria, el código de limpieza actual se puede reemplazar con una línea que establece el índice correspondiente en la tabla en nil
.