Added basic torch import functionality. Fixes #3
WIP #3. Added import tests WIP #3 Added more test-cases WIP #3 Added more tests WIP #3. Fixed concat.lua test WIP #3 minor changes WIP #3 Fixed concat-parallel.lua WIP #3 Added check-model helper WIP #3 Added more tests for model checker WIP #3 Added extra tests WIP #3 Changed check-model to GraphChecker WIP #3. multiple cases fail for ImportTorch... WIP #3 Fixed ImportTorch batch test case running WIP #3 Changed graph checker to use gme path for id WIP #3 Updated tests WIP #3. Tweaked to get all examples working locally w/ 'th' WIP #3 Fixed tests
Esse commit está contido em:
@@ -7,6 +7,7 @@
|
||||
},
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"lodash.difference": "^4.1.2",
|
||||
"webgme": "^1.1.0",
|
||||
"webgme-autoviz": "dfst/webgme-autoviz",
|
||||
"webgme-breadcrumbheader": "dfst/webgme-breadcrumbheader",
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
define([
|
||||
'deepforge/js-yaml.min'
|
||||
], function(
|
||||
yaml
|
||||
) {
|
||||
|
||||
var Importer = function(core) {
|
||||
this._core = core;
|
||||
};
|
||||
|
||||
Importer.prototype.gme = function(children) {
|
||||
var conns = children.filter(child => isConnection(this._core, child)),
|
||||
gmeToId = {},
|
||||
gmeToNode = {},
|
||||
nodes;
|
||||
|
||||
nodes = children
|
||||
.filter(child => !isConnection(this._core, child))
|
||||
.map(node => {
|
||||
var n = fromGme(this._core, node),
|
||||
id = this._core.getPath(node);
|
||||
gmeToId[id] = n.id;
|
||||
gmeToNode[id] = n;
|
||||
return n;
|
||||
});
|
||||
|
||||
// Set the 'next' values
|
||||
conns.forEach(conn => {
|
||||
var dstId = this._core.getPointerPath(conn, 'dst'),
|
||||
srcId = this._core.getPointerPath(conn, 'src'),
|
||||
src = gmeToNode[srcId];
|
||||
|
||||
src.next.push(gmeToId[dstId]);
|
||||
});
|
||||
|
||||
return new Nodes(this._core, nodes);
|
||||
};
|
||||
|
||||
Importer.prototype.yaml = function(text) {
|
||||
var nodes = yaml.load(text);
|
||||
return new Nodes(this._core, nodes);
|
||||
};
|
||||
|
||||
var Exporter = function(nodes) {
|
||||
this._nodes = nodes;
|
||||
};
|
||||
|
||||
Exporter.prototype.yaml = function() {
|
||||
return yaml.dump(this._nodes);
|
||||
};
|
||||
|
||||
var Operator = function(core, nodes, fn) {
|
||||
Importer.call(this, core);
|
||||
this._nodes = nodes;
|
||||
this._fn = fn;
|
||||
this.to = this;
|
||||
};
|
||||
|
||||
// For each of the converter formats, create an operator function
|
||||
// that converts then calls the _fn
|
||||
Object.keys(Importer.prototype) // formats
|
||||
.forEach(format => Operator.prototype[format] = function() {
|
||||
var nodes = Importer.prototype[format].apply(this, arguments).nodes();
|
||||
return this._fn(this._nodes, nodes);
|
||||
});
|
||||
|
||||
var Nodes = function(core, nodes) {
|
||||
this._nodes = nodes;
|
||||
|
||||
nodes.forEach(node => {
|
||||
node.next = node.next || [];
|
||||
node.attributes = node.attributes || {};
|
||||
});
|
||||
|
||||
// Operations
|
||||
this.map = new Operator(core, nodes, _modelMatches);
|
||||
this.to = new Exporter(nodes);
|
||||
};
|
||||
|
||||
Nodes.prototype.nodes = function() {
|
||||
return this._nodes;
|
||||
};
|
||||
|
||||
var fromGme = function(core, node) {
|
||||
var result = {},
|
||||
attrs,
|
||||
n;
|
||||
|
||||
n = core.getBase(node);
|
||||
|
||||
result.type = core.getAttribute(n, 'name');
|
||||
result.id = core.getPath(node);
|
||||
result.next = [];
|
||||
|
||||
// Get attribute names
|
||||
attrs = core.getAttributeNames(node).filter(name => name !== 'name');
|
||||
|
||||
result.attributes = {};
|
||||
for (var i = attrs.length; i--;) {
|
||||
result.attributes[attrs[i]] = core.getAttribute(node, attrs[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
var isConnection = function(core, node) {
|
||||
var ptrs = core.getPointerNames(node);
|
||||
return ptrs.indexOf('src') !== -1 && ptrs.indexOf('dst') !== -1;
|
||||
};
|
||||
|
||||
var GraphChecker = function(core) {
|
||||
Importer.call(this, core);
|
||||
};
|
||||
|
||||
GraphChecker.prototype = new Importer();
|
||||
|
||||
// Check if two models are isomorphic
|
||||
var modelMatches = function(gmeNodes, text) {
|
||||
var nodes = convertNodes(gmeNodes),
|
||||
soln = yaml.load(text);
|
||||
|
||||
nodes.concat(soln).forEach(node => {
|
||||
node.next = node.next || [];
|
||||
node.attributes = node.attributes || {};
|
||||
});
|
||||
|
||||
return _modelMatches(nodes, soln);
|
||||
};
|
||||
|
||||
//////////////// Operators ////////////////
|
||||
var _modelMatches = function(soln, nodes) {
|
||||
var nodeMap = createMap(nodes),
|
||||
solnMap = createMap(soln),
|
||||
sInits, // soln start nodes
|
||||
nInits, // 'nodes' start nodes
|
||||
resMap = {}, // soln node id to node id
|
||||
solnIds = soln.map(n => n.id),
|
||||
nodeIds = nodes.map(n => n.id);
|
||||
|
||||
if (nodes.length !== soln.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the node with the fewest number of options
|
||||
var startTuple = getMostConstrained(soln, nodes),
|
||||
startId = startTuple[0].id;
|
||||
|
||||
if (startTuple[1].length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return inferGraph(startId, solnMap, nodeMap);
|
||||
};
|
||||
|
||||
var getMostConstrained = function(soln, nodes) {
|
||||
var options = soln.map(sn => [sn, nodes.filter(n => nodesMatch(sn, n))]),
|
||||
startId;
|
||||
|
||||
options.sort((a, b) => b[1].length < a[1].length);
|
||||
return options[0];
|
||||
};
|
||||
|
||||
var inferGraph = function(id, solnMap, nodeMap, mappings) {
|
||||
var snext = solnMap[id].next,
|
||||
nodes = Object.keys(nodeMap).map(id => nodeMap[id]),
|
||||
snode = solnMap[id],
|
||||
options,
|
||||
used,
|
||||
node;
|
||||
|
||||
mappings = mappings || {};
|
||||
|
||||
if (mappings.hasOwnProperty(id)) { // skip if already been assigned
|
||||
return mappings;
|
||||
}
|
||||
|
||||
used = Object.keys(mappings).map(id => mappings[id]);
|
||||
options = nodes
|
||||
.filter(n => used.indexOf(n.id) === -1) // Remove already taken ids
|
||||
.filter(n => nodesMatch(n, snode));
|
||||
|
||||
if (options.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// try all the options
|
||||
var result,
|
||||
mappings2;
|
||||
|
||||
snext = snext
|
||||
.filter(id => !mappings.hasOwnProperty(id));
|
||||
|
||||
// Filter by known connections into
|
||||
// TODO
|
||||
|
||||
if (snext.length === 0 && nodes.length !== (used.length + 1)) {
|
||||
// Add the next most constrained node to snext
|
||||
var startId,
|
||||
tuple,
|
||||
soln;
|
||||
|
||||
soln = Object.keys(solnMap)
|
||||
.filter(nId => nId != id && !mappings.hasOwnProperty(nId)) // not assigned
|
||||
.map(id => solnMap[id]);
|
||||
|
||||
tuple = getMostConstrained(soln, nodes);
|
||||
startId = tuple[0].id;
|
||||
|
||||
if (tuple[1].length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
snext.push(startId);
|
||||
}
|
||||
|
||||
for (var i = options.length; i--;) {
|
||||
mappings[id] = options[i].id; // need to clone the object
|
||||
|
||||
mappings2 = clone(mappings);
|
||||
result = snext.reduce((prev, curr) => {
|
||||
mappings2 = inferGraph(curr, solnMap, nodeMap, mappings2);
|
||||
return prev && mappings;
|
||||
}, true);
|
||||
|
||||
if (result) {
|
||||
return mappings2;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
// infer parent nodes of id
|
||||
// TODO
|
||||
};
|
||||
|
||||
var clone = function(obj) {
|
||||
var keys = Object.keys(obj),
|
||||
res = {};
|
||||
|
||||
for (var i = keys.length; i--;) {
|
||||
res[keys[i]] = obj[keys[i]];
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
var nodesMatch = function(n1, n2) {
|
||||
var a1 = Object.keys(n1.attributes),
|
||||
a2 = Object.keys(n2.attributes);
|
||||
|
||||
return n1.type === n2.type && // compare META id
|
||||
n1.next.length === n2.next.length && // # of conns
|
||||
// compare attributes:
|
||||
// if they have a different number of attrs, don't bother
|
||||
// ow - check that the attributes match
|
||||
a1.length === a2.length &&
|
||||
a1.reduce((prev, attr) => {
|
||||
return prev &&
|
||||
n2.attributes[attr] === n1.attributes[attr];
|
||||
}, true);
|
||||
};
|
||||
|
||||
var createMap = function(nodes) {
|
||||
var result = {};
|
||||
|
||||
for (var i = nodes.length; i--;) {
|
||||
result[nodes[i].id] = nodes[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Convert nodes to the form:
|
||||
// - type: MetaType
|
||||
// id:
|
||||
// attributes:
|
||||
// - attr: 2
|
||||
// next:
|
||||
// - id1
|
||||
|
||||
return GraphChecker;
|
||||
});
|
||||
@@ -24,6 +24,15 @@ define([
|
||||
return attr.output || 1;
|
||||
};
|
||||
|
||||
dimensionality.View = function(type, attr, prev) {
|
||||
// If there are no -1's then return the attributes
|
||||
// TODO
|
||||
// Else, use the previous dimensions to get the amount of data
|
||||
// then infer the omitted dimension
|
||||
// TODO
|
||||
return attr.output || 1;
|
||||
};
|
||||
|
||||
var PassThru = function(type, attr, prev) {
|
||||
if (!prev) {
|
||||
throw 'Cannot determine prev args of ' + type;
|
||||
@@ -50,6 +59,9 @@ define([
|
||||
'AddConstant',
|
||||
'MulConstant',
|
||||
|
||||
'BatchNormalization',
|
||||
'SpatialBatchNormalization',
|
||||
|
||||
// Math
|
||||
'Mul', // Does this really leave the size the same?
|
||||
'CMul',
|
||||
|
||||
+218
-61
@@ -13,63 +13,42 @@
|
||||
# This should have tests to verify that this document is up to date...
|
||||
# TODO
|
||||
|
||||
# TODO: Add the following layers
|
||||
#VolumetricMaxUnpooling
|
||||
#ConcatTable
|
||||
#Jacobian
|
||||
#SpatialCrossMapLRN
|
||||
#CAddTable
|
||||
#TanhShrink
|
||||
#MixtureTable
|
||||
#SpatialConvolutionLocal
|
||||
#BatchNormalization
|
||||
#MulConstant
|
||||
#NarrowTable
|
||||
#SplitTable
|
||||
#DotProduct
|
||||
#SpatialBatchNormalization
|
||||
#DepthConcat
|
||||
#CMulTable
|
||||
#Parallel
|
||||
#Log
|
||||
#SpatialDropout
|
||||
#hessian
|
||||
#ELU
|
||||
#CSubTable
|
||||
#VolumetricAveragePooling
|
||||
#StochasticGradient
|
||||
#SpatialContrastiveNormalization
|
||||
#Bilinear
|
||||
#Padding
|
||||
#Container
|
||||
#VolumetricFullConvolution
|
||||
#Concat
|
||||
#SparseJacobian
|
||||
#Contiguous
|
||||
#L1Cost
|
||||
#JoinTable
|
||||
#CosineDistance
|
||||
#Index
|
||||
#SpatialDivisiveNormalization
|
||||
#L1Penalty
|
||||
#Sequential
|
||||
#Cosine
|
||||
#Clamp
|
||||
#SpatialConvolutionMM
|
||||
#LogSigmoid
|
||||
#Threshold
|
||||
#ParallelTable
|
||||
#CDivTable
|
||||
#SpatialFullConvolutionMap
|
||||
#GradientReversal
|
||||
#SpatialMaxUnpooling
|
||||
#Transpose
|
||||
#SpatialFullConvolution
|
||||
#FlattenTable
|
||||
#Normalize
|
||||
#SpatialSoftMax
|
||||
#SelectTable
|
||||
#SpatialFractionalMaxPooling
|
||||
Containers:
|
||||
- Concat:
|
||||
- dim:
|
||||
min: 1 # TODO: Figure out exactly how this works
|
||||
|
||||
Module:
|
||||
- SpatialBatchNormalization:
|
||||
- input:
|
||||
ignore: true # change this to `infer: 'dimensionality'`
|
||||
- eps:
|
||||
default: 0.00001
|
||||
- momentum:
|
||||
default: 0.1
|
||||
- affine:
|
||||
default: true
|
||||
|
||||
- BatchNormalization:
|
||||
- input:
|
||||
ignore: true # change this to `infer: 'dimensionality'`
|
||||
- eps:
|
||||
default: 0.00001
|
||||
- momentum:
|
||||
default: 0.1
|
||||
- affine:
|
||||
default: true
|
||||
|
||||
- Threshold:
|
||||
- threshold:
|
||||
type: float
|
||||
default: 1e-6
|
||||
- value:
|
||||
type: float
|
||||
default: 0
|
||||
- inplace:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
ConvLayer:
|
||||
- TemporalConvolution:
|
||||
@@ -85,9 +64,8 @@ ConvLayer:
|
||||
- TemporalMaxPooling:
|
||||
- kernelWidth:
|
||||
min: 1
|
||||
- step:
|
||||
- step: # FIXME: defaults to 'kernelWidth'
|
||||
min: 1
|
||||
# TODO: What is the default?
|
||||
|
||||
- TemporalSubSampling:
|
||||
- inputFrameSize:
|
||||
@@ -101,11 +79,33 @@ ConvLayer:
|
||||
- LookupTable:
|
||||
- nIndex:
|
||||
min: 1
|
||||
# TODO: What is the default?
|
||||
- sizes:
|
||||
min: 1
|
||||
|
||||
# Spatial Modules
|
||||
- SpatialConvolutionMM:
|
||||
- nInputPlane: # TODO: Infer this
|
||||
min: 1
|
||||
- nOutputPlane:
|
||||
min: 1
|
||||
- kernelWidth:
|
||||
min: 1
|
||||
- kernelHeight:
|
||||
min: 1
|
||||
|
||||
- strideWidth:
|
||||
min: 1
|
||||
default: 1
|
||||
- strideWidth:
|
||||
min: 1
|
||||
default: 1
|
||||
- padWidth:
|
||||
min: 0
|
||||
default: 0
|
||||
- padHeight: # FIXME: this defaults to padWidth - not 0
|
||||
min: 0
|
||||
default: 0
|
||||
|
||||
- SpatialConvolution:
|
||||
- nInputPlane:
|
||||
min: 1
|
||||
@@ -216,6 +216,103 @@ ConvLayer:
|
||||
- kernel:
|
||||
min: 1
|
||||
|
||||
- SpatialCrossMapLRN:
|
||||
- size:
|
||||
min: 1
|
||||
- alpha:
|
||||
default: 0.0001
|
||||
- beta:
|
||||
default: 0.75
|
||||
- k:
|
||||
default: 1
|
||||
|
||||
- SpatialConvolutionLocal:
|
||||
- nInputPlane:
|
||||
min: 1
|
||||
- nOutputPlane:
|
||||
min: 1
|
||||
- inputWidth: # TODO: infer this
|
||||
min: 1
|
||||
- inputHeight: # TODO: infer this
|
||||
min: 1
|
||||
- kernelWidth:
|
||||
min: 1
|
||||
- kernelHeight:
|
||||
min: 1
|
||||
- strideWidth:
|
||||
min: 1
|
||||
default: 1
|
||||
- strideHeight:
|
||||
min: 1
|
||||
default: 1
|
||||
- padWidth:
|
||||
min: 0
|
||||
default: 0
|
||||
- padHeight: # FIXME: this defaults to padWidth - not 0
|
||||
min: 0
|
||||
default: 0
|
||||
|
||||
- SpatialDropout:
|
||||
- probability:
|
||||
default: 0.5
|
||||
|
||||
- SpatialFractionalMaxPooling:
|
||||
- poolWidth:
|
||||
- min: 2
|
||||
- poolHeight:
|
||||
- min: 2
|
||||
- outWidth: # Optionally, these could be ratioW/H FIXME
|
||||
- min: 1
|
||||
- outHeight:
|
||||
- min: 1
|
||||
|
||||
- SpatialDivisiveNormalization:
|
||||
- nInputPlane: # TODO: infer this
|
||||
- default: 1
|
||||
- kernel: # TODO: this is a tensor type...
|
||||
- threshold:
|
||||
- default: 0.0001
|
||||
- thresval:
|
||||
- default: 0.0001 # FIXME: this defaults to "threshold"
|
||||
|
||||
- SpatialContrastiveNormalization:
|
||||
- nInputPlane: # TODO: infer this
|
||||
- default: 1
|
||||
- kernel: # TODO: this is a tensor type...
|
||||
- threshold:
|
||||
- default: 0.0001
|
||||
- thresval:
|
||||
- default: 0.0001 # FIXME: this defaults to "threshold"
|
||||
|
||||
- SpatialFullConvolution:
|
||||
- nInputPlane: # TODO: should infer this
|
||||
min: 1
|
||||
- nOutputPlane:
|
||||
min: 1
|
||||
- kernelWidth:
|
||||
min: 1
|
||||
- kernelHeight:
|
||||
min: 1
|
||||
- strideWidth:
|
||||
min: 1
|
||||
default: 1
|
||||
- strideHeight:
|
||||
min: 1
|
||||
default: 1
|
||||
- padWidth:
|
||||
min: 0
|
||||
default: 0
|
||||
- padHeight:
|
||||
min: 0
|
||||
default: 0
|
||||
- adjWidth:
|
||||
min: 0
|
||||
default: 0
|
||||
- adjHeight:
|
||||
min: 0
|
||||
default: 0
|
||||
# Additional constraint:
|
||||
|
||||
# Volumetric Modules
|
||||
- VolumetricConvolution:
|
||||
- nInputPlane:
|
||||
@@ -317,7 +414,8 @@ SimpleLayer:
|
||||
- dimensions:
|
||||
type: list
|
||||
- View:
|
||||
- sizes:
|
||||
- sizes: # list
|
||||
type: list
|
||||
min: 0
|
||||
- Select:
|
||||
- dimensions:
|
||||
@@ -359,6 +457,9 @@ TransferLayer:
|
||||
- MulConstant:
|
||||
- scalar:
|
||||
type: float
|
||||
min: 1
|
||||
- inplace:
|
||||
default: false
|
||||
|
||||
Criterion:
|
||||
- BCECriterion
|
||||
@@ -380,6 +481,62 @@ Criterion:
|
||||
- ClassNLLCriterion
|
||||
- ParallelCriterion
|
||||
|
||||
MiscLayers:
|
||||
- Jacobian
|
||||
- ConcatTable
|
||||
- CMulTable
|
||||
- CAddTable
|
||||
- TanhShrink
|
||||
- Padding:
|
||||
- dim:
|
||||
- pad:
|
||||
min: 0
|
||||
- nInputDim: # TODO: infer?
|
||||
min: 1
|
||||
- value:
|
||||
min: 0
|
||||
default: 0
|
||||
|
||||
# TODO: Add the following layers
|
||||
#VolumetricMaxUnpooling
|
||||
# Takes a poolingModule as an arg...
|
||||
|
||||
#MixtureTable
|
||||
#NarrowTable
|
||||
#SplitTable
|
||||
#DotProduct
|
||||
#DepthConcat
|
||||
#Parallel
|
||||
#Log
|
||||
#hessian
|
||||
#ELU
|
||||
#CSubTable
|
||||
#VolumetricAveragePooling
|
||||
#StochasticGradient
|
||||
#Bilinear
|
||||
#VolumetricFullConvolution
|
||||
#SparseJacobian
|
||||
#Contiguous
|
||||
#L1Cost
|
||||
#JoinTable
|
||||
#CosineDistance
|
||||
#Index
|
||||
#L1Penalty
|
||||
#Cosine
|
||||
#Clamp
|
||||
#SpatialConvolutionMM
|
||||
#LogSigmoid
|
||||
#ParallelTable
|
||||
#CDivTable
|
||||
#SpatialFullConvolutionMap
|
||||
#GradientReversal
|
||||
#SpatialMaxUnpooling
|
||||
#Transpose
|
||||
#Normalize
|
||||
#SpatialSoftMax
|
||||
#SelectTable
|
||||
#FlattenTable
|
||||
|
||||
# CONTAINERS and TableLayouts
|
||||
# Some of these are captured by the visual structure of the architecture and are not needed
|
||||
# as explicit layers in the metamodel
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*globals define*/
|
||||
/*jshint node:true, browser:true*/
|
||||
|
||||
/**
|
||||
* Generated by PluginGenerator 0.14.0 from webgme on Thu Apr 07 2016 06:13:30 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'deepforge/GraphChecker',
|
||||
'plugin/PluginBase'
|
||||
], function (
|
||||
GraphChecker,
|
||||
PluginBase
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initializes a new instance of GenerateYaml.
|
||||
* @class
|
||||
* @augments {PluginBase}
|
||||
* @classdesc This class represents the plugin GenerateYaml.
|
||||
* @constructor
|
||||
*/
|
||||
var GenerateYaml = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
};
|
||||
|
||||
// Prototypal inheritance from PluginBase.
|
||||
GenerateYaml.prototype = Object.create(PluginBase.prototype);
|
||||
GenerateYaml.prototype.constructor = GenerateYaml;
|
||||
|
||||
/**
|
||||
* Gets the name of the GenerateYaml.
|
||||
* @returns {string} The name of the plugin.
|
||||
* @public
|
||||
*/
|
||||
GenerateYaml.prototype.getName = function () {
|
||||
return 'GenerateYaml';
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the semantic version (semver.org) of the GenerateYaml.
|
||||
* @returns {string} The version of the plugin.
|
||||
* @public
|
||||
*/
|
||||
GenerateYaml.prototype.getVersion = function () {
|
||||
return '0.1.0';
|
||||
};
|
||||
|
||||
/**
|
||||
* Main function for the plugin to execute. This will perform the execution.
|
||||
* Notes:
|
||||
* - Always log with the provided logger.[error,warning,info,debug].
|
||||
* - Do NOT put any user interaction logic UI, etc. inside this method.
|
||||
* - callback always has to be called even if error happened.
|
||||
*
|
||||
* @param {function(string, plugin.PluginResult)} callback - the result callback
|
||||
*/
|
||||
GenerateYaml.prototype.main = function (callback) {
|
||||
// Use self to access core, project, result, logger etc from PluginBase.
|
||||
// These are all instantiated at this point.
|
||||
|
||||
var converter = new GraphChecker(this.core),
|
||||
name = this.core.getAttribute(this.activeNode, 'name') + '.yml';
|
||||
|
||||
this.core.loadChildren(this.activeNode)
|
||||
.then(children => {
|
||||
var yaml = converter.gme(children).to.yaml();
|
||||
|
||||
// Save the yaml output
|
||||
this.blobClient.putFile(name, yaml)
|
||||
.then(hash => {
|
||||
this.result.addArtifact(hash);
|
||||
this.result.setSuccess(true);
|
||||
callback(null, this.result);
|
||||
})
|
||||
.catch(err => callback(err));
|
||||
});
|
||||
};
|
||||
|
||||
return GenerateYaml;
|
||||
});
|
||||
@@ -6,11 +6,16 @@
|
||||
*/
|
||||
|
||||
define([
|
||||
'plugin/PluginConfig',
|
||||
'deepforge/layer-args',
|
||||
'./lua',
|
||||
'./nn',
|
||||
'plugin/PluginBase'
|
||||
], function (
|
||||
PluginConfig,
|
||||
PluginBase) {
|
||||
LayerDict,
|
||||
luajs,
|
||||
createNNSearcher,
|
||||
PluginBase
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
@@ -57,57 +62,8 @@ define([
|
||||
ImportTorch.prototype.getConfigStructure = function () {
|
||||
return [
|
||||
{
|
||||
name: 'species',
|
||||
displayName: 'Animal Species',
|
||||
regex: '^[a-zA-Z]+$',
|
||||
regexMessage: 'Name can only contain English characters!',
|
||||
description: 'Which species does the animal belong to.',
|
||||
value: 'Horse',
|
||||
valueType: 'string',
|
||||
readOnly: false
|
||||
},
|
||||
{
|
||||
name: 'age',
|
||||
displayName: 'Age',
|
||||
description: 'How old is the animal.',
|
||||
value: 3,
|
||||
valueType: 'number',
|
||||
minValue: 0,
|
||||
maxValue: 10000,
|
||||
readOnly: false
|
||||
},
|
||||
{
|
||||
name: 'carnivore',
|
||||
displayName: 'Carnivore',
|
||||
description: 'Does the animal eat other animals?',
|
||||
value: false,
|
||||
valueType: 'boolean',
|
||||
readOnly: false
|
||||
},
|
||||
{
|
||||
name: 'classification',
|
||||
displayName: 'Classification',
|
||||
description: '',
|
||||
value: 'Vertebrates',
|
||||
valueType: 'string',
|
||||
valueItems: [
|
||||
'Vertebrates',
|
||||
'Invertebrates',
|
||||
'Unknown'
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'color',
|
||||
displayName: 'Color',
|
||||
description: 'The hex color code for the animal.',
|
||||
readOnly: false,
|
||||
value: '#FF0000',
|
||||
regex: '^#([A-Fa-f0-9]{6})$',
|
||||
valueType: 'string'
|
||||
},
|
||||
{
|
||||
name: 'anAsset',
|
||||
displayName: 'Document',
|
||||
name: 'srcHash',
|
||||
displayName: 'Torch Source Code',
|
||||
description: '',
|
||||
value: '',
|
||||
valueType: 'asset',
|
||||
@@ -127,42 +83,66 @@ define([
|
||||
* @param {function(string, plugin.PluginResult)} callback - the result callback
|
||||
*/
|
||||
ImportTorch.prototype.main = function (callback) {
|
||||
// Use self to access core, project, result, logger etc from PluginBase.
|
||||
// These are all instantiated at this point.
|
||||
var self = this,
|
||||
nodeObject;
|
||||
var srcHash = this.getCurrentConfig().srcHash;
|
||||
|
||||
if (!srcHash) {
|
||||
return callback('Torch code not provided.', this.result);
|
||||
}
|
||||
|
||||
// Using the logger.
|
||||
self.logger.debug('This is a debug message.');
|
||||
self.logger.info('This is an info message.');
|
||||
self.logger.warn('This is a warning message.');
|
||||
self.logger.error('This is an error message.');
|
||||
this.blobClient.getMetadata(srcHash)
|
||||
.then(mdata => { // Create the new model
|
||||
var name = mdata.name.replace('.lua', '');
|
||||
this.tgtNode = this.core.createNode({
|
||||
base: this.META.Architecture,
|
||||
parent: this.rootNode
|
||||
});
|
||||
this.core.setAttribute(this.tgtNode, 'name', name);
|
||||
return this.blobClient.getObjectAsString(srcHash);
|
||||
})
|
||||
.then(src => { // Retrieved the source code
|
||||
this.logger.debug('Retrieved the torch src');
|
||||
this.context = luajs.newContext();
|
||||
this.context.loadStdLib();
|
||||
|
||||
// Using the coreAPI to make changes.
|
||||
this.loadNNMock();
|
||||
|
||||
nodeObject = self.activeNode;
|
||||
// Cross compile to js and run
|
||||
this.bin = this.context.loadString(src);
|
||||
this.bin();
|
||||
|
||||
self.core.setAttribute(nodeObject, 'name', 'My new obj');
|
||||
self.core.setRegistry(nodeObject, 'position', {x: 70, y: 70});
|
||||
this.afterExecution();
|
||||
|
||||
return this.save('ImportTorch updated model.');
|
||||
})
|
||||
.then(() => { // changes saved successfully
|
||||
this.result.setSuccess(true);
|
||||
callback(null, this.result);
|
||||
})
|
||||
.fail(err =>
|
||||
callback(err, this.result)
|
||||
);
|
||||
};
|
||||
|
||||
// Obtain the current user configuration.
|
||||
var currentConfig = self.getCurrentConfig();
|
||||
self.logger.info('Current configuration ' + JSON.stringify(currentConfig, null, 4));
|
||||
// Create the 'nn' shim and add it to the global context
|
||||
ImportTorch.prototype.loadNNMock = function () {
|
||||
// This needs a refactor...
|
||||
// createNN(this)
|
||||
var lib = createNNSearcher(this).bind(this.context);
|
||||
|
||||
// This will save the changes. If you don't want to save;
|
||||
// exclude self.save and call callback directly from this scope.
|
||||
self.save('ImportTorch updated model.', function (err) {
|
||||
if (err) {
|
||||
callback(err, self.result);
|
||||
return;
|
||||
// Create a "searcher" to allow this 'nn' to be in the lib path
|
||||
this.context._G.get('package').set('searchers', [function(name) {
|
||||
if (name === 'nn') {
|
||||
return lib;
|
||||
}
|
||||
self.result.setSuccess(true);
|
||||
callback(null, self.result);
|
||||
});
|
||||
}]);
|
||||
|
||||
// Some scripts don't include `require 'nn'`. I may have to add the
|
||||
// "nn" package to the global scope...
|
||||
};
|
||||
|
||||
ImportTorch.prototype.afterExecution = function () {
|
||||
// TODO
|
||||
};
|
||||
|
||||
return ImportTorch;
|
||||
});
|
||||
});
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,200 @@
|
||||
// This is the searcher for the mock library
|
||||
define([
|
||||
'deepforge/layer-args',
|
||||
'common/util/assert',
|
||||
'./lua'
|
||||
], function(
|
||||
LayerDict,
|
||||
assert,
|
||||
luajs
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var nop = function() {};
|
||||
var createSearcher = function(plugin) {
|
||||
var core = plugin.core,
|
||||
META = plugin.META,
|
||||
parent = plugin.tgtNode;
|
||||
|
||||
var connect = function(src, dst) {
|
||||
var conn = core.createNode({
|
||||
parent: parent,
|
||||
base: META.Connection
|
||||
});
|
||||
core.setPointer(conn, 'src', src);
|
||||
core.setPointer(conn, 'dst', dst);
|
||||
};
|
||||
|
||||
// nn drawing library
|
||||
var Layer = function(base, attrs, args) {
|
||||
this._base = base;
|
||||
this._attrs = attrs;
|
||||
for (var i = 0; i < attrs.length; i++) {
|
||||
this[attrs[i].name] = args[i];
|
||||
}
|
||||
|
||||
// inputs/outputs used for being added to containers
|
||||
this._cachedNode = null;
|
||||
this._inputs = [this._node()];
|
||||
this._outputs = [this._node()];
|
||||
};
|
||||
|
||||
Layer.prototype._node = function() {
|
||||
var attrs = this._attrs,
|
||||
name,
|
||||
node,
|
||||
value;
|
||||
|
||||
if (this._cachedNode) {
|
||||
// only generate a single node for each layer
|
||||
return this._cachedNode;
|
||||
}
|
||||
|
||||
assert(META[this._base], this._base + ' is not a supported type');
|
||||
node = core.createNode({
|
||||
base: META[this._base],
|
||||
parent: parent
|
||||
});
|
||||
|
||||
for (var i = this._attrs.length; i--;) {
|
||||
name = this._attrs[i].name;
|
||||
value = this[name];
|
||||
if ((typeof value) === 'object') {
|
||||
// special lua.js object
|
||||
value = value.valueOf();
|
||||
}
|
||||
|
||||
if (!this._attrs[i].ignore) {
|
||||
core.setAttribute(node, name, (value === undefined ? null : value));
|
||||
}
|
||||
}
|
||||
|
||||
this._cachedNode = node;
|
||||
return node;
|
||||
};
|
||||
|
||||
// Each container will have `inputs` and `outputs`
|
||||
var Container = function() {
|
||||
// inputs and outputs are webgme nodes
|
||||
this._inputs = [];
|
||||
this._outputs = [];
|
||||
};
|
||||
|
||||
Container.prototype.add = function(self, tlayer) {
|
||||
console.error('Add is not overridden!');
|
||||
};
|
||||
|
||||
var Sequential = function(attrs, args) {
|
||||
Container.call(this);
|
||||
};
|
||||
|
||||
Sequential.prototype = new Container();
|
||||
|
||||
Sequential.prototype.add = function(self, tlayer) {
|
||||
var layer = tlayer.get('_node'),
|
||||
nodes = layer._inputs,
|
||||
conn;
|
||||
|
||||
// If this._inputs is empty, add the layer to the inputs list
|
||||
if (this._inputs.length === 0) { // first node
|
||||
this._inputs = this._inputs.concat(nodes);
|
||||
} else {
|
||||
// connect all inputs of the added node to the current outputs
|
||||
this._outputs.forEach(src =>
|
||||
nodes.forEach(dst => connect(src, dst))
|
||||
);
|
||||
}
|
||||
this._outputs = layer._outputs;
|
||||
return self;
|
||||
};
|
||||
|
||||
var Concat = function(attrs, args) {
|
||||
Container.call(this);
|
||||
|
||||
// Create a concat node and add it to this._outputs
|
||||
var concat = new Layer('Concat', attrs, args);
|
||||
this._outputs.push(concat._node());
|
||||
};
|
||||
|
||||
Concat.prototype = new Container();
|
||||
|
||||
Concat.prototype.add = function(self, tlayer) {
|
||||
// Connect the tlayer outputs to this._outputs
|
||||
var layer = tlayer.get('_node'),
|
||||
concatLayer = this._outputs[0];
|
||||
|
||||
layer._outputs.forEach(output => connect(output, concatLayer));
|
||||
|
||||
// Connect the incomingly connected node to tlayer
|
||||
// TODO: This might not work if adding layers after this container is
|
||||
// added to some parent
|
||||
|
||||
// Add the layer's inputs to the inputs
|
||||
this._inputs = this._inputs.concat(layer._inputs);
|
||||
return self;
|
||||
};
|
||||
|
||||
// Special layers (with special functions - like 'add')
|
||||
var LAYERS = {
|
||||
Concat: Concat,
|
||||
Sequential: Sequential
|
||||
};
|
||||
|
||||
var CreateLayer = function(type) {
|
||||
var res = luajs.newContext()._G,
|
||||
attrs = [].slice.call(arguments, 1),
|
||||
proto,
|
||||
node;
|
||||
|
||||
if (LAYERS[type]) {
|
||||
node = new LAYERS[type](LayerDict[type] || [], attrs);
|
||||
proto = LAYERS[type].prototype;
|
||||
} else { // Call generic Layer with type name
|
||||
node = new Layer(type, LayerDict[type] || [], attrs);
|
||||
proto = Layer.prototype;
|
||||
}
|
||||
|
||||
res.set('_node', node);
|
||||
|
||||
// all public methods (and attributes) get added to lua context
|
||||
for (var fn in node) {
|
||||
if (fn.indexOf('_') !== 0) {
|
||||
if (typeof node[fn] === 'function') {
|
||||
res.set(fn, node[fn].bind(node));
|
||||
} else {
|
||||
res.set(fn, node[fn]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
// searcher
|
||||
return function (pkg) {
|
||||
if (pkg !== 'nn') {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Create the nn object
|
||||
var nn = luajs.newContext()._G,
|
||||
names = Object.keys(LayerDict);
|
||||
|
||||
for (var i = names.length; i--;) {
|
||||
nn.set(names[i], CreateLayer.bind(null, names[i]));
|
||||
}
|
||||
|
||||
// Additional containers the sequential layer
|
||||
var extraLayers = [
|
||||
'Sequential',
|
||||
'Concat'
|
||||
];
|
||||
|
||||
extraLayers.forEach(name => nn.set(name, CreateLayer.bind(null, name)));
|
||||
|
||||
this._G.set('nn', nn);
|
||||
return nn;
|
||||
};
|
||||
};
|
||||
|
||||
return createSearcher;
|
||||
});
|
||||
@@ -0,0 +1,173 @@
|
||||
/*globals define*/
|
||||
/*jshint node:true, browser:true*/
|
||||
|
||||
/**
|
||||
* Generated by PluginGenerator 0.14.0 from webgme on Fri Apr 08 2016 19:50:34 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'deepforge/GraphChecker',
|
||||
'plugin/PluginBase'
|
||||
], function (
|
||||
GraphChecker,
|
||||
PluginBase
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initializes a new instance of ImportYaml.
|
||||
* @class
|
||||
* @augments {PluginBase}
|
||||
* @classdesc This class represents the plugin ImportYaml.
|
||||
* @constructor
|
||||
*/
|
||||
var ImportYaml = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
};
|
||||
|
||||
// Prototypal inheritance from PluginBase.
|
||||
ImportYaml.prototype = Object.create(PluginBase.prototype);
|
||||
ImportYaml.prototype.constructor = ImportYaml;
|
||||
|
||||
/**
|
||||
* Gets the name of the ImportYaml.
|
||||
* @returns {string} The name of the plugin.
|
||||
* @public
|
||||
*/
|
||||
ImportYaml.prototype.getName = function () {
|
||||
return 'ImportYaml';
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the semantic version (semver.org) of the ImportYaml.
|
||||
* @returns {string} The version of the plugin.
|
||||
* @public
|
||||
*/
|
||||
ImportYaml.prototype.getVersion = function () {
|
||||
return '0.1.0';
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the configuration structure for the ImportYaml.
|
||||
* The ConfigurationStructure defines the configuration for the plugin
|
||||
* and will be used to populate the GUI when invoking the plugin from webGME.
|
||||
* @returns {object} The version of the plugin.
|
||||
* @public
|
||||
*/
|
||||
ImportYaml.prototype.getConfigStructure = function () {
|
||||
return [
|
||||
{
|
||||
name: 'srcHash',
|
||||
displayName: 'yaml nodes',
|
||||
description: '',
|
||||
value: '',
|
||||
valueType: 'asset',
|
||||
readOnly: false
|
||||
},
|
||||
{
|
||||
name: 'baseType',
|
||||
displayName: 'Base type of model container',
|
||||
description: '',
|
||||
value: '',
|
||||
valueType: 'string',
|
||||
readOnly: false
|
||||
},
|
||||
{
|
||||
name: 'connType',
|
||||
displayName: 'Base type of connections to use',
|
||||
description: '',
|
||||
value: '',
|
||||
valueType: 'string',
|
||||
readOnly: false
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Main function for the plugin to execute. This will perform the execution.
|
||||
* Notes:
|
||||
* - Always log with the provided logger.[error,warning,info,debug].
|
||||
* - Do NOT put any user interaction logic UI, etc. inside this method.
|
||||
* - callback always has to be called even if error happened.
|
||||
*
|
||||
* @param {function(string, plugin.PluginResult)} callback - the result callback
|
||||
*/
|
||||
ImportYaml.prototype.main = function (callback) {
|
||||
var config = this.getCurrentConfig(),
|
||||
srcHash = config.srcHash,
|
||||
base = config.baseType || 'FCO';
|
||||
|
||||
if (!srcHash) {
|
||||
return callback('yaml not provided.', this.result);
|
||||
}
|
||||
|
||||
this.blobClient.getMetadata(srcHash)
|
||||
.then(mdata => { // Create the new model
|
||||
var name = mdata.name.replace(/.ya?ml$/, '');
|
||||
this.tgtNode = this.core.createNode({
|
||||
base: this.META[base],
|
||||
parent: this.rootNode
|
||||
});
|
||||
this.core.setAttribute(this.tgtNode, 'name', name);
|
||||
return this.blobClient.getObjectAsString(srcHash);
|
||||
})
|
||||
.then(src => { // Retrieved the source code
|
||||
this.logger.debug('Retrieved the yaml');
|
||||
var converter = new GraphChecker(this.core),
|
||||
nodes = converter.yaml(src).nodes(),
|
||||
nodeMap = {};
|
||||
|
||||
nodes.forEach(node => nodeMap[node.id] = this.createNode(node));
|
||||
|
||||
// Create all the connections
|
||||
nodes.forEach(node => {
|
||||
node.next.map(id => nodeMap[id])
|
||||
.forEach(next => this.connect(nodeMap[node.id], next));
|
||||
});
|
||||
|
||||
return this.save('ImportYaml updated model.');
|
||||
})
|
||||
.then(() => { // changes saved successfully
|
||||
this.result.setSuccess(true);
|
||||
callback(null, this.result);
|
||||
})
|
||||
.fail(err =>
|
||||
callback(err, this.result)
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
ImportYaml.prototype.createNode = function (desc) {
|
||||
var node,
|
||||
attrs = Object.keys(desc.attributes);
|
||||
|
||||
node = this.core.createNode({
|
||||
base: this.META[desc.type],
|
||||
parent: this.tgtNode
|
||||
});
|
||||
|
||||
// Add attributes
|
||||
attrs.forEach(attr =>
|
||||
this.core.setAttribute(node, attr, desc.attributes[attr])
|
||||
);
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
ImportYaml.prototype.connect = function (src, dst) {
|
||||
var base = this.getCurrentConfig().connType || 'FCO',
|
||||
conn;
|
||||
|
||||
conn = this.core.createNode({
|
||||
base: this.META[base],
|
||||
parent: this.tgtNode
|
||||
});
|
||||
|
||||
this.core.setPointer(conn, 'src', src);
|
||||
this.core.setPointer(conn, 'dst', dst);
|
||||
return conn;
|
||||
};
|
||||
|
||||
return ImportYaml;
|
||||
});
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -0,0 +1,20 @@
|
||||
env:
|
||||
browser: false
|
||||
node: true
|
||||
es6: true
|
||||
extends: 'eslint:recommended'
|
||||
parserOptions:
|
||||
sourceType: module
|
||||
rules:
|
||||
indent:
|
||||
- error
|
||||
- 4
|
||||
linebreak-style:
|
||||
- error
|
||||
- unix
|
||||
quotes:
|
||||
- error
|
||||
- single
|
||||
semi:
|
||||
- error
|
||||
- always
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"esnext": true,
|
||||
"node": true
|
||||
}
|
||||
@@ -8,7 +8,7 @@ var testFixture = require('../../globals'),
|
||||
path = testFixture.path,
|
||||
jszip = require('jszip'),
|
||||
fs = require('fs'),
|
||||
TEST_CASE_DIR = path.join(__dirname, '..', 'test-cases'),
|
||||
TEST_CASE_DIR = path.join(__dirname, '..', '..', 'test-cases', 'code'),
|
||||
SEED_DIR = path.join(testFixture.SEED_DIR, '..', 'devTests');
|
||||
|
||||
describe('GenerateArchitecture', function () {
|
||||
@@ -85,8 +85,8 @@ describe('GenerateArchitecture', function () {
|
||||
|
||||
describe('test cases', function() {
|
||||
var cases = [
|
||||
['/R', 'basic.lua'],
|
||||
['/e', 'basic-transfers.lua']
|
||||
['/w', 'basic.lua'],
|
||||
['/d', 'basic-transfers.lua']
|
||||
];
|
||||
|
||||
var runTest = function(pair, done) {
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*jshint node:true, mocha:true*/
|
||||
/**
|
||||
* Generated by PluginGenerator 0.14.0 from webgme on Thu Apr 07 2016 06:13:30 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var testFixture = require('../../globals'),
|
||||
path = testFixture.path,
|
||||
BASE_DIR = path.join(testFixture.SEED_DIR, '..');
|
||||
|
||||
describe('GenerateYaml', function () {
|
||||
var gmeConfig = testFixture.getGmeConfig(),
|
||||
expect = testFixture.expect,
|
||||
logger = testFixture.logger.fork('GenerateYaml'),
|
||||
PluginCliManager = testFixture.WebGME.PluginCliManager,
|
||||
GraphChecker = testFixture.requirejs('deepforge/GraphChecker'),
|
||||
projectName = 'testProject',
|
||||
pluginName = 'GenerateYaml',
|
||||
project,
|
||||
gmeAuth,
|
||||
storage,
|
||||
commitHash;
|
||||
|
||||
before(function (done) {
|
||||
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
|
||||
.then(function (gmeAuth_) {
|
||||
gmeAuth = gmeAuth_;
|
||||
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
|
||||
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
|
||||
return storage.openDatabase();
|
||||
})
|
||||
.then(function () {
|
||||
var importParam = {
|
||||
projectSeed: testFixture.path.join(BASE_DIR, 'devTests', 'devTests.zip'),
|
||||
projectName: projectName,
|
||||
branchName: 'master',
|
||||
logger: logger,
|
||||
gmeConfig: gmeConfig
|
||||
};
|
||||
|
||||
return testFixture.importProject(storage, importParam);
|
||||
})
|
||||
.then(function (importResult) {
|
||||
project = importResult.project;
|
||||
commitHash = importResult.commitHash;
|
||||
return project.createBranch('test', commitHash);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
storage.closeDatabase()
|
||||
.then(function () {
|
||||
return gmeAuth.unload();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
// '/i' should be 'basic.yml'
|
||||
it('should run plugin and NOT update the branch', function (done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {
|
||||
},
|
||||
context = {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '/960660211',
|
||||
};
|
||||
|
||||
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
|
||||
expect(err).to.equal(null);
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
// TODO: Generate some yaml and compare it to the yaml in /test/test-cases/models
|
||||
|
||||
project.getBranchHash('test')
|
||||
.then(function (branchHash) {
|
||||
expect(branchHash).to.equal(commitHash);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,15 +4,39 @@
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var testFixture = require('../../globals');
|
||||
var testFixture = require('../../globals'),
|
||||
path = testFixture.path,
|
||||
fs = require('fs'),
|
||||
BASE_DIR = path.join(testFixture.SEED_DIR, '..'),
|
||||
SKIP_TESTS = [ // FIXME: This should be empty when actually committing
|
||||
'alexnetowtbn.lua',
|
||||
'alexnet.lua',
|
||||
'ninbn.lua',
|
||||
'overfeat.lua',
|
||||
'vggbn.lua',
|
||||
'basic3.lua',
|
||||
'googlenet.lua',
|
||||
'basic4.lua'
|
||||
],
|
||||
ONLY_TESTS = [
|
||||
];
|
||||
|
||||
describe('ImportTorch', function () {
|
||||
var gmeConfig = testFixture.getGmeConfig(),
|
||||
Q = testFixture.Q,
|
||||
GraphChecker = testFixture.requirejs('deepforge/GraphChecker'),
|
||||
TEST_CASE_DIR = path.join(__dirname, '..', '..', 'test-cases', 'code'),
|
||||
YAML_DIR = path.join(__dirname, '..', '..', 'test-cases', 'models'),
|
||||
expect = testFixture.expect,
|
||||
logger = testFixture.logger.fork('NewPlugin'),
|
||||
logger = testFixture.logger.fork('ImportTorch'),
|
||||
PluginCliManager = testFixture.WebGME.PluginCliManager,
|
||||
BlobClient = require('webgme/src/server/middleware/blob/BlobClientWithFSBackend'),
|
||||
blobClient = new BlobClient(gmeConfig, logger),
|
||||
projectName = 'testProject',
|
||||
pluginName = 'ImportTorch',
|
||||
rootNode,
|
||||
checker,
|
||||
core,
|
||||
project,
|
||||
gmeAuth,
|
||||
storage,
|
||||
@@ -28,7 +52,7 @@ describe('ImportTorch', function () {
|
||||
})
|
||||
.then(function () {
|
||||
var importParam = {
|
||||
projectSeed: testFixture.path.join(testFixture.SEED_DIR, 'DevMinimal.zip'),
|
||||
projectSeed: testFixture.path.join(BASE_DIR, 'devTests', 'devTests.zip'),
|
||||
projectName: projectName,
|
||||
branchName: 'master',
|
||||
logger: logger,
|
||||
@@ -40,8 +64,14 @@ describe('ImportTorch', function () {
|
||||
.then(function (importResult) {
|
||||
project = importResult.project;
|
||||
commitHash = importResult.commitHash;
|
||||
core = importResult.core;
|
||||
rootNode = importResult.rootNode;
|
||||
checker = new GraphChecker(core);
|
||||
return project.createBranch('test', commitHash);
|
||||
})
|
||||
.then(function () {
|
||||
return project.getBranchHash('test');
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
@@ -53,7 +83,7 @@ describe('ImportTorch', function () {
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should run plugin and update the branch', function (done) {
|
||||
it('should require Torch code', function (done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {
|
||||
},
|
||||
@@ -61,19 +91,98 @@ describe('ImportTorch', function () {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '/960660211',
|
||||
activeNode: '',
|
||||
};
|
||||
|
||||
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
|
||||
expect(err).to.equal(null);
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
expect(err).to.equal('Torch code not provided.');
|
||||
expect(pluginResult.success).to.equal(false);
|
||||
|
||||
project.getBranchHash('test')
|
||||
.then(function (branchHash) {
|
||||
expect(branchHash).to.not.equal(commitHash);
|
||||
})
|
||||
.nodeify(done);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
var runTest = function(name, done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {},
|
||||
context = {
|
||||
project: project,
|
||||
branchName: 'test',
|
||||
activeNode: '',
|
||||
},
|
||||
data = fs.readFileSync(path.join(TEST_CASE_DIR, name), 'utf8'),
|
||||
ymlFile = path.join(YAML_DIR, name.replace(/lua$/, 'yml')),
|
||||
yml = fs.readFileSync(ymlFile, 'utf8'),
|
||||
initModels;
|
||||
|
||||
// Load the children from the head of the 'test' branch
|
||||
project.getBranchHash('test')
|
||||
.then(function (branchHash) {
|
||||
return Q.ninvoke(project, 'loadObject', branchHash);
|
||||
})
|
||||
.then(function (commitObject) {
|
||||
return Q.ninvoke(core, 'loadRoot', commitObject.root);
|
||||
})
|
||||
.then(function (root) {
|
||||
return core.loadChildren(root);
|
||||
})
|
||||
.then(children => {
|
||||
initModels = children.map(core.getPath);
|
||||
return blobClient.putFile(name, data); // upload the file
|
||||
})
|
||||
.then(hash => {
|
||||
pluginConfig.srcHash = hash;
|
||||
return Q.nfcall(
|
||||
manager.executePlugin.bind(manager),
|
||||
pluginName,
|
||||
pluginConfig,
|
||||
context
|
||||
);
|
||||
})
|
||||
.then(pluginResult => {
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
return project.getBranchHash('test');
|
||||
})
|
||||
// Use the check-model object to check the result models!
|
||||
.then(function (branchHash) {
|
||||
return Q.ninvoke(project, 'loadObject', branchHash);
|
||||
})
|
||||
.then(function (commitObject) {
|
||||
return Q.ninvoke(core, 'loadRoot', commitObject.root);
|
||||
})
|
||||
.then(function (root) {
|
||||
return core.loadChildren(root);
|
||||
})
|
||||
.then(children => {
|
||||
var newModel = children.find(model =>
|
||||
initModels.indexOf(core.getPath(model)) === -1);
|
||||
|
||||
expect(initModels.length+1).to.equal(children.length);
|
||||
expect(!!newModel).to.equal(true); // found the new model
|
||||
return core.loadChildren(newModel);
|
||||
})
|
||||
.then(children => {
|
||||
// Retrieve the id of the newly generated node
|
||||
// wrong solution!!!
|
||||
var map = checker.gme(children).map.to.yaml(yml);
|
||||
|
||||
expect(!!map).to.equal(true);
|
||||
})
|
||||
.fail(err => {
|
||||
throw err;
|
||||
})
|
||||
.nodeify(done);
|
||||
};
|
||||
|
||||
describe('run test cases', function() {
|
||||
var cases = fs.readdirSync(TEST_CASE_DIR)
|
||||
.filter(name => path.extname(name) === '.lua')
|
||||
// Skipping/only-ing tests
|
||||
.filter(name => SKIP_TESTS.indexOf(name) === -1)
|
||||
.filter(name => !ONLY_TESTS.length || ONLY_TESTS.indexOf(name) > -1);
|
||||
|
||||
// one test for each test name
|
||||
cases.forEach(name => it(`should run test "${name}"`, runTest.bind(this, name)));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/*jshint node:true, mocha:true*/
|
||||
/**
|
||||
* Generated by PluginGenerator 0.14.0 from webgme on Fri Apr 08 2016 19:50:34 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var testFixture = require('../../globals'),
|
||||
path = testFixture.path,
|
||||
fs = require('fs'),
|
||||
BASE_DIR = path.join(testFixture.SEED_DIR, '..');
|
||||
|
||||
describe('ImportYaml', function () {
|
||||
var gmeConfig = testFixture.getGmeConfig(),
|
||||
Q = testFixture.Q,
|
||||
GraphChecker = testFixture.requirejs('deepforge/GraphChecker'),
|
||||
TEST_CASE_DIR = path.join(__dirname, '..', '..', 'test-cases', 'code'),
|
||||
YAML_DIR = path.join(__dirname, '..', '..', 'test-cases', 'models'),
|
||||
expect = testFixture.expect,
|
||||
logger = testFixture.logger.fork('ImportYaml'),
|
||||
PluginCliManager = testFixture.WebGME.PluginCliManager,
|
||||
BlobClient = require('webgme/src/server/middleware/blob/BlobClientWithFSBackend'),
|
||||
blobClient = new BlobClient(gmeConfig, logger),
|
||||
projectName = 'testProject',
|
||||
pluginName = 'ImportYaml',
|
||||
rootNode,
|
||||
checker,
|
||||
core,
|
||||
project,
|
||||
gmeAuth,
|
||||
storage,
|
||||
commitHash;
|
||||
|
||||
before(function (done) {
|
||||
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
|
||||
.then(function (gmeAuth_) {
|
||||
gmeAuth = gmeAuth_;
|
||||
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
|
||||
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
|
||||
return storage.openDatabase();
|
||||
})
|
||||
.then(function () {
|
||||
var importParam = {
|
||||
projectSeed: testFixture.path.join(BASE_DIR, 'devTests', 'devTests.zip'),
|
||||
projectName: projectName,
|
||||
branchName: 'master',
|
||||
logger: logger,
|
||||
gmeConfig: gmeConfig
|
||||
};
|
||||
|
||||
return testFixture.importProject(storage, importParam);
|
||||
})
|
||||
.then(function (importResult) {
|
||||
project = importResult.project;
|
||||
commitHash = importResult.commitHash;
|
||||
core = importResult.core;
|
||||
rootNode = importResult.rootNode;
|
||||
checker = new GraphChecker(core);
|
||||
return project.createBranch('test', commitHash);
|
||||
})
|
||||
.then(function () {
|
||||
return project.getBranchHash('test');
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
storage.closeDatabase()
|
||||
.then(function () {
|
||||
return gmeAuth.unload();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should require yaml file', function (done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {
|
||||
},
|
||||
context = {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '',
|
||||
};
|
||||
|
||||
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
|
||||
expect(err).to.equal('yaml not provided.');
|
||||
expect(pluginResult.success).to.equal(false);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
var runTest = function(name, done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {},
|
||||
context = {
|
||||
project: project,
|
||||
branchName: 'test',
|
||||
activeNode: '',
|
||||
},
|
||||
data = fs.readFileSync(path.join(YAML_DIR, name), 'utf8'),
|
||||
ymlFile = path.join(YAML_DIR, name.replace(/lua$/, 'yml')),
|
||||
yml = fs.readFileSync(ymlFile, 'utf8'),
|
||||
initModels;
|
||||
|
||||
// Load the children from the head of the 'test' branch
|
||||
project.getBranchHash('test')
|
||||
.then(function (branchHash) {
|
||||
return Q.ninvoke(project, 'loadObject', branchHash);
|
||||
})
|
||||
.then(function (commitObject) {
|
||||
return Q.ninvoke(core, 'loadRoot', commitObject.root);
|
||||
})
|
||||
.then(function (root) {
|
||||
return core.loadChildren(root);
|
||||
})
|
||||
.then(children => {
|
||||
initModels = children.map(core.getPath);
|
||||
return blobClient.putFile(name, data); // upload the file
|
||||
})
|
||||
.then(hash => {
|
||||
pluginConfig.srcHash = hash;
|
||||
return Q.nfcall(
|
||||
manager.executePlugin.bind(manager),
|
||||
pluginName,
|
||||
pluginConfig,
|
||||
context
|
||||
);
|
||||
})
|
||||
.then(pluginResult => {
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
return project.getBranchHash('test');
|
||||
})
|
||||
// Use the check-model object to check the result models!
|
||||
.then(function (branchHash) {
|
||||
return Q.ninvoke(project, 'loadObject', branchHash);
|
||||
})
|
||||
.then(function (commitObject) {
|
||||
return Q.ninvoke(core, 'loadRoot', commitObject.root);
|
||||
})
|
||||
.then(function (root) {
|
||||
return core.loadChildren(root);
|
||||
})
|
||||
.then(children => {
|
||||
var newModel = children.find(model =>
|
||||
initModels.indexOf(core.getPath(model)) === -1);
|
||||
|
||||
expect(initModels.length+1).to.equal(children.length);
|
||||
expect(!!newModel).to.equal(true); // found the new model
|
||||
return core.loadChildren(newModel);
|
||||
})
|
||||
.then(children => {
|
||||
// Retrieve the id of the newly generated node
|
||||
var map = checker.gme(children).map.to.yaml(yml);
|
||||
|
||||
expect(!!map).to.equal(true);
|
||||
})
|
||||
.fail(err => {
|
||||
throw err;
|
||||
})
|
||||
.nodeify(done);
|
||||
};
|
||||
|
||||
describe('run test cases', function() {
|
||||
var cases = fs.readdirSync(YAML_DIR)
|
||||
.filter(name => path.extname(name) === '.yml');
|
||||
|
||||
// one test for each test name
|
||||
cases.forEach(name => it(`should run test "${name}"`, runTest.bind(this, name)));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
-- thanks to https://github.com/soumith/imagenet-multiGPU.torch for this example
|
||||
require 'nn'
|
||||
|
||||
local nClasses = 10;
|
||||
local nGPU = 1;
|
||||
|
||||
local features = nn.Concat(2)
|
||||
--local fb1 = nn.Sequential() -- branch 1
|
||||
--fb1:add(nn.SpatialConvolution(3,48,11,11,4,4,2,2)) -- 224 -> 55
|
||||
--fb1:add(nn.ReLU(true))
|
||||
--fb1:add(nn.SpatialMaxPooling(3,3,2,2)) -- 55 -> 27
|
||||
--fb1:add(nn.SpatialConvolution(48,128,5,5,1,1,2,2)) -- 27 -> 27
|
||||
--fb1:add(nn.ReLU(true))
|
||||
--fb1:add(nn.SpatialMaxPooling(3,3,2,2)) -- 27 -> 13
|
||||
--fb1:add(nn.SpatialConvolution(128,192,3,3,1,1,1,1)) -- 13 -> 13
|
||||
--fb1:add(nn.ReLU(true))
|
||||
--fb1:add(nn.SpatialConvolution(192,192,3,3,1,1,1,1)) -- 13 -> 13
|
||||
--fb1:add(nn.ReLU(true))
|
||||
--fb1:add(nn.SpatialConvolution(192,128,3,3,1,1,1,1)) -- 13 -> 13
|
||||
--fb1:add(nn.ReLU(true))
|
||||
--fb1:add(nn.SpatialMaxPooling(3,3,2,2)) -- 13 -> 6
|
||||
|
||||
--local fb2 = fb1:clone() -- branch 2
|
||||
--for k,v in ipairs(fb2:findModules('nn.SpatialConvolution')) do
|
||||
--v:reset() -- reset branch 2's weights
|
||||
--end
|
||||
|
||||
--features:add(fb1)
|
||||
--features:add(fb2)
|
||||
---- features:cuda()
|
||||
---- features = makeDataParallel(features, nGPU) -- defined in util.lua
|
||||
|
||||
---- 1.3. Create Classifier (fully connected layers)
|
||||
--local classifier = nn.Sequential()
|
||||
--classifier:add(nn.View(256*6*6))
|
||||
--classifier:add(nn.Dropout(0.5))
|
||||
--classifier:add(nn.Linear(256*6*6, 4096))
|
||||
--classifier:add(nn.Threshold(0, 1e-6))
|
||||
--classifier:add(nn.Dropout(0.5))
|
||||
--classifier:add(nn.Linear(4096, 4096))
|
||||
--classifier:add(nn.Threshold(0, 1e-6))
|
||||
--classifier:add(nn.Linear(4096, nClasses))
|
||||
--classifier:add(nn.LogSoftMax())
|
||||
----classifier:cuda()
|
||||
|
||||
---- 1.4. Combine 1.1 and 1.3 to produce final model
|
||||
--local model = nn.Sequential():add(features):add(classifier)
|
||||
--model.imageSize = 256
|
||||
--model.imageCrop = 224
|
||||
|
||||
--return model
|
||||
@@ -0,0 +1,45 @@
|
||||
require 'nn'
|
||||
-- thanks to https://github.com/soumith/imagenet-multiGPU.torch for this example
|
||||
nGPU = 4
|
||||
nClasses = 5
|
||||
-- from https://code.google.com/p/cuda-convnet2/source/browse/layers/layers-imagenet-1gpu.cfg
|
||||
-- this is AlexNet that was presented in the One Weird Trick paper. http://arxiv.org/abs/1404.5997
|
||||
local features = nn.Sequential()
|
||||
features:add(nn.SpatialConvolution(3,64,11,11,4,4,2,2)) -- 224 -> 55
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2)) -- 55 -> 27
|
||||
features:add(nn.SpatialConvolution(64,192,5,5,1,1,2,2)) -- 27 -> 27
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2)) -- 27 -> 13
|
||||
features:add(nn.SpatialConvolution(192,384,3,3,1,1,1,1)) -- 13 -> 13
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialConvolution(384,256,3,3,1,1,1,1)) -- 13 -> 13
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialConvolution(256,256,3,3,1,1,1,1)) -- 13 -> 13
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2)) -- 13 -> 6
|
||||
|
||||
-- features:cuda()
|
||||
-- features = makeDataParallel(features, nGPU) -- defined in util.lua
|
||||
|
||||
local classifier = nn.Sequential()
|
||||
classifier:add(nn.View(256*6*6))
|
||||
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(256*6*6, 4096))
|
||||
classifier:add(nn.ReLU())
|
||||
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(4096, 4096))
|
||||
classifier:add(nn.ReLU())
|
||||
|
||||
classifier:add(nn.Linear(4096, nClasses))
|
||||
classifier:add(nn.LogSoftMax())
|
||||
|
||||
-- classifier:cuda()
|
||||
|
||||
local model = nn.Sequential():add(features):add(classifier)
|
||||
model.imageSize = 256
|
||||
model.imageCrop = 224
|
||||
|
||||
return model
|
||||
@@ -0,0 +1,52 @@
|
||||
require 'nn'
|
||||
-- thanks to https://github.com/soumith/imagenet-multiGPU.torch for this example
|
||||
nGPU = 4
|
||||
nClasses = 10
|
||||
-- from https://code.google.com/p/cuda-convnet2/source/browse/layers/layers-imagenet-1gpu.cfg
|
||||
-- this is AlexNet that was presented in the One Weird Trick paper. http://arxiv.org/abs/1404.5997
|
||||
local features = nn.Sequential()
|
||||
features:add(nn.SpatialConvolution(3,64,11,11,4,4,2,2)) -- 224 -> 55
|
||||
features:add(nn.SpatialBatchNormalization(64,0.001))
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2)) -- 55 -> 27
|
||||
features:add(nn.SpatialConvolution(64,192,5,5,1,1,2,2)) -- 27 -> 27
|
||||
features:add(nn.SpatialBatchNormalization(192,0.001))
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2)) -- 27 -> 13
|
||||
features:add(nn.SpatialConvolution(192,384,3,3,1,1,1,1)) -- 13 -> 13
|
||||
features:add(nn.SpatialBatchNormalization(384,0.001))
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialConvolution(384,256,3,3,1,1,1,1)) -- 13 -> 13
|
||||
features:add(nn.SpatialBatchNormalization(256,0.001))
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialConvolution(256,256,3,3,1,1,1,1)) -- 13 -> 13
|
||||
features:add(nn.SpatialBatchNormalization(256,0.001))
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2)) -- 13 -> 6
|
||||
|
||||
-- features:cuda()
|
||||
-- features = makeDataParallel(features, nGPU) -- defined in util.lua
|
||||
|
||||
local classifier = nn.Sequential()
|
||||
classifier:add(nn.View(256*6*6))
|
||||
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(256*6*6, 4096))
|
||||
classifier:add(nn.BatchNormalization(4096, 0.001))
|
||||
classifier:add(nn.ReLU())
|
||||
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(4096, 4096))
|
||||
classifier:add(nn.BatchNormalization(4096, 0.001))
|
||||
classifier:add(nn.ReLU())
|
||||
|
||||
classifier:add(nn.Linear(4096, nClasses))
|
||||
classifier:add(nn.LogSoftMax())
|
||||
|
||||
-- classifier:cuda()
|
||||
|
||||
local model = nn.Sequential():add(features):add(classifier)
|
||||
model.imageSize = 256
|
||||
model.imageCrop = 224
|
||||
|
||||
return model
|
||||
@@ -1,5 +1,10 @@
|
||||
require 'nn'
|
||||
|
||||
local nfeats = 500
|
||||
local nstates = {}
|
||||
local filtsize = 10
|
||||
local poolsize = 10
|
||||
|
||||
-- a typical modern convolution network (conv+relu+pool)
|
||||
model = nn.Sequential()
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
require 'nn'
|
||||
|
||||
nhiddens = 150
|
||||
|
||||
function createSeq(input, output)
|
||||
seq = nn.Sequential();
|
||||
seq:add(nn.Linear(input,nhiddens))
|
||||
seq:add(nn.Tanh())
|
||||
seq:add(nn.Linear(nhiddens,output))
|
||||
return seq
|
||||
end
|
||||
|
||||
-- merge
|
||||
mlp = nn.Sequential()
|
||||
mlp:add(nn.Reshape(100))
|
||||
|
||||
-- concat layer
|
||||
concat = nn.Concat(1)
|
||||
concat:add(createSeq(100, 50))
|
||||
concat:add(createSeq(100, 30))
|
||||
|
||||
mlp:add(concat)
|
||||
|
||||
-- join
|
||||
mlp:add(nn.Tanh())
|
||||
mlp:add(nn.Linear(80,7))
|
||||
@@ -0,0 +1,21 @@
|
||||
require 'nn'
|
||||
|
||||
nhiddens = 150
|
||||
|
||||
function createSeq(input, output)
|
||||
seq = nn.Sequential();
|
||||
seq:add(nn.Linear(input,nhiddens))
|
||||
seq:add(nn.Tanh())
|
||||
seq:add(nn.Linear(nhiddens,output))
|
||||
return seq
|
||||
end
|
||||
|
||||
mlp = nn.Sequential()
|
||||
|
||||
-- concat layer
|
||||
concat = nn.Concat(1)
|
||||
concat:add(createSeq(100, 50))
|
||||
concat:add(createSeq(100, 30))
|
||||
|
||||
-- merge
|
||||
mlp:add(concat)
|
||||
@@ -0,0 +1,23 @@
|
||||
require 'nn'
|
||||
|
||||
nhiddens = 150
|
||||
|
||||
function createSeq(input, output)
|
||||
seq = nn.Sequential();
|
||||
seq:add(nn.Linear(input,nhiddens))
|
||||
seq:add(nn.Tanh())
|
||||
seq:add(nn.Linear(nhiddens,output))
|
||||
return seq
|
||||
end
|
||||
|
||||
mlp = nn.Sequential()
|
||||
|
||||
-- concat layer
|
||||
concat = nn.Concat(1)
|
||||
concat:add(createSeq(100, 50))
|
||||
concat:add(createSeq(100, 30))
|
||||
|
||||
-- merge
|
||||
mlp:add(concat)
|
||||
mlp:add(nn.Tanh())
|
||||
mlp:add(nn.Linear(80,7))
|
||||
@@ -0,0 +1,10 @@
|
||||
require 'nn'
|
||||
|
||||
n = nn.Sequential();
|
||||
|
||||
mlp = nn.Concat(1)
|
||||
mlp:add(nn.Linear(5,3))
|
||||
mlp:add(nn.Linear(5,7))
|
||||
|
||||
n:add(nn.Reshape(5))
|
||||
n:add(mlp)
|
||||
@@ -0,0 +1,85 @@
|
||||
-- thanks to https://github.com/soumith/imagenet-multiGPU.torch for this example
|
||||
require 'nn'
|
||||
nClasses = 4
|
||||
|
||||
local function inception(input_size, config)
|
||||
local concat = nn.Concat(2)
|
||||
if config[1][1] ~= 0 then
|
||||
local conv1 = nn.Sequential()
|
||||
conv1:add(nn.SpatialConvolution(input_size, config[1][1],1,1,1,1)):add(nn.ReLU(true))
|
||||
concat:add(conv1)
|
||||
end
|
||||
|
||||
local conv3 = nn.Sequential()
|
||||
conv3:add(nn.SpatialConvolution( input_size, config[2][1],1,1,1,1)):add(nn.ReLU(true))
|
||||
conv3:add(nn.SpatialConvolution(config[2][1], config[2][2],3,3,1,1,1,1)):add(nn.ReLU(true))
|
||||
concat:add(conv3)
|
||||
|
||||
local conv3xx = nn.Sequential()
|
||||
conv3xx:add(nn.SpatialConvolution( input_size, config[3][1],1,1,1,1)):add(nn.ReLU(true))
|
||||
conv3xx:add(nn.SpatialConvolution(config[3][1], config[3][2],3,3,1,1,1,1)):add(nn.ReLU(true))
|
||||
conv3xx:add(nn.SpatialConvolution(config[3][2], config[3][2],3,3,1,1,1,1)):add(nn.ReLU(true))
|
||||
concat:add(conv3xx)
|
||||
|
||||
local pool = nn.Sequential()
|
||||
pool:add(nn.SpatialZeroPadding(1,1,1,1)) -- remove after getting nn R2 into fbcode
|
||||
if config[4][1] == 'max' then
|
||||
pool:add(nn.SpatialMaxPooling(3,3,1,1):ceil())
|
||||
elseif config[4][1] == 'avg' then
|
||||
pool:add(nn.SpatialAveragePooling(3,3,1,1):ceil())
|
||||
else
|
||||
error('Unknown pooling')
|
||||
end
|
||||
if config[4][2] ~= 0 then
|
||||
pool:add(nn.SpatialConvolution(input_size, config[4][2],1,1,1,1)):add(nn.ReLU(true))
|
||||
end
|
||||
concat:add(pool)
|
||||
|
||||
return concat
|
||||
end
|
||||
|
||||
local features = nn.Sequential()
|
||||
features:add(nn.SpatialConvolution(3,64,7,7,2,2,3,3)):add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2):ceil())
|
||||
features:add(nn.SpatialConvolution(64,64,1,1)):add(nn.ReLU(true))
|
||||
features:add(nn.SpatialConvolution(64,192,3,3,1,1,1,1)):add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2):ceil())
|
||||
features:add(inception( 192, {{ 64},{ 64, 64},{ 64, 96},{'avg', 32}})) -- 3(a)
|
||||
features:add(inception( 256, {{ 64},{ 64, 96},{ 64, 96},{'avg', 64}})) -- 3(b)
|
||||
features:add(inception( 320, {{ 0},{128,160},{ 64, 96},{'max', 0}})) -- 3(c)
|
||||
features:add(nn.SpatialConvolution(576,576,2,2,2,2))
|
||||
features:add(inception( 576, {{224},{ 64, 96},{ 96,128},{'avg',128}})) -- 4(a)
|
||||
features:add(inception( 576, {{192},{ 96,128},{ 96,128},{'avg',128}})) -- 4(b)
|
||||
features:add(inception( 576, {{160},{128,160},{128,160},{'avg', 96}})) -- 4(c)
|
||||
features:add(inception( 576, {{ 96},{128,192},{160,192},{'avg', 96}})) -- 4(d)
|
||||
|
||||
local main_branch = nn.Sequential()
|
||||
main_branch:add(inception( 576, {{ 0},{128,192},{192,256},{'max', 0}})) -- 4(e)
|
||||
main_branch:add(nn.SpatialConvolution(1024,1024,2,2,2,2))
|
||||
main_branch:add(inception(1024, {{352},{192,320},{160,224},{'avg',128}})) -- 5(a)
|
||||
main_branch:add(inception(1024, {{352},{192,320},{192,224},{'max',128}})) -- 5(b)
|
||||
main_branch:add(nn.SpatialAveragePooling(7,7,1,1))
|
||||
main_branch:add(nn.View(1024):setNumInputDims(3))
|
||||
main_branch:add(nn.Linear(1024,nClasses))
|
||||
main_branch:add(nn.LogSoftMax())
|
||||
|
||||
-- add auxillary classifier here (thanks to Christian Szegedy for the details)
|
||||
local aux_classifier = nn.Sequential()
|
||||
aux_classifier:add(nn.SpatialAveragePooling(5,5,3,3):ceil())
|
||||
aux_classifier:add(nn.SpatialConvolution(576,128,1,1,1,1))
|
||||
aux_classifier:add(nn.View(128*4*4):setNumInputDims(3))
|
||||
aux_classifier:add(nn.Linear(128*4*4,768))
|
||||
aux_classifier:add(nn.ReLU())
|
||||
aux_classifier:add(nn.Linear(768,nClasses))
|
||||
aux_classifier:add(nn.LogSoftMax())
|
||||
|
||||
local splitter = nn.Concat(2)
|
||||
splitter:add(main_branch):add(aux_classifier)
|
||||
local model = nn.Sequential():add(features):add(splitter)
|
||||
|
||||
-- model:cuda()
|
||||
-- model = makeDataParallel(model, nGPU) -- defined in util.lua
|
||||
model.imageSize = 256
|
||||
model.imageCrop = 224
|
||||
|
||||
return model
|
||||
@@ -0,0 +1,51 @@
|
||||
-- thanks to https://github.com/soumith/imagenet-multiGPU.torch for this example
|
||||
|
||||
-- Achieves 62.6% top1 on validation set at 35 epochs with this regime:
|
||||
-- { 1, 9, 1e-1, 5e-4, },
|
||||
-- { 10, 19, 1e-2, 5e-4 },
|
||||
-- { 20, 25, 0.001, 0 },
|
||||
-- { 26, 30, 1e-4, 0 },
|
||||
-- Trained model:
|
||||
-- https://gist.github.com/szagoruyko/0f5b4c5e2d2b18472854
|
||||
|
||||
require 'nn'
|
||||
local nin = nn.Sequential()
|
||||
local function block(...)
|
||||
local arg = {...}
|
||||
local no = arg[2]
|
||||
nin:add(nn.SpatialConvolution(...))
|
||||
nin:add(nn.SpatialBatchNormalization(no,0.001))
|
||||
nin:add(nn.ReLU(true))
|
||||
nin:add(nn.SpatialConvolution(no, no, 1, 1, 1, 1, 0, 0))
|
||||
nin:add(nn.SpatialBatchNormalization(no,0.001))
|
||||
nin:add(nn.ReLU(true))
|
||||
nin:add(nn.SpatialConvolution(no, no, 1, 1, 1, 1, 0, 0))
|
||||
nin:add(nn.SpatialBatchNormalization(no,0.001))
|
||||
nin:add(nn.ReLU(true))
|
||||
end
|
||||
|
||||
local function mp(...)
|
||||
nin:add(nn.SpatialMaxPooling(...))
|
||||
end
|
||||
|
||||
block(3, 96, 11, 11, 4, 4, 5, 5)
|
||||
mp(3, 3, 2, 2, 1, 1)
|
||||
block(96, 256, 5, 5, 1, 1, 2, 2)
|
||||
mp(3, 3, 2, 2, 1, 1)
|
||||
block(256, 384, 3, 3, 1, 1, 1, 1)
|
||||
mp(3, 3, 2, 2, 1, 1)
|
||||
block(384, 1024, 3, 3, 1, 1, 1, 1)
|
||||
|
||||
nin:add(nn.SpatialAveragePooling(7, 7, 1, 1))
|
||||
nin:add(nn.View(-1):setNumInputDims(3))
|
||||
|
||||
local model = nn.Sequential()
|
||||
-- :add(makeDataParallel(nin, nGPU))
|
||||
:add(nin)
|
||||
:add(nn.Linear(1024,1000))
|
||||
:add(nn.LogSoftMax())
|
||||
|
||||
model.imageSize = 256
|
||||
model.imageCrop = 224
|
||||
|
||||
return model-- :cuda()
|
||||
@@ -0,0 +1,47 @@
|
||||
-- thanks to https://github.com/soumith/imagenet-multiGPU.torch for this example
|
||||
require 'nn'
|
||||
nClasses = 7
|
||||
local features = nn.Sequential()
|
||||
|
||||
features:add(nn.SpatialConvolution(3, 96, 11, 11, 4, 4))
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(2, 2, 2, 2))
|
||||
|
||||
features:add(nn.SpatialConvolution(96, 256, 5, 5, 1, 1))
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(2, 2, 2, 2))
|
||||
|
||||
features:add(nn.SpatialConvolution(256, 512, 3, 3, 1, 1, 1, 1))
|
||||
features:add(nn.ReLU(true))
|
||||
|
||||
features:add(nn.SpatialConvolution(512, 1024, 3, 3, 1, 1, 1, 1))
|
||||
features:add(nn.ReLU(true))
|
||||
|
||||
features:add(nn.SpatialConvolution(1024, 1024, 3, 3, 1, 1, 1, 1))
|
||||
features:add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(2, 2, 2, 2))
|
||||
|
||||
-- features:cuda()
|
||||
-- features = makeDataParallel(features, nGPU) -- defined in util.lua
|
||||
|
||||
-- 1.3. Create Classifier (fully connected layers)
|
||||
local classifier = nn.Sequential()
|
||||
classifier:add(nn.View(1024*5*5))
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(1024*5*5, 3072))
|
||||
classifier:add(nn.Threshold(0, 0.000001))
|
||||
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(3072, 4096))
|
||||
classifier:add(nn.Threshold(0, 0.000001))
|
||||
|
||||
classifier:add(nn.Linear(4096, nClasses))
|
||||
classifier:add(nn.LogSoftMax())
|
||||
|
||||
-- classifier:cuda()
|
||||
|
||||
-- 1.4. Combine 1.2 and 1.3 to produce final model
|
||||
local model = nn.Sequential():add(features):add(classifier)
|
||||
model.imageSize = 256
|
||||
model.imageCrop = 224
|
||||
return model
|
||||
@@ -0,0 +1,58 @@
|
||||
-- thanks to https://github.com/soumith/imagenet-multiGPU.torch for this example
|
||||
require 'nn'
|
||||
local nGPU = 4
|
||||
local nClasses = 10
|
||||
local modelType = 'A' -- on a titan black, B/D/E run out of memory even for batch-size 32
|
||||
|
||||
-- Create tables describing VGG configurations A, B, D, E
|
||||
local cfg = {}
|
||||
if modelType == 'A' then
|
||||
cfg = {64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'}
|
||||
elseif modelType == 'B' then
|
||||
cfg = {64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'}
|
||||
elseif modelType == 'D' then
|
||||
cfg = {64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'}
|
||||
elseif modelType == 'E' then
|
||||
cfg = {64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'}
|
||||
else
|
||||
error('Unknown model type: ' .. modelType .. ' | Please specify a modelType A or B or D or E')
|
||||
end
|
||||
|
||||
local features = nn.Sequential()
|
||||
do
|
||||
local iChannels = 3;
|
||||
for k,v in ipairs(cfg) do
|
||||
if v == 'M' then
|
||||
features:add(nn.SpatialMaxPooling(2,2,2,2))
|
||||
else
|
||||
local oChannels = v;
|
||||
local conv3 = nn.SpatialConvolution(iChannels,oChannels,3,3,1,1,1,1);
|
||||
features:add(conv3)
|
||||
features:add(nn.ReLU(true))
|
||||
iChannels = oChannels;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- features:cuda()
|
||||
-- features = makeDataParallel(features, nGPU) -- defined in util.lua
|
||||
|
||||
local classifier = nn.Sequential()
|
||||
classifier:add(nn.View(512*7*7))
|
||||
classifier:add(nn.Linear(512*7*7, 4096))
|
||||
-- Add support for 1e-6:to luajs
|
||||
classifier:add(nn.Threshold(0, 0.000001))
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(4096, 4096))
|
||||
classifier:add(nn.Threshold(0, 0.000001))
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(4096, nClasses))
|
||||
classifier:add(nn.LogSoftMax())
|
||||
-- classifier:cuda()
|
||||
|
||||
local model = nn.Sequential()
|
||||
model:add(features):add(classifier)
|
||||
model.imageSize = 256
|
||||
model.imageCrop = 224
|
||||
|
||||
return model
|
||||
@@ -0,0 +1,55 @@
|
||||
-- thanks to https://github.com/soumith/imagenet-multiGPU.torch for this example
|
||||
require 'nn'
|
||||
local modelType = 'A' -- on a titan black, B/D/E run out of memory even for batch-size 32
|
||||
|
||||
-- Create tables describing VGG configurations A, B, D, E
|
||||
local cfg = {}
|
||||
if modelType == 'A' then
|
||||
cfg = {64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'}
|
||||
elseif modelType == 'B' then
|
||||
cfg = {64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'}
|
||||
elseif modelType == 'D' then
|
||||
cfg = {64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'}
|
||||
elseif modelType == 'E' then
|
||||
cfg = {64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'}
|
||||
else
|
||||
error('Unknown model type: ' .. modelType .. ' | Please specify a modelType A or B or D or E')
|
||||
end
|
||||
|
||||
local features = nn.Sequential()
|
||||
do
|
||||
local iChannels = 3;
|
||||
for k,v in ipairs(cfg) do
|
||||
if v == 'M' then
|
||||
features:add(nn.SpatialMaxPooling(2,2,2,2))
|
||||
else
|
||||
local oChannels = v;
|
||||
local conv3 = nn.SpatialConvolution(iChannels,oChannels,3,3,1,1,1,1);
|
||||
features:add(conv3)
|
||||
features:add(nn.ReLU(true))
|
||||
iChannels = oChannels;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- features:cuda()
|
||||
-- features = makeDataParallel(features, nGPU) -- defined in util.lua
|
||||
|
||||
local classifier = nn.Sequential()
|
||||
classifier:add(nn.View(512*7*7))
|
||||
classifier:add(nn.Linear(512*7*7, 4096))
|
||||
classifier:add(nn.Threshold(0, 0.000001))
|
||||
classifier:add(nn.BatchNormalization(4096, 0.001))
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(4096, 4096))
|
||||
classifier:add(nn.Threshold(0, 0.000001))
|
||||
classifier:add(nn.BatchNormalization(4096, 0.001))
|
||||
classifier:add(nn.Dropout(0.5))
|
||||
classifier:add(nn.Linear(4096, 1000))
|
||||
classifier:add(nn.LogSoftMax())
|
||||
-- classifier:cuda()
|
||||
|
||||
local model = nn.Sequential()
|
||||
model:add(features):add(classifier)
|
||||
|
||||
return model
|
||||
@@ -0,0 +1,149 @@
|
||||
- type: LogSoftMax
|
||||
id: /S/2
|
||||
next: []
|
||||
attributes: {}
|
||||
- type: SpatialMaxPooling
|
||||
id: /S/7
|
||||
next:
|
||||
- /S/j
|
||||
attributes:
|
||||
strideWidth: 2
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
- type: SpatialConvolution
|
||||
id: /S/8
|
||||
next:
|
||||
- /S/C
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 256
|
||||
nInputPlane: 384
|
||||
- type: Linear
|
||||
id: /S/A
|
||||
next:
|
||||
- /S/W
|
||||
attributes:
|
||||
output: 4096
|
||||
- type: ReLU
|
||||
id: /S/B
|
||||
next:
|
||||
- /S/7
|
||||
attributes: {}
|
||||
- type: ReLU
|
||||
id: /S/C
|
||||
next:
|
||||
- /S/R
|
||||
attributes: {}
|
||||
- type: SpatialConvolution
|
||||
id: /S/I
|
||||
next:
|
||||
- /S/a
|
||||
attributes:
|
||||
strideWidth: 4
|
||||
kernelHeight: 11
|
||||
kernelWidth: 11
|
||||
nOutputPlane: 64
|
||||
nInputPlane: 3
|
||||
- type: ReLU
|
||||
id: /S/K
|
||||
next:
|
||||
- /S/X
|
||||
attributes: {}
|
||||
- type: Dropout
|
||||
id: /S/N
|
||||
next:
|
||||
- /S/A
|
||||
attributes:
|
||||
probability: 0.5
|
||||
- type: SpatialMaxPooling
|
||||
id: /S/O
|
||||
next:
|
||||
- /S/d
|
||||
attributes:
|
||||
strideWidth: 2
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
- type: Linear
|
||||
id: /S/Q
|
||||
next:
|
||||
- /S/K
|
||||
attributes:
|
||||
output: 4096
|
||||
- type: SpatialConvolution
|
||||
id: /S/R
|
||||
next:
|
||||
- /S/rc
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 256
|
||||
nInputPlane: 256
|
||||
- type: ReLU
|
||||
id: /S/T
|
||||
next:
|
||||
- /S/8
|
||||
attributes: {}
|
||||
- type: ReLU
|
||||
id: /S/W
|
||||
next:
|
||||
- /S/z
|
||||
attributes: {}
|
||||
- type: Linear
|
||||
id: /S/X
|
||||
next:
|
||||
- /S/2
|
||||
attributes:
|
||||
output: 5
|
||||
- type: View
|
||||
id: /S/Yp
|
||||
next:
|
||||
- /S/N
|
||||
attributes:
|
||||
sizes: 9216
|
||||
- type: ReLU
|
||||
id: /S/a
|
||||
next:
|
||||
- /S/O
|
||||
attributes: {}
|
||||
- type: SpatialConvolution
|
||||
id: /S/d
|
||||
next:
|
||||
- /S/B
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 5
|
||||
kernelWidth: 5
|
||||
nOutputPlane: 192
|
||||
nInputPlane: 64
|
||||
- type: SpatialConvolution
|
||||
id: /S/j
|
||||
next:
|
||||
- /S/T
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 384
|
||||
nInputPlane: 192
|
||||
- type: ReLU
|
||||
id: /S/rc
|
||||
next:
|
||||
- /S/s
|
||||
attributes: {}
|
||||
- type: SpatialMaxPooling
|
||||
id: /S/s
|
||||
next:
|
||||
- /S/Yp
|
||||
attributes:
|
||||
strideWidth: 2
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
- type: Dropout
|
||||
id: /S/z
|
||||
next:
|
||||
- /S/Q
|
||||
attributes:
|
||||
probability: 0.5
|
||||
@@ -0,0 +1,60 @@
|
||||
- type: Reshape
|
||||
id: 0
|
||||
next:
|
||||
- 2
|
||||
attributes:
|
||||
dimensions: 100
|
||||
- type: SoftMax
|
||||
id: 1
|
||||
next: []
|
||||
attributes: {}
|
||||
- type: Linear
|
||||
id: 2
|
||||
next:
|
||||
- 5
|
||||
attributes:
|
||||
output: 300
|
||||
- type: ReLU
|
||||
id: 3
|
||||
next:
|
||||
- 6
|
||||
attributes: {}
|
||||
- type: Sigmoid
|
||||
id: 4
|
||||
next:
|
||||
- 7
|
||||
attributes: {}
|
||||
- type: RReLU
|
||||
id: 5
|
||||
next:
|
||||
- 10
|
||||
attributes: {}
|
||||
- type: Linear
|
||||
id: 6
|
||||
next:
|
||||
- 4
|
||||
attributes:
|
||||
output: 100
|
||||
- type: Linear
|
||||
id: 7
|
||||
next:
|
||||
- 8
|
||||
attributes:
|
||||
output: 120
|
||||
- type: LeakyReLU
|
||||
id: 8
|
||||
next:
|
||||
- 9
|
||||
attributes: {}
|
||||
- type: Linear
|
||||
id: 9
|
||||
next:
|
||||
- 1
|
||||
attributes:
|
||||
output: 5
|
||||
- type: Linear
|
||||
id: 10
|
||||
next:
|
||||
- 3
|
||||
attributes:
|
||||
output: 100
|
||||
@@ -0,0 +1,22 @@
|
||||
- type: Linear
|
||||
id: 0
|
||||
next: []
|
||||
attributes:
|
||||
output: 10
|
||||
- type: Linear
|
||||
id: 1
|
||||
next:
|
||||
- 2
|
||||
attributes:
|
||||
output: 300
|
||||
- type: HardTanh
|
||||
id: 2
|
||||
next:
|
||||
- 0
|
||||
attributes: {}
|
||||
- type: Reshape
|
||||
id: 3
|
||||
next:
|
||||
- 1
|
||||
attributes:
|
||||
dimensions: 100
|
||||
@@ -0,0 +1,22 @@
|
||||
- type: Linear
|
||||
id: 4
|
||||
next:
|
||||
- 7
|
||||
attributes:
|
||||
output: 300
|
||||
- type: Reshape
|
||||
id: 5
|
||||
next:
|
||||
- 4
|
||||
attributes:
|
||||
dimensions: 100
|
||||
- type: Linear
|
||||
id: 6
|
||||
next: []
|
||||
attributes:
|
||||
output: 10
|
||||
- type: Tanh
|
||||
id: 7
|
||||
next:
|
||||
- 6
|
||||
attributes: {}
|
||||
@@ -0,0 +1,65 @@
|
||||
- type: Reshape
|
||||
id: 1
|
||||
attributes:
|
||||
dimensions: 100
|
||||
next:
|
||||
- 2
|
||||
- 3
|
||||
|
||||
# Left side
|
||||
- type: Linear
|
||||
id: 2
|
||||
attributes:
|
||||
output: 150
|
||||
next:
|
||||
- 4
|
||||
|
||||
- type: Tanh
|
||||
id: 4
|
||||
next:
|
||||
- 6
|
||||
|
||||
- type: Linear
|
||||
id: 6
|
||||
attributes:
|
||||
output: 50
|
||||
next:
|
||||
- 8
|
||||
|
||||
# Right side
|
||||
- type: Linear
|
||||
id: 3
|
||||
attributes:
|
||||
output: 150
|
||||
next:
|
||||
- 5
|
||||
|
||||
- type: Tanh
|
||||
id: 5
|
||||
next:
|
||||
- 7
|
||||
|
||||
- type: Linear
|
||||
id: 7
|
||||
attributes:
|
||||
output: 30
|
||||
next:
|
||||
- 8
|
||||
|
||||
# Center
|
||||
- type: Concat
|
||||
id: 8
|
||||
attributes:
|
||||
dim: 1
|
||||
next:
|
||||
- 9
|
||||
|
||||
- type: Tanh
|
||||
id: 9
|
||||
next:
|
||||
- 10
|
||||
|
||||
- type: Linear
|
||||
id: 10
|
||||
attributes:
|
||||
output: 7
|
||||
@@ -0,0 +1,39 @@
|
||||
- type: Tanh
|
||||
id: 8
|
||||
next:
|
||||
- 12
|
||||
attributes: {}
|
||||
- type: Tanh
|
||||
id: 9
|
||||
next:
|
||||
- 14
|
||||
attributes: {}
|
||||
- type: Linear
|
||||
id: 10
|
||||
next:
|
||||
- 8
|
||||
attributes:
|
||||
output: 150
|
||||
- type: Concat
|
||||
id: 11
|
||||
next: []
|
||||
attributes:
|
||||
dim: 1
|
||||
- type: Linear
|
||||
id: 12
|
||||
next:
|
||||
- 11
|
||||
attributes:
|
||||
output: 50
|
||||
- type: Linear
|
||||
id: 13
|
||||
next:
|
||||
- 9
|
||||
attributes:
|
||||
output: 150
|
||||
- type: Linear
|
||||
id: 14
|
||||
next:
|
||||
- 11
|
||||
attributes:
|
||||
output: 30
|
||||
@@ -0,0 +1,55 @@
|
||||
# Left side
|
||||
- type: Linear
|
||||
id: 2
|
||||
attributes:
|
||||
output: 150
|
||||
next:
|
||||
- 4
|
||||
|
||||
- type: Tanh
|
||||
id: 4
|
||||
next:
|
||||
- 6
|
||||
|
||||
- type: Linear
|
||||
id: 6
|
||||
attributes:
|
||||
output: 50
|
||||
|
||||
# Right side
|
||||
- type: Linear
|
||||
id: 3
|
||||
attributes:
|
||||
output: 150
|
||||
next:
|
||||
- 5
|
||||
|
||||
- type: Tanh
|
||||
id: 5
|
||||
next:
|
||||
- 7
|
||||
|
||||
- type: Linear
|
||||
id: 7
|
||||
attributes:
|
||||
output: 30
|
||||
next:
|
||||
- 8
|
||||
|
||||
# Center
|
||||
- type: Concat
|
||||
id: 8
|
||||
attributes:
|
||||
dim: 1
|
||||
next:
|
||||
- 9
|
||||
|
||||
- type: Tanh
|
||||
id: 9
|
||||
next:
|
||||
- 10
|
||||
|
||||
- type: Linear
|
||||
id: 10
|
||||
attributes:
|
||||
output: 7
|
||||
@@ -0,0 +1,57 @@
|
||||
# Left side
|
||||
- type: Linear
|
||||
id: 2
|
||||
attributes:
|
||||
output: 150
|
||||
next:
|
||||
- 4
|
||||
|
||||
- type: Tanh
|
||||
id: 4
|
||||
next:
|
||||
- 6
|
||||
|
||||
- type: Linear
|
||||
id: 6
|
||||
attributes:
|
||||
output: 50
|
||||
next:
|
||||
- 8
|
||||
|
||||
# Right side
|
||||
- type: Linear
|
||||
id: 3
|
||||
attributes:
|
||||
output: 150
|
||||
next:
|
||||
- 5
|
||||
|
||||
- type: Tanh
|
||||
id: 5
|
||||
next:
|
||||
- 7
|
||||
|
||||
- type: Linear
|
||||
id: 7
|
||||
attributes:
|
||||
output: 30
|
||||
next:
|
||||
- 8
|
||||
|
||||
# Center
|
||||
- type: Concat
|
||||
id: 8
|
||||
attributes:
|
||||
dim: 1
|
||||
next:
|
||||
- 9
|
||||
|
||||
- type: Tanh
|
||||
id: 9
|
||||
next:
|
||||
- 10
|
||||
|
||||
- type: Linear
|
||||
id: 10
|
||||
attributes:
|
||||
output: 7
|
||||
@@ -0,0 +1,24 @@
|
||||
- type: Linear
|
||||
id: 0
|
||||
next:
|
||||
- 1
|
||||
attributes:
|
||||
output: 3
|
||||
- type: Concat
|
||||
id: 1
|
||||
next: []
|
||||
attributes:
|
||||
dim: 1
|
||||
- type: Linear
|
||||
id: 2
|
||||
next:
|
||||
- 1
|
||||
attributes:
|
||||
output: 7
|
||||
- type: Reshape
|
||||
id: 3
|
||||
next:
|
||||
- 2
|
||||
- 0
|
||||
attributes:
|
||||
dimensions: 5
|
||||
@@ -0,0 +1,11 @@
|
||||
- type: Linear
|
||||
id: 11
|
||||
next: []
|
||||
attributes:
|
||||
output: 10
|
||||
- type: Reshape
|
||||
id: 12
|
||||
next:
|
||||
- 11
|
||||
attributes:
|
||||
dimensions: 100
|
||||
@@ -0,0 +1,216 @@
|
||||
- type: Threshold
|
||||
id: 0
|
||||
next:
|
||||
- 17
|
||||
attributes:
|
||||
inplace: null
|
||||
value: 0.000001
|
||||
threshold: 0
|
||||
- type: ReLU
|
||||
id: 1
|
||||
next:
|
||||
- 2
|
||||
attributes: {}
|
||||
- type: SpatialMaxPooling
|
||||
id: 2
|
||||
next:
|
||||
- 11
|
||||
attributes:
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: View
|
||||
id: 3
|
||||
next:
|
||||
- 14
|
||||
attributes:
|
||||
sizes: 25088
|
||||
- type: SpatialConvolution
|
||||
id: 4
|
||||
next:
|
||||
- 21
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: ReLU
|
||||
id: 5
|
||||
next:
|
||||
- 10
|
||||
attributes: {}
|
||||
- type: SpatialConvolution
|
||||
id: 6
|
||||
next:
|
||||
- 29
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 128
|
||||
nInputPlane: 64
|
||||
- type: SpatialMaxPooling
|
||||
id: 7
|
||||
next:
|
||||
- 6
|
||||
attributes:
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: ReLU
|
||||
id: 8
|
||||
next:
|
||||
- 18
|
||||
attributes: {}
|
||||
- type: Linear
|
||||
id: 9
|
||||
next:
|
||||
- 0
|
||||
attributes:
|
||||
output: 4096
|
||||
- type: SpatialMaxPooling
|
||||
id: 10
|
||||
next:
|
||||
- 4
|
||||
attributes:
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: SpatialConvolution
|
||||
id: 11
|
||||
next:
|
||||
- 23
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 256
|
||||
- type: SpatialConvolution
|
||||
id: 12
|
||||
next:
|
||||
- 26
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 64
|
||||
nInputPlane: 3
|
||||
- type: Dropout
|
||||
id: 13
|
||||
next:
|
||||
- 9
|
||||
attributes:
|
||||
probability: 0.5
|
||||
- type: Linear
|
||||
id: 14
|
||||
next:
|
||||
- 16
|
||||
attributes:
|
||||
output: 4096
|
||||
- type: SpatialMaxPooling
|
||||
id: 15
|
||||
next:
|
||||
- 20
|
||||
attributes:
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: Threshold
|
||||
id: 16
|
||||
next:
|
||||
- 13
|
||||
attributes:
|
||||
inplace: null
|
||||
value: 0.000001
|
||||
threshold: 0
|
||||
- type: Dropout
|
||||
id: 17
|
||||
next:
|
||||
- 27
|
||||
attributes:
|
||||
probability: 0.5
|
||||
- type: SpatialConvolution
|
||||
id: 18
|
||||
next:
|
||||
- 1
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 256
|
||||
nInputPlane: 256
|
||||
- type: SpatialConvolution
|
||||
id: 19
|
||||
next:
|
||||
- 28
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: SpatialConvolution
|
||||
id: 20
|
||||
next:
|
||||
- 8
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 256
|
||||
nInputPlane: 128
|
||||
- type: ReLU
|
||||
id: 21
|
||||
next:
|
||||
- 19
|
||||
attributes: {}
|
||||
- type: LogSoftMax
|
||||
id: 22
|
||||
next: []
|
||||
attributes: {}
|
||||
- type: ReLU
|
||||
id: 23
|
||||
next:
|
||||
- 25
|
||||
attributes: {}
|
||||
- type: SpatialMaxPooling
|
||||
id: 24
|
||||
next:
|
||||
- 3
|
||||
attributes:
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: SpatialConvolution
|
||||
id: 25
|
||||
next:
|
||||
- 5
|
||||
attributes:
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: ReLU
|
||||
id: 26
|
||||
next:
|
||||
- 7
|
||||
attributes: {}
|
||||
- type: Linear
|
||||
id: 27
|
||||
next:
|
||||
- 22
|
||||
attributes:
|
||||
output: 10
|
||||
- type: ReLU
|
||||
id: 28
|
||||
next:
|
||||
- 24
|
||||
attributes: {}
|
||||
- type: ReLU
|
||||
id: 29
|
||||
next:
|
||||
- 15
|
||||
attributes: {}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*jshint node:true, mocha:true*/
|
||||
/**
|
||||
* Generated by PluginGenerator 0.14.0 from webgme on Tue Mar 15 2016 21:19:45 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var testFixture = require('../globals'),
|
||||
path = testFixture.path,
|
||||
assert = require('assert'),
|
||||
SEED_DIR = path.join(testFixture.SEED_DIR, '..'),
|
||||
fs = require('fs');
|
||||
|
||||
describe('utils', function () {
|
||||
var gmeConfig = testFixture.getGmeConfig(),
|
||||
GraphChecker = testFixture.requirejs('deepforge/GraphChecker'),
|
||||
expect = testFixture.expect,
|
||||
path = testFixture.path,
|
||||
MODELS_DIR = path.join(__dirname, '..', 'test-cases', 'models'),
|
||||
BASE_DIR = path.join(__dirname, '..', 'common'),
|
||||
logger = testFixture.logger.fork('utils'),
|
||||
projectName = 'testProject',
|
||||
Q = testFixture.Q,
|
||||
core,
|
||||
rootNode,
|
||||
project,
|
||||
gmeAuth,
|
||||
storage,
|
||||
commitHash,
|
||||
checker;
|
||||
|
||||
before(function (done) {
|
||||
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
|
||||
.then(function (gmeAuth_) {
|
||||
gmeAuth = gmeAuth_;
|
||||
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
|
||||
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
|
||||
return storage.openDatabase();
|
||||
})
|
||||
.then(function () {
|
||||
var importParam = {
|
||||
projectSeed: path.join(SEED_DIR, 'devTests', 'devTests.zip'),
|
||||
projectName: projectName,
|
||||
branchName: 'master',
|
||||
logger: logger,
|
||||
gmeConfig: gmeConfig
|
||||
};
|
||||
|
||||
return testFixture.importProject(storage, importParam);
|
||||
})
|
||||
.then(function (importResult) {
|
||||
project = importResult.project;
|
||||
core = importResult.core;
|
||||
checker = new GraphChecker(core);
|
||||
commitHash = importResult.commitHash;
|
||||
return project.createBranch('test', commitHash);
|
||||
})
|
||||
.then(function () {
|
||||
return project.getBranchHash('test');
|
||||
})
|
||||
.then(function (branchHash) {
|
||||
return Q.ninvoke(project, 'loadObject', branchHash);
|
||||
})
|
||||
.then(function (commitObject) {
|
||||
return Q.ninvoke(core, 'loadRoot', commitObject.root);
|
||||
})
|
||||
.then(function (root) {
|
||||
rootNode = root;
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
storage.closeDatabase()
|
||||
.then(function () {
|
||||
return gmeAuth.unload();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
var run = function(nodePath, filename, result, done) {
|
||||
var txt = fs.readFileSync(path.join(MODELS_DIR, filename + '.yml'), 'utf8');
|
||||
|
||||
core.loadByPath(rootNode, nodePath)
|
||||
.then(node => {
|
||||
return core.loadChildren(node);
|
||||
})
|
||||
.then(children => {
|
||||
var mappings = checker.yaml(txt).map.to.gme(children),
|
||||
nodes = children.filter(child => {
|
||||
var ptrs = core.getPointerNames(child);
|
||||
return (ptrs.indexOf('dst') + ptrs.indexOf('src')) === -2;
|
||||
});
|
||||
|
||||
assert.equal(!!mappings, result, 'mappings are ' + JSON.stringify(mappings));
|
||||
|
||||
if (result) {
|
||||
assert.equal(nodes.length, Object.keys(mappings).length,
|
||||
`Missing mappings. Expected ${nodes.length} keys. Found ` +
|
||||
` ${JSON.stringify(mappings)}`);
|
||||
}
|
||||
})
|
||||
.nodeify(done);
|
||||
};
|
||||
|
||||
describe('matching architectures', function() {
|
||||
var cases = [
|
||||
['/I', 'concat-parallel'],
|
||||
['/x', 'concat-y'],
|
||||
['/2B', 'concat-y-bad-conn'] // disconnected graph
|
||||
];
|
||||
|
||||
cases.forEach(pair => it('should validate ' + pair[1],
|
||||
run.bind(this, pair[0], pair[1], true)));
|
||||
});
|
||||
|
||||
describe('mismatching architectures', function() {
|
||||
var cases = [
|
||||
['/u', 'concat-y'],
|
||||
['/x', 'concat-parallel'],
|
||||
['/t', 'concat-y'],
|
||||
['/2B', 'concat-y']
|
||||
];
|
||||
|
||||
cases.forEach(pair => it('should validate ' + pair[1],
|
||||
run.bind(this, pair[0], pair[1], false)));
|
||||
});
|
||||
});
|
||||
@@ -12,6 +12,14 @@
|
||||
"GenerateArchitecture": {
|
||||
"src": "src/plugins/GenerateArchitecture",
|
||||
"test": "test/plugins/GenerateArchitecture"
|
||||
},
|
||||
"GenerateYaml": {
|
||||
"src": "src/plugins/GenerateYaml",
|
||||
"test": "test/plugins/GenerateYaml"
|
||||
},
|
||||
"ImportYaml": {
|
||||
"src": "src/plugins/ImportYaml",
|
||||
"test": "test/plugins/ImportYaml"
|
||||
}
|
||||
},
|
||||
"layouts": {},
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário