Date: Thu, 1 Nov 2018 19:01:21 +0100
Subject: [PATCH 03/27] Update adding_new_layers.md
---
tutorials/adding_new_layers.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tutorials/adding_new_layers.md b/tutorials/adding_new_layers.md
index 393fe176e..e7d0a54a7 100644
--- a/tutorials/adding_new_layers.md
+++ b/tutorials/adding_new_layers.md
@@ -52,6 +52,7 @@
- Now, add a new line for the layer you just added in ```data.js``` in the section of Activation/Neuron Layer, because this layer belongs to this category.
- ```your_layer_name``` this line will make your layer visible in Fabrik.
+- Add ```"your_layer_id"``` to 1 of 3 framework filter array ```var KerasLayers = [...]```, ```var TensorFlowLayers = [...]``` or ```var CaffeLayers = []```. This should be like this ```var KerasLayers = ["RNN_Button", "GRU_Button", "your_layer_id"]```. This arrays are placed inside ```changeEvent() {}``` function.
### Adding layer handling to the backend
@@ -87,4 +88,4 @@
- Check the new layer inside the category you added it. See if all the parameters are properly displayed and usable as you wanted.
- If everything is working fine commit your changes and push it to your fork then make a Pull Request.
-- Congratulations! Happy contributing :-)
\ No newline at end of file
+- Congratulations! Happy contributing :-)
From db576e364d73ecf75d900b2ef9f95c9ac37db1d2 Mon Sep 17 00:00:00 2001
From: ZeroZeroJedenJeden
<44526720+ZeroZeroJedenJeden@users.noreply.github.com>
Date: Thu, 1 Nov 2018 19:03:01 +0100
Subject: [PATCH 04/27] Update adding_new_layers.md
---
tutorials/adding_new_layers.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutorials/adding_new_layers.md b/tutorials/adding_new_layers.md
index e7d0a54a7..de0736110 100644
--- a/tutorials/adding_new_layers.md
+++ b/tutorials/adding_new_layers.md
@@ -52,7 +52,7 @@
- Now, add a new line for the layer you just added in ```data.js``` in the section of Activation/Neuron Layer, because this layer belongs to this category.
- ```your_layer_name``` this line will make your layer visible in Fabrik.
-- Add ```"your_layer_id"``` to 1 of 3 framework filter array ```var KerasLayers = [...]```, ```var TensorFlowLayers = [...]``` or ```var CaffeLayers = []```. This should be like this ```var KerasLayers = ["RNN_Button", "GRU_Button", "your_layer_id"]```. This arrays are placed inside ```changeEvent() {}``` function.
+- Add ```"your_layer_id"``` to 1(or more) of 3 framework filter array ```var KerasLayers = [...]```, ```var TensorFlowLayers = [...]``` or ```var CaffeLayers = [...]```. This should be like this ```var KerasLayers = ["RNN_Button", "GRU_Button", "your_layer_id"]```. This arrays are placed inside ```changeEvent() {}``` function.
### Adding layer handling to the backend
From 7e197ff0d3be75dfc4a1c28e8f4dad9050be8304 Mon Sep 17 00:00:00 2001
From: ZeroZeroJedenJeden
<44526720+ZeroZeroJedenJeden@users.noreply.github.com>
Date: Fri, 2 Nov 2018 07:39:19 +0100
Subject: [PATCH 05/27] Add files via upload
---
ide/static/js/pane.js | 49 ++++++++++++++++++++++++++++++++-----------
1 file changed, 37 insertions(+), 12 deletions(-)
diff --git a/ide/static/js/pane.js b/ide/static/js/pane.js
index 8bd9c2a2c..ce16c540e 100644
--- a/ide/static/js/pane.js
+++ b/ide/static/js/pane.js
@@ -88,13 +88,13 @@ changeEvent() {
"GaussianNoise_Button", "GaussianDropout_Button", "AlphaDropout_Button", "TimeDistributed_Button",
"Bidirectional_Button", "RepeatVector_Button", "Masking_Button", "Permute_Button", "InnerProduct_Button",
"Deconvolution_Button", "Regularization_Button", "Softsign_Button", "Upsample_Button", "Pooling_Button",
- "LocallyConnected_Button"];
+ "LocallyConnected_Button", "Crop_Button"];
var TensorFlowLayers = ["RNN_Button", "GRU_Button", "LSTM_Button", "Embed_Button", "Eltwise_Button",
"ThresholdedReLU", "ReLU_Button", "PReLU_Button", "Softmax_Button", "BatchNorm_Button", "GaussianNoise_Button",
"GaussianDropout_Button", "AlphaDropout_Button", "TimeDistributed_Button", "Bidirectional_Button",
"RepeatVector_Button", "Masking_Button", "Permute_Button", "InnerProduct_Button", "Deconvolution_Button",
"Regularization_Button", "Softsign_Button", "Upsample_Button", "Pooling_Button", "LocallyConnected_Button",
- "SoftmaxWithLoss_Button", "SigmoidCrossEntropyLoss_Button"];
+ "SoftmaxWithLoss_Button", "SigmoidCrossEntropyLoss_Button", "Crop_Button", "DepthwiseConv_Button"];
var CaffeLayers = ["ImageData_Button", "HDF5Data_Button", "HDF5Output_Button", "Input_Button", "WindowData_Button",
"MemoryData_Button", "DummyData_Button", "Convolution_Button", "Pooling_Button", "SPP_Button", "Deconvolution_Button",
"Recurrent_Button", "RNN_Button", "LSTM_Button", "LRN_Button", "MVN_Button", "BatchNorm_Button",
@@ -104,23 +104,23 @@ changeEvent() {
"Reshape_Button", "BatchReindex_Button", "Split_Button", "Concat_Button", "Eltwise_Button", "Filter_Button",
"Reduction_Button", "Silence_Button", "ArgMax_Button", "Softmax_Button", "MultinomialLogisticLoss_Button",
"InfogainLoss_Button", "SoftmaxWithLoss_Button", "EuclideanLoss_Button", "HingeLoss_Button",
- "SigmoidCrossEntropyLoss_Button", "Accuracy_Button", "ContrastiveLoss_Button", "Data_Button"];
- var CheckBoxA = this.refs.CheckBoxA;
- var CheckBoxB = this.refs.CheckBoxB;
- var CheckBoxC = this.refs.CheckBoxC;
+ "SigmoidCrossEntropyLoss_Button", "Accuracy_Button", "ContrastiveLoss_Button", "Data_Button", "Crop_Button"];
+ var CheckBoxA = document.getElementById("CheckBoxA");
+ var CheckBoxB = document.getElementById("CheckBoxB");
+ var CheckBoxC = document.getElementById("CheckBoxC");
var visible = [];
if(CheckBoxA.checked == false & CheckBoxB.checked == false & CheckBoxC.checked == false){
for (let elem of $('.drowpdown-button')) {
elem.classList.remove("hide");
}
}
- if (this.refs.CheckBoxA.checked == true){
+ if (CheckBoxA.checked == true){
visible = visible.concat(KerasLayers);
}
- if (this.refs.CheckBoxB.checked == true){
+ if (CheckBoxB.checked == true){
visible = visible.concat(TensorFlowLayers);
}
- if (this.refs.CheckBoxC.checked == true){
+ if (CheckBoxC.checked == true){
visible = visible.concat(CaffeLayers);
}
@@ -141,9 +141,34 @@ changeEvent() {
render() {
return (
Q: What is Fabrik?
+ A: Fabrik is an online platform, created by CloudCV, allowing AI researchers and enthusiasts to
+ build and visualize deep learning models.
+ Q: What is the model zoo?
+ A: It is a collection of pre-built models that you can use.
+ To access it, simply click the folder icon in the left corner of the toolbox and pick a model.
+ You can find the available models
+ here.
+
+ Q: What do the Train/Test buttons mean?
+ A: They are two different modes of your model:
+ Train and Test - respectively for training your model with data and testing how and if it works.
+ Q: What does the import fuction do?
+ A: It allows you to import your previously created models in Caffe (.protoxt files),
+ Keras (.json files) and TensorFlow (.pbtxt files)
+ Q: What does the export function do?
+ A: You can use it to download models from Fabrik. You can train and test them directly on your computer,
+ using Caffe,
+ Keras
+ and TensorFlow.
+ Q: How can I contribute to Fabrik?
+ A: Please see the instructions listed
+ here
+
+
+ If you have anymore questions, please visit Fabrik's Github page available
+ here for more information.
+
);
+ this.openModal();
+ }
+ toggleSidebar() {
+ $('#sidebar').toggleClass('visible');
+ $('.sidebar-button').toggleClass('close');
+ }
+ zooModal() {
+ this.modalHeader = null;
+ this.modalContent = ;
+ this.openModal();
+ }
+ setModelFramework(e) {
+ const el = e.target;
+ const modelFramework = el.dataset.framework;
+ this.setState({modelFramework});
+ $('.import-textbox-tab.selected').removeClass('selected');
+ $(el).addClass('selected');
+ }
+ setModelFrameworkUrl(e) {
+ const el = e.target;
+ const modelFramework = el.dataset.framework;
+ this.setState({modelFramework});
+ $('.url-import-modal-tab.selected').removeClass('selected');
+ $(el).addClass('selected');
+ }
+ setModelConfig(e) {
+ const modelConfig = e.target.value;
+ this.setState({modelConfig});
+ }
+ setModelUrl(url) {
+ this.setState({ modelUrl: url});
+ }
+ textboxModal() {
+ this.modalHeader = null;
+ this.modalContent = ;
+ this.openModal();
+ }
+ urlModal() {
+ this.modalHeader = null;
+ this.modalContent = ;
+ this.openModal();
+ }
+ updateHistoryModal() {
+ $.ajax({
+ url: '/model_history',
+ dataType: 'json',
+ type: 'POST',
+ data: {
+ net_id: this.state.networkId
+ },
+ success : function (response) {
+ if (response.result == 'success') {
+ this.modalHeader = 'Model update history';
+ this.modalContent = ;
+ this.openModal();
+ }
+ else if (response.result == 'error') {
+ this.addError(response.error);
+ }
+ this.setState({ load: false });
+ }.bind(this),
+ error() {
+ this.setState({ load: false });
+ }
+ });
+ }
+ handleClick(event) {
+ event.preventDefault();
+ this.clickEvent = true;
+
+ const net = this.state.net;
+ // extracting layerId from Pane id which is in form LayerName_Button
+ const id = event.target.id.split('_')[0];
+ const prevLayerId = 'l' + (this.state.nextLayerId - 1);
+ const prev = net[prevLayerId];
+ const next = data[id];
+ const zoom = instance.getZoom();
+ const layer = {};
+ let phase = this.state.selectedPhase;
+
+ if (this.state.nextLayerId>0 //makes sure that there are other layers
+ && data[prev.info.type].endpoint.src == "Bottom" //makes sure that the source has a bottom
+ && next.endpoint.trg == "Top") { //makes sure that the target has a top
+ layer.connection = { input: [], output: [] };
+ layer.info = {
+ type: id.toString(),
+ phase,
+ class: ''
+ }
+ layer.params = {
+ 'endPoint' : [next['endpoint'], false] //This key is endpoint in data.js, but endPoint in everywhere else.
+ }
+ Object.keys(next.params).forEach(j => {
+ layer.params[j] = [next.params[j].value, false]; //copys all params from data.js
+ });
+ layer.props = JSON.parse(JSON.stringify(next.props)) //copys all props rom data.js
+ layer.state = {
+ top: `${(parseInt(prev.state.top.split('px')[0])/zoom + 80)}px`, // This makes the new layer is exactly 80px under the previous one.
+ left: `${(parseInt(prev.state.left.split('px')[0])/zoom)}px`, // This aligns the new layer with the previous one.
+ class: ''
+ }
+ layer.props.name = `${next.name}${this.state.nextLayerId}`;
+ prev.connection.output.push(`l${this.state.nextLayerId}`);
+ layer.connection.input.push(`l${this.state.nextLayerId-1}`);
+ this.addNewLayer(layer, prevLayerId);
+ }
+
+ else if (Object.keys(net).length == 0) { // if there are no layers
+ layer.connection = { input: [], output: [] };
+ layer.info = {
+ type: id.toString(),
+ phase,
+ class: ''
+ }
+ layer.params = {
+ 'endPoint' : [next['endpoint'], false] //This key is endpoint in data.js, but endPoint in everywhere else.
+ }
+ Object.keys(next.params).forEach(j => {
+ layer.params[j] = [next.params[j].value, false]; //copys all params from data.js
+ });
+ layer.props = JSON.parse(JSON.stringify(next.props)) //copys all props from data.js
+ const height = Math.round(0.05*window.innerHeight, 0); // 5% of screen height, rounded to zero decimals
+ const width = Math.round(0.35*window.innerWidth, 0); // 35% of screen width, rounded to zero decimals
+ var top = height + Math.ceil(81-height);
+ var left = width;
+ layer.state = {
+ top: `${top}px`,
+ left: `${left}px`,
+ class: ''
+ }
+ layer.props.name = `${next.name}${this.state.nextLayerId}`;
+ this.addNewLayer(layer);
+ }
+ }
+ render() {
+ let loader = null;
+ if (this.state.load) {
+ loader = (
+ Multinomial Logistic Loss
+ Infogain Loss
+ Softmax With Loss
+ Euclidean Loss
+ Hinge Loss
+ Sigmoid Cross Entropy Loss
+ Accuracy
+ Contrastive Loss
+ Python
+
- Multinomial Logistic Loss
- Infogain Loss
- Softmax With Loss
- Euclidean Loss
- Hinge Loss
- Sigmoid Cross Entropy Loss
- Accuracy
- Contrastive Loss
- Python
-
-
- );
- }
-}
-
-Pane.propTypes = {
- handleClick: React.PropTypes.func.isRequired,
- setDraggingLayer: React.PropTypes.func.isRequired
-};
-export default Pane;
From 244980b43fac51fa23768adc3a57d8aa82185735 Mon Sep 17 00:00:00 2001
From: ZeroZeroJedenJeden
<44526720+ZeroZeroJedenJeden@users.noreply.github.com>
Date: Sat, 3 Nov 2018 18:57:17 +0100
Subject: [PATCH 18/27] Delete content.js
---
content.js | 1416 ----------------------------------------------------
1 file changed, 1416 deletions(-)
delete mode 100644 content.js
diff --git a/content.js b/content.js
deleted file mode 100644
index d620739b7..000000000
--- a/content.js
+++ /dev/null
@@ -1,1416 +0,0 @@
-import React from 'react';
-import Canvas from './canvas';
-import Pane from './pane';
-import SetParams from './setParams';
-import Tooltip from './tooltip'
-import TopBar from './topBar';
-import Tabs from './tabs';
-import data from './data';
-import netLayout from './netLayout_vertical';
-import Modal from 'react-modal';
-import ModelZoo from './modelZoo';
-import Login from './login';
-import ImportTextbox from './importTextbox';
-import UrlImportModal from './urlImportModal';
-import UserProfile from './UserProfile';
-import UpdateHistoryModal from './updateHistoryModal';
-import CommentSidebar from './CommentSidebar';
-import FilterBar from './filterbar';
-import $ from 'jquery'
-
-const infoStyle = {
- content : {
- top : '50%',
- left : '50%',
- right : '60%',
- bottom : 'auto',
- marginRight : '-50%',
- transform : 'translate(-50%, -50%)',
- borderRadius : '8px'
- },
- overlay: {
- zIndex : 100
- }
-};
-
-class Content extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- net: {},
- net_name: 'Untitled',
- networkId: 0,
- draggingLayer: null,
- selectedLayer: null,
- commentOnLayer: null,
- hoveredLayer: null,
- nextLayerId: 0,
- rebuildNet: false,
- selectedPhase: 0,
- error: [],
- info: [],
- load: false,
- modalIsOpen: false,
- totalParameters: 0,
- modelConfig: null,
- modelFramework: 'caffe',
- isShared: false,
- isForked: false,
- socket: null,
- randomUserId: null,
- highlightColor: '#000000'
- };
- this.addNewLayer = this.addNewLayer.bind(this);
- this.changeSelectedLayer = this.changeSelectedLayer.bind(this);
- this.changeHoveredLayer = this.changeHoveredLayer.bind(this);
- this.componentWillMount = this.componentWillMount.bind(this);
- this.modifyLayer = this.modifyLayer.bind(this);
- this.setDraggingLayer = this.setDraggingLayer.bind(this);
- this.changeNetName = this.changeNetName.bind(this);
- this.adjustParameters = this.adjustParameters.bind(this);
- this.modifyLayerParams = this.modifyLayerParams.bind(this);
- this.deleteLayer = this.deleteLayer.bind(this);
- this.exportPrep = this.exportPrep.bind(this);
- this.exportNet = this.exportNet.bind(this);
- this.importNet = this.importNet.bind(this);
- this.changeNetStatus = this.changeNetStatus.bind(this);
- this.changeNetPhase = this.changeNetPhase.bind(this);
- this.dismissError = this.dismissError.bind(this);
- this.addError = this.addError.bind(this);
- this.dismissAllErrors = this.dismissAllErrors.bind(this);
- this.addInfo = this.addInfo.bind(this);
- this.dismissInfo = this.dismissInfo.bind(this);
- this.copyTrain = this.copyTrain.bind(this);
- this.trainOnly = this.trainOnly.bind(this);
- this.openModal = this.openModal.bind(this);
- this.closeModal = this.closeModal.bind(this);
- this.saveDb = this.saveDb.bind(this);
- this.loadDb = this.loadDb.bind(this);
- this.infoModal = this.infoModal.bind(this);
- this.faqModal = this.faqModal.bind(this);
- this.toggleSidebar = this.toggleSidebar.bind(this);
- this.zooModal = this.zooModal.bind(this);
- this.textboxModal = this.textboxModal.bind(this);
- this.urlModal = this.urlModal.bind(this);
- this.updateHistoryModal =this.updateHistoryModal.bind(this);
- this.setModelConfig = this.setModelConfig.bind(this);
- this.setModelFramework = this.setModelFramework.bind(this);
- this.setModelUrl = this.setModelUrl.bind(this);
- this.setModelFrameworkUrl = this.setModelFrameworkUrl.bind(this);
- this.loadLayerShapes = this.loadLayerShapes.bind(this);
- this.calculateParameters = this.calculateParameters.bind(this);
- this.getLayerParameters = this.getLayerParameters.bind(this);
- this.updateLayerShape = this.updateLayerShape.bind(this);
- this.createSocket = this.createSocket.bind(this);
- this.onSocketConnect = this.onSocketConnect.bind(this);
- this.sendSocketMessage = this.sendSocketMessage.bind(this);
- this.onSocketMessage = this.onSocketMessage.bind(this);
- this.onSocketOpen = this.onSocketOpen.bind(this);
- this.onSocketError = this.onSocketError.bind(this);
- this.waitForConnection = this.waitForConnection.bind(this);
- this.setUserId = this.setUserId.bind(this);
- this.getUserId = this.getUserId.bind(this);
- this.getUserName = this.getUserName.bind(this);
- this.setUserName = this.setUserName.bind(this);
- this.modalContent = null;
- this.modalHeader = null;
- // Might need to improve the logic of clickEvent
- this.clickEvent = false;
- this.handleClick = this.handleClick.bind(this);
- this.performSharedUpdate = this.performSharedUpdate.bind(this);
- this.performSharedAdd = this.performSharedAdd.bind(this);
- this.performSharedDelete = this.performSharedDelete.bind(this);
- this.addHighlightOnLayer = this.addHighlightOnLayer.bind(this);
- this.addSharedComment = this.addSharedComment.bind(this);
- this.changeCommentOnLayer = this.changeCommentOnLayer.bind(this);
- this.getRandomColor = this.getRandomColor.bind(this);
- this.downloadModel = this.downloadModel.bind(this);
- }
- getRandomColor() {
- var rint = Math.round(0xffffff * Math.random());
- return ('#0' + rint.toString(16)).replace(/^#0([0-9a-f]{6})$/i, '#$1');
- }
- createSocket(url) {
- return new WebSocket(url);
- }
- onSocketConnect() {
- // binder for socket
- const socket = this.state.socket;
- socket.onopen = this.onSocketOpen;
- socket.onmessage = this.onSocketMessage;
- socket.onerror = this.onSocketError;
- }
- onSocketOpen() {
- // socket opening goes here
- // console.log('socket opened for RTC....');
- }
- onSocketMessage(message) {
- // message received on socket
- let data = JSON.parse(message['data']);
- //let rebuildNet = false;
- //let nextLayerId = this.state.nextLayerId;
- const net = this.state.net;
-
- if(data['action'] == 'ExportNet') {
- if(data['result'] == 'success') {
- this.downloadModel(data);
- }
- else {
- this.addError(data['error']);
- }
- }
- else if(data['action'] == 'UpdateHighlight' && data['randomId'] != this.state.randomId) {
- let addHighlightToId = data['addHighlightTo'];
- let removeHighlightFromId = data['removeHighlightFrom'];
- let username = data['username'];
-
- if (addHighlightToId != null) {
- if (('highlight' in net[addHighlightToId]) == false) {
- net[addHighlightToId]['highlight'] = [];
- net[addHighlightToId]['highlightColor'] = [];
- }
- net[addHighlightToId]['highlight'].push(username);
- net[addHighlightToId]['highlightColor'].push(data['highlightColor'])
- }
- if (removeHighlightFromId != null) {
- let index = net[removeHighlightFromId]['highlight'].indexOf(removeHighlightFromId);
- net[removeHighlightFromId]['highlight'].splice(index, 1);
- net[removeHighlightFromId]['highlightColor'].splice(index, 1);
- }
-
- this.setState({
- net: net
- });
- }
- else {
- if (data['randomId'] != this.state.randomId) {
- if(data['action'] == 'UpdateParam') {
- if (data['isProp']) {
- net[data['layerId']]['props'][data['param']] = data['value'];
- }
- else {
- net[data['layerId']]['params'][data['param']][0] = data['value'];
- }
- this.setState({ net: net });
- }
- else if (data['action'] == 'AddLayer') {
- this.addNewLayer(data['layer'], data['prevLayerId'], false);
- this.changeNetStatus(true);
- }
- else if(data['action'] == 'DeleteLayer') {
- this.deleteLayer(data['layerId'], false);
- }
- else if(data['action'] == 'AddComment') {
- if (('comments' in net[data['layerId']]) == false) {
- net[data['layerId']]['comments'] = [];
- }
- net[data['layerId']]['comments'].push(data['comment']);
- this.setState({ net });
- }
- }
- }
- }
- sendSocketMessage(message) {
- // generalized method to send message to socket
- const socket = this.state.socket;
- socket.send(JSON.stringify(message));
- }
- onSocketError(error) {
- // socket error handling goes here
- this.addError(error);
- }
- waitForConnection(callback, interval=100) {
- // delay hook used while creating a new socket
- const socket = this.state.socket;
- if (socket != null && socket.readyState === 1) {
- callback();
- }
- else {
- var that = this;
- setTimeout(function () {
- that.waitForConnection(callback, interval);
- }, interval);
- }
- }
- performSharedUpdate(layerId, param, value, isProp) {
- // method to handle pre-processing of message before sending
- // through a socket based on type of action, will be extended further
- // as per requirement of message types.
- let msg = '';
- msg = 'Layer parameter updated';
-
- this.sendSocketMessage({
- layerId: layerId,
- param: param,
- value: value,
- isProp: isProp,
- action: 'UpdateParam',
- message: msg,
- nextLayerId: this.state.nextLayerId,
- randomId: this.state.randomId
- });
- }
- performSharedAdd(layer, prevLayerId, nextLayerId, layerId) {
- let msg = 'New layer added';
-
- this.sendSocketMessage({
- layer: layer,
- prevLayerId: prevLayerId,
- layerId: layerId,
- action: 'AddLayer',
- message: msg,
- nextLayerId: nextLayerId,
- randomId: this.state.randomId
- })
- }
- performSharedDelete(net, layerId, nextLayerId) {
- let msg = 'Delete existing layer';
-
- this.sendSocketMessage({
- layerId: layerId,
- nextLayerId: nextLayerId,
- action: 'DeleteLayer',
- message: msg,
- randomId: this.state.randomId
- })
- }
- addHighlightOnLayer(layerId, previousLayerId) {
- this.sendSocketMessage({
- addHighlightTo: layerId,
- removeHighlightFrom: previousLayerId,
- userId: this.getUserId(),
- action: 'UpdateHighlight',
- randomId: this.state.randomId,
- highlightColor: this.state.highlightColor,
- username: this.getUserName()
- })
- }
- addSharedComment(layerId, comment) {
- this.sendSocketMessage({
- layerId: layerId,
- comment: comment,
- action: 'AddComment',
- randomId: this.state.randomId
- })
- }
- downloadModel(response) {
- const downloadAnchor = document.getElementById('download');
- downloadAnchor.download = response.name;
- downloadAnchor.href = response.url;
- downloadAnchor.click();
- if ('customLayers' in response && response.customLayers.length !== 0) {
- this.addInfo(
-
- This network uses custom layers, to download click on:
- {response.customLayers.map((layer, index) => {
- return (
-
-
- {layer.name}
-
- {index != response.customLayers.length-1 && , }
-
- );
- })}
-
- );
- }
- }
- openModal() {
- this.setState({ modalIsOpen: true });
- }
- closeModal() {
- this.setState({ modalIsOpen: false });
- }
- setUserId(user_id) {
- UserProfile.setUserId(user_id);
- }
- getUserId() {
- return UserProfile.getUserId();
- }
- setUserName(name) {
- UserProfile.setUsername(name);
- }
- getUserName() {
- return UserProfile.getUsername();
- }
- addNewLayer(layer, prevLayerId, publishUpdate=true) {
- const net = this.state.net;
- const layerId = `l${this.state.nextLayerId}`;
- const nextLayerId = this.state.nextLayerId;
- var totalParameters = this.state.totalParameters;
- // shared addition of layer connections
- if (publishUpdate == false) {
- if (Array.isArray(prevLayerId)) {
- for (var i=0;i {
- if (intParams.includes(param)){
- net[layerId].params[param][0] = parseInt(net[layerId].params[param][0]);
- if (isNaN(net[layerId].params[param][0]))
- net[layerId].params[param][0] = 0;
- }
- });
- this.updateLayerShape(net, layerId);
- // Check for only layers with valid shape
- if (net[layerId]['shape']['input'] != null && net[layerId]['shape']['output'] != null) {
- net[layerId]['info']['parameters'] = this.getLayerParameters(net[layerId], net);
- totalParameters += net[layerId]['info']['parameters'];
- }
- this.setState({ net, nextLayerId: this.state.nextLayerId + 1, totalParameters: totalParameters });
- // if model is in RTC mode send updates to respective sockets
- if (this.state.isShared && !this.state.isForked && publishUpdate) {
- this.performSharedAdd(net[layerId], prevLayerId, nextLayerId + 1, layerId);
- }
- }
- changeCommentOnLayer(layerId) {
- this.setState({
- commentOnLayer: layerId
- });
- }
- changeSelectedLayer(layerId) {
- const net = this.state.net;
- if (this.state.selectedLayer) {
- // remove css from previously selected layer
- net[this.state.selectedLayer].info.class = '';
- }
- if (layerId) {
- // css when layer is selected
- net[layerId].info.class = 'selected';
- }
- if (this.state.isShared && !this.state.isForked) {
- this.addHighlightOnLayer(layerId, this.state.selectedLayer);
- }
- this.setState({ net, selectedLayer: layerId });
- }
- changeHoveredLayer(layerId) {
- const net = this.state.net;
- if (this.state.hoveredLayer && this.state.hoveredLayer in net) {
- // remove css from previously selected layer
- net[this.state.hoveredLayer].info.class = '';
- }
- if (layerId) {
- // css when layer is selected
- net[layerId].info.class = 'hover';
- }
- this.setState({ net, hoveredLayer: layerId });
- }
-
- modifyLayer(layer, layerId = this.state.selectedLayer) {
- const net = this.state.net;
- var oldLayerParams = this.state.totalParameters;
- if (net[layerId]['shape']['input'] != null && net[layerId]['shape']['output'] != null)
- oldLayerParams -= net[layerId]['info']['parameters'];
- net[layerId] = layer;
- this.updateLayerShape(net, layerId);
- if (net[layerId]['shape']['input']!=null && net[layerId]['shape']['output']!=null) {
- net[layerId]['info']['parameters'] = this.getLayerParameters(net[layerId], net);
- oldLayerParams += net[layerId]['info']['parameters'];
- }
- this.setState({ net: net, totalParameters: oldLayerParams });
- }
- modifyLayerParams(layer, layerId = this.state.selectedLayer) {
- const net = this.state.net;
- let index;
-
- if (this.state.selectedPhase === 1 && net[layerId].info.phase === null) {
- // we need to break this common layer for each phase
- const testLayer = JSON.parse(JSON.stringify(layer));
- const trainLayer = JSON.parse(JSON.stringify(net[layerId]));
-
- testLayer.info.phase = 1;
- (testLayer.connection.output).forEach(outputId => {
- if (net[outputId].info.phase === 0) {
- index = testLayer.connection.output.indexOf(outputId);
- testLayer.connection.output.splice(index, 1);
- index = net[outputId].connection.input.indexOf(layerId);
- net[outputId].connection.input.splice(index, 1);
- }
- });
- (testLayer.connection.input).forEach(inputId => {
- if (net[inputId].info.phase === 0) {
- index = testLayer.connection.input.indexOf(inputId);
- testLayer.connection.input.splice(index, 1);
- index = net[inputId].connection.output.indexOf(layerId);
- net[inputId].connection.output.splice(index, 1);
- }
- });
- net[layerId] = testLayer;
- this.setState({ net });
-
- trainLayer.info.phase = 0;
- trainLayer.props.name = `${data[trainLayer.info.type].name}${this.state.nextLayerId}`;
- (trainLayer.connection.output).forEach(outputId => {
- if (net[outputId].info.phase === 1) {
- index = trainLayer.connection.output.indexOf(outputId);
- trainLayer.connection.output.splice(index, 1);
- }
- });
- (trainLayer.connection.input).forEach(inputId => {
- if (net[inputId].info.phase === 1) {
- index = trainLayer.connection.input.indexOf(inputId);
- trainLayer.connection.input.splice(index, 1);
- }
- });
-
- const nextLayerId = `l${this.state.nextLayerId}`;
-
- (trainLayer.connection.output).forEach(outputId => {
- net[outputId].connection.input.push(nextLayerId);
- });
-
- const inputIds = [];
- (trainLayer.connection.input).forEach(inputId => {
- net[inputId].connection.output.push(nextLayerId);
- inputIds.push(inputId)
- });
-
- this.addNewLayer(trainLayer, inputIds);
- // if model is in RTC mode addNewLayer will send updates to respective sockets
- } else {
- net[layerId] = layer;
- this.setState({ net });
- }
- }
- deleteLayer(layerId, publishUpdate=true) {
- const net = this.state.net;
- const input = net[layerId].connection.input;
- const output = net[layerId].connection.output;
- const layerIdNum = parseInt(layerId.substring(1,layerId.length)); //numeric value of the layerId
- const nextLayerId = this.state.nextLayerId - 1 == layerIdNum ? layerIdNum : this.state.nextLayerId;
- //if last layer was deleted nextLayerId is replaced by deleted layer's id
- var totalParameters = this.state.totalParameters;
- let index;
- totalParameters -= this.getLayerParameters(net[layerId], net);
- delete net[layerId];
- input.forEach(inputId => {
- index = net[inputId].connection.output.indexOf(layerId);
- net[inputId].connection.output.splice(index, 1);
- });
- output.forEach(outputId => {
- index = net[outputId].connection.input.indexOf(layerId);
- net[outputId].connection.input.splice(index, 1);
- });
- this.setState({ net, selectedLayer: null, nextLayerId: nextLayerId, totalParameters: totalParameters });
- // if model is in RTC mode send updates to respective sockets
- // to avoid infinite loop of deletion over multiple session
- if (this.state.isShared && !this.state.isForked && publishUpdate == true) {
- this.performSharedDelete(net, layerId, nextLayerId);
- }
- }
-
- updateLayerShape(net, layerId) {
- const netData = JSON.parse(JSON.stringify(net));
- Object.keys(netData[layerId].params).forEach(param => {
- netData[layerId].params[param] = netData[layerId].params[param][0];
- });
- net[layerId]['shape'] = {};
- net[layerId]['shape']['input'] = null;
- net[layerId]['shape']['output'] = null;
- net[layerId]['info']['parameters'] = 0;
-
- $.ajax({
- url: 'layer_parameter/',
- dataType: 'json',
- type: 'POST',
- async: false,
- data: {
- net: JSON.stringify(netData),
- layerId: layerId
- },
- success : function (response) {
- if (response.result == "success") {
- if (response.net[layerId]['shape']['input'] != null)
- net[layerId]['shape']['input'] = response.net[layerId]['shape']['input'].slice();
- if (response.net[layerId]['shape']['output'] != null)
- net[layerId]['shape']['output'] = response.net[layerId]['shape']['output'].slice();
- }
- else
- this.addError(response.error);
- }.bind(this)
- });
- }
- getLayerParameters(layer, net) {
- // check for layers with no shape to avoid errors
- // this can be improved further.
- if (layer['shape']['input'] == null || layer['shape']['output'] == null) {
- return 0;
- }
- // obtain the total parameters of the model
- var weight_params = 0;
- var bias_params = 0;
-
- var filter_layers = ["Convolution", "Deconvolution"];
- var fc_layers = ["InnerProduct", "Embed", "Recurrent", "LSTM"];
-
- if(filter_layers.includes(layer.info.type)) {
- // if layer is Conv or DeConv calculating total parameter of the layer using:
- // N_Input * K_H * K_W * N_Output
- var kernel_params = 1;
- if('kernel_h' in layer.params && layer.params['kernel_h'][0] != '')
- kernel_params *= layer.params['kernel_h'][0];
- if('kernel_w' in layer.params && layer.params['kernel_w'][0] != '')
- kernel_params *= layer.params['kernel_w'][0];
- if('kernel_d' in layer.params && layer.params['kernel_d'][0] != '')
- kernel_params *= layer.params['kernel_d'][0];
-
- weight_params = layer.shape['input'][0] * kernel_params * layer.params['num_output'][0];
- bias_params += layer.params['num_output'][0];
- }
- else if(fc_layers.includes(layer.info.type)) {
- // if layer is one of Recurrent layer or Fully Connected layers calculate parameters using:
- // Num_Input * Num_Ouput
- // if previous layer is D-dimensional then obtain the total inputs by (N1xN2x...xNd)
- var inputParams = 1;
- for(var i=0;i 0) {
- const childLayer = net[layer.connection['output'][0]];
- if(childLayer.info.type == "Scale") {
- if(childLayer.params['scale'][0] == true)
- cnt +=1
- if(childLayer.params['bias_term'][0] == true)
- cnt +=1;
- }
- }
- weight_params = cnt * layer.shape['output'][0];
- }
- if('use_bias' in layer.params) {
- if (layer.params['use_bias'][0] == false)
- bias_params = 0;
- }
-
- // Update the total parameters of model after considering this layer.
- return (weight_params + bias_params);
- }
- calculateParameters(net) {
- // Iterate over model's each layer & separately add the contribution of each layer
- var totalParameters = 0;
-
- Object.keys(net).sort().forEach(layerId => {
- const layer = net[layerId];
- net[layerId]['info']['parameters'] = this.getLayerParameters(layer, net);
- totalParameters += net[layerId]['info']['parameters'];
- });
- this.setState({ net: net, totalParameters: totalParameters});
- }
- loadLayerShapes() {
- this.dismissAllErrors();
- // Making call to endpoint inorder to obtain shape of each layer i.e. input & output shape
- const netData = JSON.parse(JSON.stringify(this.state.net));
- $.ajax({
- url: 'model_parameter/',
- dataType: 'json',
- type: 'POST',
- data: {
- net: JSON.stringify(netData)
- },
- success : function (response) {
- const net = response.net;
- // call to intermediate method which will iterate over layers & calculate the parameters separately
- this.calculateParameters(net);
- // update the net object with shape attributes added
- this.setState({ net });
- }.bind(this),
- error() {
- //console.log('error'+response.error);
- }
- });
- }
- exportPrep(callback) {
- this.dismissAllErrors();
- const error = [];
- const netObj = JSON.parse(JSON.stringify(this.state.net));
- if (Object.keys(netObj).length == 0) {
- this.addError("No model available for export");
- return;
- }
-
- Object.keys(netObj).forEach(layerId => {
- const layer = netObj[layerId];
- Object.keys(layer.params).forEach(param => {
- layer.params[param] = layer.params[param][0];
- const paramData = data[layer.info.type].params[param];
- if (layer.info.type == 'Python' || param == 'endPoint'){
- return;
- }
- if (paramData.required === true && layer.params[param] === '') {
- error.push(`Error: "${paramData.name}" required in "${layer.props.name}" Layer`);
- }
- });
- });
- if (error.length) {
- this.setState({ error });
- } else {
- callback(netObj);
- }
- }
- exportNet(framework) {
- this.exportPrep(function(netData) {
- Object.keys(netData).forEach(layerId => {
- delete netData[layerId].state;
- if (netData[layerId]['comments']) {
- // not adding comments as part of export parameters of net
- delete netData[layerId].comments;
- }
- });
-
- this.sendSocketMessage({
- framework: framework,
- net: JSON.stringify(netData),
- action: 'ExportNet',
- net_name: this.state.net_name,
- randomId: this.state.randomId
- });
-
- }.bind(this));
- }
- importNet(framework, id) {
- this.dismissAllErrors();
- this.closeModal();
- this.clickEvent = false;
- const url = {'caffe': '/caffe/import', 'keras': '/keras/import', 'tensorflow': '/tensorflow/import'};
- const formData = new FormData();
- const caffe_fillers = ['constant', 'gaussian', 'positive_unitball', 'uniform', 'xavier', 'msra', 'bilinear'];
- const keras_fillers = ['Zeros', 'Ones', 'Constant', 'RandomNormal', 'RandomUniform', 'TruncatedNormal',
- 'VarianceScaling', 'Orthogonal', 'Identity', 'lecun_uniform', 'glorot_normal', 'glorot_uniform', 'he_normal', 'he_uniform'];
- if (framework == 'samplecaffe'){
- framework = 'caffe'
- formData.append('sample_id', id);
- }
- else if (framework == 'samplekeras'){
- framework = 'keras'
- formData.append('sample_id', id);
- }
- else if (framework == 'input') {
- framework = this.state.modelFramework;
- formData.append('config', this.state.modelConfig);
- }
- else if (framework == 'url') {
- framework = this.state.modelFramework;
- formData.append('url', this.state.modelUrl);
- }
- else
- formData.append('file', $('#inputFile'+framework)[0].files[0]);
- this.setState({ load: true });
- if (framework == 'keras'){
- var fillers = keras_fillers;
- }
- else{
- fillers = caffe_fillers;
- }
- data['Convolution']['params']['weight_filler']['options'] = fillers;
- data['Convolution']['params']['bias_filler']['options'] = fillers;
- data['Deconvolution']['params']['weight_filler']['options'] = fillers;
- data['Deconvolution']['params']['bias_filler']['options'] = fillers;
- data['Recurrent']['params']['weight_filler']['options'] = fillers;
- data['Recurrent']['params']['bias_filler']['options'] = fillers;
- data['RNN']['params']['weight_filler']['options'] = fillers;
- data['RNN']['params']['bias_filler']['options'] = fillers;
- data['LSTM']['params']['weight_filler']['options'] = fillers;
- data['LSTM']['params']['bias_filler']['options'] = fillers;
- data['InnerProduct']['params']['weight_filler']['options'] = fillers;
- data['InnerProduct']['params']['bias_filler']['options'] = fillers;
- data['Embed']['params']['weight_filler']['options'] = fillers;
- data['Bias']['params']['filler']['options'] = fillers;
- $.ajax({
- url: url[framework],
- dataType: 'json',
- type: 'POST',
- data: formData,
- processData: false, // tell jQuery not to process the data
- contentType: false,
- success: function (response) {
- if (response.result === 'success'){
- this.initialiseImportedNet(response.net,response.net_name);
- if (Object.keys(this.state.net).length)
- this.loadLayerShapes();
- } else if (response.result === 'error'){
- this.addError(response.error);
- }
- this.setState({ load: false });
- }.bind(this),
- error : function () {
- this.setState({ load: false });
- this.addError("Error");
- }.bind(this)
- });
- }
- initialiseImportedNet(net,net_name) {
- // this line will unmount all the layers
- // so that the new imported layers will all be mounted again
- const tempError = {};
- // Initialize Python layer parameters to be empty
- data['Python']['params'] = {}
- this.setState({ net: {}, selectedLayer: null, hoveredLayer: null, nextLayerId: 0, selectedPhase: 0, error: [] });
- Object.keys(net).forEach(layerId => {
- var layer = net[layerId];
- const type = layer.info.type;
- // extract unique input & output nodes
- net[layerId]['connection']['input'] = net[layerId]['connection']['input'].filter((val,id,array) => array.indexOf(val) == id);
- net[layerId]['connection']['output'] = net[layerId]['connection']['output'].filter((val,id,array) => array.indexOf(val) == id);
- // const index = +layerId.substring(1);
- if (this.state.isShared == false) {
- // if network object is being loaded from db avoid reinitializing the frontend part
- if (type == 'Python') {
- Object.keys(layer.params).forEach(param => {
- layer.params[param] = [layer.params[param], false];
- });
- layer.params['caffe'] = [true, false];
- }
- if (data.hasOwnProperty(type)) {
- // add the missing params with default values
- Object.keys(data[type].params).forEach(param => {
- if (!layer.params.hasOwnProperty(param)) {
- // The initial value is a list with the first element being the actual value, and the second being a flag which
- // controls whether the parameter is disabled or not on the frontend.
- layer.params[param] = [data[type].params[param].value, false];
- }
- else {
- layer.params[param] = [layer.params[param], false];
- }
- });
- if (type == 'Convolution' || type == 'Pooling' || type == 'Upsample' || type == 'LocallyConnected' || type == 'Eltwise'){
- layer = this.adjustParameters(layer, 'layer_type', layer.params['layer_type'][0]);
- }
- // layer.props = JSON.parse(JSON.stringify(data[type].props));
- layer.props = {};
- // default name
- layer.props.name = layerId;
- }
- else {
- tempError[type] = null;
- }
- }
- });
- // initialize the position of layers
- if (tempError.length == undefined) {
- netLayout(net);
- }
-
- if (Object.keys(tempError).length) {
- const errorLayers = Object.keys(tempError).join(', ');
- this.setState({ error: [`Error: Currently we do not support these layers: ${errorLayers}.`] });
- } else {
- instance.detachEveryConnection();
- instance.deleteEveryEndpoint();
- this.setState({
- net,
- net_name,
- selectedLayer: null,
- hoveredLayer: null,
- nextLayerId: Object.keys(net).length,
- rebuildNet: true,
- selectedPhase: 0,
- error: [],
- totalParameters: 0
- });
- }
- }
- setDraggingLayer(id) {
- this.setState({ draggingLayer: id })
- }
- changeNetName(event) {
- this.setState({net_name: event.target.value});
- }
- adjustParameters(layer, para, value) {
- if (para == 'layer_type'){
- if (layer.info['type'] == 'Convolution' || layer.info['type'] == 'Pooling'){
- if (value == '1D'){
- layer.params['caffe'] = [false, false];
- layer.params['kernel_h'] = [layer.params['kernel_h'][0], true];
- layer.params['kernel_d'] = [layer.params['kernel_d'][0], true];
- layer.params['pad_h'] = [layer.params['pad_h'][0], true];
- layer.params['pad_d'] = [layer.params['pad_d'][0], true];
- layer.params['stride_h'] = [layer.params['stride_h'][0], true];
- layer.params['stride_d'] = [layer.params['stride_d'][0], true];
- if (layer.info['type'] == 'Convolution'){
- layer.params['dilation_h'] = [layer.params['dilation_h'][0], true];
- layer.params['dilation_d'] = [layer.params['dilation_d'][0], true];
- }
- }
- else if (value == '2D'){
- layer.params['caffe'] = [true, false];
- layer.params['kernel_h'] = [layer.params['kernel_h'][0], false];
- layer.params['kernel_d'] = [layer.params['kernel_d'][0], true];
- layer.params['pad_h'] = [layer.params['pad_h'][0], false];
- layer.params['pad_d'] = [layer.params['pad_d'][0], true];
- layer.params['stride_h'] = [layer.params['stride_h'][0], false];
- layer.params['stride_d'] = [layer.params['stride_d'][0], true];
- if (layer.info['type'] == 'Convolution'){
- layer.params['dilation_h'] = [layer.params['dilation_h'][0], false];
- layer.params['dilation_d'] = [layer.params['dilation_d'][0], true];
- }
- }
- else {
- layer.params['caffe'] = [false, false];
- layer.params['kernel_h'] = [layer.params['kernel_h'][0], false];
- layer.params['kernel_d'] = [layer.params['kernel_d'][0], false];
- layer.params['pad_h'] = [layer.params['pad_h'][0], false];
- layer.params['pad_d'] = [layer.params['pad_d'][0], false];
- layer.params['stride_h'] = [layer.params['stride_h'][0], false];
- layer.params['stride_d'] = [layer.params['stride_d'][0], false];
- if (layer.info['type'] == 'Convolution'){
- layer.params['dilation_h'] = [layer.params['dilation_h'][0], false];
- layer.params['dilation_d'] = [layer.params['dilation_d'][0], false];
- }
- }
- }
- else if (layer.info['type'] == 'Upsample'){
- if (value == '1D'){
- layer.params['size_h'] = [layer.params['size_h'][0], true];
- layer.params['size_d'] = [layer.params['size_d'][0], true];
- }
- else if (value == '2D'){
- layer.params['size_h'] = [layer.params['size_h'][0], false];
- layer.params['size_d'] = [layer.params['size_d'][0], true];
- }
- else{
- layer.params['size_h'] = [layer.params['size_h'][0], false];
- layer.params['size_d'] = [layer.params['size_d'][0], false];
- }
- }
- else if (layer.info['type'] == 'LocallyConnected'){
- if (value == '1D'){
- layer.params['kernel_h'] = [layer.params['kernel_h'][0], true];
- layer.params['stride_h'] = [layer.params['stride_h'][0], true];
- }
- }
- else if (layer.info['type'] == 'Eltwise'){
- if (value == 'Average' || value == 'Dot'){
- layer.params['caffe'] = [false, false];
- }
- }
- }
- return layer;
- }
- changeNetStatus(bool) {
- this.setState({ rebuildNet: bool });
- }
- changeNetPhase(phase) {
- const net = this.state.net;
- this.setState({ net, selectedPhase: phase, rebuildNet: true });
- }
- dismissError(errorIndex) {
- const error = this.state.error;
- error.splice(errorIndex, 1);
- this.setState({ error, info: []});
- }
- addError(errorText) {
- const error = this.state.error;
- error.push(errorText);
- this.setState({ error });
- }
- dismissAllErrors() {
- this.setState({ error: [] });
- this.setState({ info: [] });
- }
- addInfo(infoContent) {
- const info = this.state.info;
- info.push(infoContent)
- this.setState({ info, error: [] })
- }
- dismissInfo(infoIndex) {
- const info = this.state.info;
- info.splice(infoIndex, 1);
- this.setState({ info });
- }
- copyTrain() {
- const net = this.state.net;
- Object.keys(net).forEach(layerId => {
- if (net[layerId].info.phase === 0) {
- net[layerId].info.phase = null;
- } else if (net[layerId].info.phase === 1) {
- this.deleteLayer(layerId);
- }
- });
- this.setState({
- net,
- selectedLayer: null,
- rebuildNet: true
- });
- }
- trainOnly() {
- const net = this.state.net;
- const layer = net[this.state.selectedLayer];
- const layerId = this.state.selectedLayer;
- let index;
- if (layer.info.phase == null) {
- (layer.connection.output).forEach(outputId => {
- if (net[outputId].info.phase === 1) {
- index = layer.connection.output.indexOf(outputId);
- layer.connection.output.splice(index, 1);
- index = net[outputId].connection.input.indexOf(layerId);
- net[outputId].connection.input.splice(index, 1);
- }
- });
- (layer.connection.input).forEach(inputId => {
- if (net[inputId].info.phase === 1) {
- index = layer.connection.input.indexOf(inputId);
- layer.connection.input.splice(index, 1);
- index = net[inputId].connection.output.indexOf(layerId);
- net[inputId].connection.output.splice(index, 1);
- }
- });
- }
- layer.info.phase = 0;
- this.setState({ net });
- }
- saveDb(){
- let netData = this.state.net;
- this.setState({ load: true });
-
- $.ajax({
- url: '/save',
- dataType: 'json',
- type: 'POST',
- data: {
- net: JSON.stringify(netData),
- net_name: this.state.net_name,
- user_id: this.getUserId(),
- nextLayerId: this.state.nextLayerId
- },
- success : function (response) {
- if (response.result == 'success') {
- var url = 'http://' + window.location.host + ':80/load?id=' + response.id;
- this.modalHeader = 'Your model url is';
- this.modalContent = ({url});
- this.openModal();
- }
- else if (response.result == 'error') {
- this.addError(response.error);
- }
- this.setState({ load: false });
- }.bind(this),
- error() {
- this.setState({ load: false });
- }
- });
- }
- componentWillMount(){
- var url = window.location.href.split('#');
- var urlParams = {};
- let randomId = url[1];
- url = url[0];
- url.replace(
- new RegExp("([^?=&]+)(=([^&]*))?", "g"),
- function($0, $1, $2, $3) {
- urlParams[$1] = $3;
- }
- );
-
- // setting up socket connection
-
- let socket = this.createSocket('ws://' + window.location.host + '/ws/connect/?id=' + urlParams['id']);
- this.setState({ socket: socket });
- this.waitForConnection (this.onSocketConnect, 1000);
-
- if ('id' in urlParams){
- if ('version' in urlParams) {
- this.loadDb(urlParams['id'], urlParams['version']);
- this.setState({
- isShared: true,
- isForked: true,
- networkId: parseInt(urlParams['id']),
- randomId: randomId,
- highlightColor: this.getRandomColor()
- });
- }
- else {
- this.loadDb(urlParams['id']);
- this.setState({
- isShared: true,
- networkId: parseInt(urlParams['id']),
- randomId: randomId,
- highlightColor: this.getRandomColor()
- });
- }
- }
- }
- loadDb(id, version_id = null) {
- // in case model is getting loaded from history disable sending updates
- // Note: this needs to be improved when handling conflict resolution to avoid
- // inconsistent states of model
- let nextLayerId = this.state.nextLayerId;
-
- this.setState({ load: true });
-
- this.dismissAllErrors();
- $.ajax({
- url: '/load',
- dataType: 'json',
- type: 'POST',
- data: {
- proto_id: id,
- version_id: version_id
- },
- success: function (response) {
- if (response.result === 'success'){
- // while loading a model ensure paramete intialisation
- // for UI show/hide is not executed, it leads to inconsistent
- // data which cannot be used further
- nextLayerId = response.next_layer_id;
- this.initialiseImportedNet(response.net,response.net_name);
- if (Object.keys(response.net).length){
- this.calculateParameters(response.net);
- }
- }
- else if (response.result === 'error') {
- this.addError(response.error);
- }
- this.setState({
- load: false,
- isShared: true,
- nextLayerId: parseInt(nextLayerId)
- });
- }.bind(this),
- error() {
- this.setState({ load: false });
- }
- });
- }
- infoModal() {
- this.modalHeader = "About"
- this.modalContent = `Fabrik is an online collaborative platform to build and visualize deep\
- learning models via a simple drag-and-drop interface. It allows researchers to\
- collaboratively develop and debug models using a web GUI that supports importing,\
- editing and exporting networks written in widely popular frameworks like Caffe,\
- Keras, and TensorFlow.`;
- this.openModal();
- }
- faqModal() {
- this.modalHeader = "Help/FAQ"
- this.modalContent = (
Q: What is Fabrik?
- A: Fabrik is an online platform, created by CloudCV, allowing AI researchers and enthusiasts to
- build and visualize deep learning models.
- Q: What is the model zoo?
- A: It is a collection of pre-built models that you can use.
- To access it, simply click the folder icon in the left corner of the toolbox and pick a model.
- You can find the available models
- here.
-
- Q: What do the Train/Test buttons mean?
- A: They are two different modes of your model:
- Train and Test - respectively for training your model with data and testing how and if it works.
- Q: What does the import fuction do?
- A: It allows you to import your previously created models in Caffe (.protoxt files),
- Keras (.json files) and TensorFlow (.pbtxt files)
- Q: What does the export function do?
- A: You can use it to download models from Fabrik. You can train and test them directly on your computer,
- using Caffe,
- Keras
- and TensorFlow.
- Q: How can I contribute to Fabrik?
- A: Please see the instructions listed
- here
-
-
- If you have anymore questions, please visit Fabrik's Github page available
- here for more information.
-
);
- this.openModal();
- }
- toggleSidebar() {
- $('#sidebar').toggleClass('visible');
- $('.sidebar-button').toggleClass('close');
- }
- zooModal() {
- this.modalHeader = null;
- this.modalContent = ;
- this.openModal();
- }
- setModelFramework(e) {
- const el = e.target;
- const modelFramework = el.dataset.framework;
- this.setState({modelFramework});
- $('.import-textbox-tab.selected').removeClass('selected');
- $(el).addClass('selected');
- }
- setModelFrameworkUrl(e) {
- const el = e.target;
- const modelFramework = el.dataset.framework;
- this.setState({modelFramework});
- $('.url-import-modal-tab.selected').removeClass('selected');
- $(el).addClass('selected');
- }
- setModelConfig(e) {
- const modelConfig = e.target.value;
- this.setState({modelConfig});
- }
- setModelUrl(url) {
- this.setState({ modelUrl: url});
- }
- textboxModal() {
- this.modalHeader = null;
- this.modalContent = ;
- this.openModal();
- }
- urlModal() {
- this.modalHeader = null;
- this.modalContent = ;
- this.openModal();
- }
- updateHistoryModal() {
- $.ajax({
- url: '/model_history',
- dataType: 'json',
- type: 'POST',
- data: {
- net_id: this.state.networkId
- },
- success : function (response) {
- if (response.result == 'success') {
- this.modalHeader = 'Model update history';
- this.modalContent = ;
- this.openModal();
- }
- else if (response.result == 'error') {
- this.addError(response.error);
- }
- this.setState({ load: false });
- }.bind(this),
- error() {
- this.setState({ load: false });
- }
- });
- }
- handleClick(event) {
- event.preventDefault();
- this.clickEvent = true;
-
- const net = this.state.net;
- // extracting layerId from Pane id which is in form LayerName_Button
- const id = event.target.id.split('_')[0];
- const prevLayerId = 'l' + (this.state.nextLayerId - 1);
- const prev = net[prevLayerId];
- const next = data[id];
- const zoom = instance.getZoom();
- const layer = {};
- let phase = this.state.selectedPhase;
-
- if (this.state.nextLayerId>0 //makes sure that there are other layers
- && data[prev.info.type].endpoint.src == "Bottom" //makes sure that the source has a bottom
- && next.endpoint.trg == "Top") { //makes sure that the target has a top
- layer.connection = { input: [], output: [] };
- layer.info = {
- type: id.toString(),
- phase,
- class: ''
- }
- layer.params = {
- 'endPoint' : [next['endpoint'], false] //This key is endpoint in data.js, but endPoint in everywhere else.
- }
- Object.keys(next.params).forEach(j => {
- layer.params[j] = [next.params[j].value, false]; //copys all params from data.js
- });
- layer.props = JSON.parse(JSON.stringify(next.props)) //copys all props rom data.js
- layer.state = {
- top: `${(parseInt(prev.state.top.split('px')[0])/zoom + 80)}px`, // This makes the new layer is exactly 80px under the previous one.
- left: `${(parseInt(prev.state.left.split('px')[0])/zoom)}px`, // This aligns the new layer with the previous one.
- class: ''
- }
- layer.props.name = `${next.name}${this.state.nextLayerId}`;
- prev.connection.output.push(`l${this.state.nextLayerId}`);
- layer.connection.input.push(`l${this.state.nextLayerId-1}`);
- this.addNewLayer(layer, prevLayerId);
- }
-
- else if (Object.keys(net).length == 0) { // if there are no layers
- layer.connection = { input: [], output: [] };
- layer.info = {
- type: id.toString(),
- phase,
- class: ''
- }
- layer.params = {
- 'endPoint' : [next['endpoint'], false] //This key is endpoint in data.js, but endPoint in everywhere else.
- }
- Object.keys(next.params).forEach(j => {
- layer.params[j] = [next.params[j].value, false]; //copys all params from data.js
- });
- layer.props = JSON.parse(JSON.stringify(next.props)) //copys all props from data.js
- const height = Math.round(0.05*window.innerHeight, 0); // 5% of screen height, rounded to zero decimals
- const width = Math.round(0.35*window.innerWidth, 0); // 35% of screen width, rounded to zero decimals
- var top = height + Math.ceil(81-height);
- var left = width;
- layer.state = {
- top: `${top}px`,
- left: `${left}px`,
- class: ''
- }
- layer.props.name = `${next.name}${this.state.nextLayerId}`;
- this.addNewLayer(layer);
- }
- }
- render() {
- let loader = null;
- if (this.state.load) {
- loader = (