You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -19,7 +19,12 @@ https://ai.danruta.co.uk/webassembly - Performance comparison between JS and Web
19
19
---
20
20
There are two different versions of jsNet: WebAssembly, and JavaScript-only. There are demos included for loading both versions, in nodejs, as well as in the browser. The WebAssembly version is a little more complex to load, due to the NetWASM files which are generated by emscripten, containing the compiled code and the glue code to manage the WASM code. The ```NetWASM.js``` lazy loads the ```NetWASM.wasm``` file with the given path.
21
21
22
-
The API has been kept the same as the JavaScript only version. Every single value has get/set bindings to the WebAssembly variables, meaning that apart from not being able to freely browse the values in dev tools (need to call them, to see them), you should notice no API difference between the two versions.
22
+
The API has been kept the same as the JavaScript only version. Every single value has get/set bindings to the WebAssembly variables, meaning that apart from not being able to freely browse the values in dev tools (need to call them, to see them), you should notice no API difference between the two versions. One thing to note is that when changing primitive WebAssembly array values, eg, setting `net.layers[1].neurons[0].weights[0]` to 1, you need to set the entire, modified weights array, not at an index. For example, you would do this instead:
23
+
```javascript
24
+
constweights=net.layers[1].neurons[0].weights
25
+
weights[0] =1
26
+
net.layers[1].neurons[0].weights= weights
27
+
```
23
28
24
29
Note that you need to serve files via a server (a basic server is an included) to load WebAssembly into a browser.
25
30
@@ -164,11 +169,12 @@ When building a convolutional network, make sure that the number of neurons in t
164
169
### Training
165
170
----
166
171
167
-
The data structure must be an object with key ```input``` having an array of numbers, and key ```expected```or ```output```holding the expected output of the network. For example, the following are both valid inputs for both training and testing.
172
+
The data structure must be an object with key ```input``` having an array of numbers, and key ```expected```holding the expected output of the network. For example, the following is a valid input for training, validation and testing.
168
173
```javascript
169
174
{input: [1,0,0.2], expected: [1, 2]}
170
-
{input: [1,0,0.2], output: [1, 2]}
171
175
```
176
+
***Tip**: You can normalize data using the ```NetUtil.normalize()``` function (see at the bottom)*
177
+
172
178
You train the network by passing a set of data. The network will log to the console the error and epoch number, after each epoch, as well as time elapsed and average epoch duration.
173
179
```javascript
174
180
const {training} =mnist.set(800, 200) // Get the training data from the mnist library, linked above
@@ -187,16 +193,70 @@ By default, this is ```1``` and represents how many times the data passed will b
187
193
net.train(training, {epochs:5}) // This will run through the training data 5 times
188
194
```
189
195
###### Callback
190
-
You can also provide a callback in the options parameter, which will get called after each iteration (Maybe updating a graph?). The callback is passed how many iterations have passed, the error, the milliseconds elapsed and the input data for that iteration.
196
+
You can also provide a callback in the options parameter, which will get called after each iteration (Maybe updating a graph?). The callback is passed how many iterations have passed, the milliseconds elapsed since training started, and the validation error OR the training error with input data for that iteration.
You can turn off the logging by passing log: false in the options parameter.
197
203
```javascript
198
204
net.train(training, {log:false})
199
205
```
206
+
207
+
###### Validation
208
+
You can specify an array of data to use as validation. This must have the same structure as the training/test data. The validation config contains three parts: data, interval, and early stopping (see below). The data is where the data is provided. The interval is an integer, representing how many training iterations pass between validations of the entire validation set. By default, this is set to 1 epoch, aka the length of the given training data set.
209
+
```javascript
210
+
// Validate every 5 training iterations
211
+
net.train(training, {validation: {
212
+
data: [...],
213
+
interval:5
214
+
}})
215
+
// Validate every 3 epochs
216
+
net.train(training, {validation: {
217
+
data: [...],
218
+
interval:training.length*3
219
+
}})
220
+
```
221
+
**Tip**: You can use ```NetUtil.splitData(data)``` to split a large array of data into training, validation, and test arrays, with default or specified ratios. See the NetUtil section at the bottom.
222
+
223
+
###### Early stopping
224
+
When using validation data, you can specify an extra config object, `earlyStopping`, to configure stopping the training early, once a condition has been met, to counter overfitting. By default, this is turned off, but each option has default values, once the type is specified, via the `type` key.
225
+
226
+
| Type | What it does | Available Configurations | Default value |
227
+
|:-------------:| :-----:| :-----:| :---: |
228
+
| threshold | Stops the training the first time the validation error reaches, or goes below the specified threshold. A final backward pass is made, and weights updated, before stopping. | threshold. | 0.01 |
229
+
| patience | This backs up the weights and biases of the network when the validation error reaches a new best low, following which, if the validation error is worse, a certain number of times in a row, it stops the training and reverts the network weights and biases to the backed up values. The number of times in a row to tolerate is configured via the `patience` hyperparameter | patience | 20 |
230
+
| divergence | This backs up the weights and biases of the network when the validation error reaches a new best low, following which, if the validation error is worse, by at least a percent value equal to that specified, it stops the training and reverts the network weights and biases to the backed up values. The percentage is configured via the `percent` hyperparameter. A very jittery validation error is likely to stop the training very early, when using this condition. | percent | 30 |
231
+
232
+
Examples:
233
+
```javascript
234
+
// Threshold - Training stops once the validation error reaches down to at most 0.2
235
+
net.train(training, {validation: {
236
+
data: [...],
237
+
earlyStopping: {
238
+
type:"threshold",
239
+
threshold:0.2
240
+
}
241
+
}})
242
+
// Patience - Training stops once the validation error is worse than the best found, 20 times in a row
243
+
net.train(training, {validation: {
244
+
data: [...],
245
+
earlyStopping: {
246
+
type:"patience",
247
+
patience:10
248
+
}
249
+
}})
250
+
// Divergence - Training stops once the validation error is worse than the best found, by 30%
251
+
net.train(training, {validation: {
252
+
data: [...],
253
+
earlyStopping: {
254
+
type:"divergence",
255
+
percent:30
256
+
}
257
+
}})
258
+
```
259
+
200
260
###### Mini Batch Size
201
261
You can use mini batch SGD training by specifying a mini batch size to use (changing it from the default, 1). You can set it to true, and it will default to how many classifications there are in the training data.
There are two way you can manage your data. The built in way is to use JSON for importing and exporting. If you provide my IMGArrays library (https://github.com/DanRuta/IMGArrays), you can alternatively use images, which are much quicker and easier to use, when using the browser.
299
+
300
+
To export weights data as JSON:
239
301
```javascript
240
302
constdata=trainedNet.toJSON()
241
303
```
242
304
305
+
See the IMGArrays library documentation for more details, and nodejs instructions, but its integration into jsNet is as follows:
306
+
```javascript
307
+
constcanvas=trainedNet.toIMG(IMGArrays, opts)
308
+
IMGArrays.downloadImage(canvas)
309
+
```
310
+
243
311
### Importing
244
312
---
245
-
Only the weights are exported. You still need to build the net with the same structure and configs, eg activation function.
313
+
Only the weights are exported. You still need to build the net with the same structure and configs, eg activation function. Again, data can be imported as either JSON or an image, when using IMGArrays, like above.
314
+
315
+
When using json:
246
316
```javascript
247
317
constfreshNetwork=newNetwork(...)
248
318
freshNetwork.fromJSON(data)
249
319
```
250
320
If using exported data from before version 2.0.0, just do a find-replace of "neurons" -> "weights" on the exported data and it will work with the new version.
Once the network has been trained, tested and imported into your page, you can use it via the ```forward``` function.
@@ -275,7 +361,7 @@ const net = new Network({
275
361
l2:undefined,
276
362
l1:undefined,
277
363
layers: [ /* 3 FCLayers */ ]
278
-
updateFn:"vanillaupdatefn",
364
+
updateFn:"vanillasgd",
279
365
weightsConfig: {
280
366
distribution:"xavieruniform"
281
367
}
@@ -289,7 +375,7 @@ You can check the framework version via Network.version (static).
289
375
| Attribute | What it does | Available Configurations | Default value |
290
376
|:-------------:| :-----:| :-----:| :---: |
291
377
| learningRate | The speed at which the net will learn. | Any number | 0.2 (see below for exceptions) |
292
-
| cost | Cost function to use when printing out the net error | crossEntropy, meanSquaredError | meansquarederror |
378
+
| cost | Cost function to use when printing out the net error | crossEntropy, meanSquaredError, rootMeanSquaredError| meansquarederror |
293
379
| channels | Specifies the number of channels in the input data. EG, 3 for RGB images. Used by convolutional networks. | Any number | undefined |
294
380
| conv | (See ConvLayer) An object where the optional keys filterSize, zeroPadding and stride set values for all Conv layers to default to | Object | {} |
295
381
| pool | (See PoolLayer) An object where the optional keys size and stride set values for all Pool layers to default to | Object | {} |
@@ -327,9 +413,10 @@ Learning rate is 0.2 by default, except when using the following configurations:
327
413
### Weight update functions
328
414
| Attribute | What it does | Available Configurations | Default value |
329
415
|:-------------:| :-----:| :-----:| :---: |
330
-
| updateFn | The function used for updating the weights/bias. The vanillaupdatefn option just sets the network to update the weights without any changes to learning rate. |vanillaupdatefn, gain, adagrad, RMSProp, adam , adadelta| vanillaupdatefn|
416
+
| updateFn | The function used for updating the weights/bias. The vanillasgd option just sets the network to update the weights without any changes to learning rate. |vanillasgd, gain, adagrad, RMSProp, adam , adadelta, momentum | vanillasgd|
331
417
| rmsDecay | The decay rate for RMSProp, when used | Any number | 0.99 |
332
418
| rho | Momentum for Adadelta, when used | Any number | 0.95 |
419
+
| momentum | Momentum for the (sgd) momentum update function. | Any number | 0.9 |
333
420
334
421
##### Examples
335
422
```javascript
@@ -543,6 +630,45 @@ net = new Network({
543
630
learningRate:0.05
544
631
})
545
632
```
633
+
### NetUtil
634
+
There is a NetUtil class included, containing some potentially useful functions.
635
+
636
+
### shuffle(data)
637
+
_array_**data** - The data array to shuffle
638
+
639
+
This randomly shuffles an array _in place_ (aka, data passed by reference, the parameter passed will be changed).
0 commit comments