mirror of
https://github.com/wassname/keras-js.git
synced 2026-09-09 11:25:25 +08:00
style fixes
This commit is contained in:
+17
-17
@@ -8,15 +8,15 @@ const checkShape = (data, shape) => {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tensor class
|
||||
*/
|
||||
* Tensor class
|
||||
*/
|
||||
export default class Tensor {
|
||||
/**
|
||||
* Creates a tensor
|
||||
* @param {(TypedArray|Array)} data
|
||||
* @param {Array} shape
|
||||
* @param {Object} [options]
|
||||
*/
|
||||
* Creates a tensor
|
||||
* @param {(TypedArray|Array)} data
|
||||
* @param {Array} shape
|
||||
* @param {Object} [options]
|
||||
*/
|
||||
constructor (data, shape, options = {}) {
|
||||
this._type = options.type || Float32Array
|
||||
|
||||
@@ -43,10 +43,10 @@ export default class Tensor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create weblas pipeline tensor in GPU memory
|
||||
* 2-D only
|
||||
* see https://github.com/waylonflinn/weblas/wiki/Pipeline
|
||||
*/
|
||||
* Create weblas pipeline tensor in GPU memory
|
||||
* 2-D only
|
||||
* see https://github.com/waylonflinn/weblas/wiki/Pipeline
|
||||
*/
|
||||
createWeblasTensor = () => {
|
||||
if (this.tensor.shape.length === 1) {
|
||||
const shape = [1, this.tensor.shape[0]]
|
||||
@@ -58,8 +58,8 @@ export default class Tensor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers weblas pipeline tensor from GPU memory
|
||||
*/
|
||||
* Transfers weblas pipeline tensor from GPU memory
|
||||
*/
|
||||
transferWeblasTensor = () => {
|
||||
if (this.weblasTensor) {
|
||||
const shape = this.weblasTensor.shape
|
||||
@@ -69,8 +69,8 @@ export default class Tensor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete weblas pipeline tensor
|
||||
*/
|
||||
* Delete weblas pipeline tensor
|
||||
*/
|
||||
deleteWeblasTensor = () => {
|
||||
if (this.weblasTensor) {
|
||||
this.weblasTensor.delete()
|
||||
@@ -79,8 +79,8 @@ export default class Tensor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces data in the underlying ndarray.
|
||||
*/
|
||||
* Replaces data in the underlying ndarray.
|
||||
*/
|
||||
replaceTensorData = data => {
|
||||
if (data && data.length && data instanceof this._type) {
|
||||
this.tensor.data = data
|
||||
|
||||
+34
-34
@@ -3,10 +3,10 @@ import cwise from 'cwise'
|
||||
import Tensor from './Tensor'
|
||||
|
||||
/**
|
||||
* Softmax activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* Softmax activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
export function softmax (x) {
|
||||
if (x.tensor.shape.length === 1) {
|
||||
ops.expeq(x.tensor)
|
||||
@@ -32,10 +32,10 @@ const _softplus = cwise({
|
||||
})
|
||||
|
||||
/**
|
||||
* Softplus activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* Softplus activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
export function softplus (x) {
|
||||
_softplus(x.tensor)
|
||||
return this
|
||||
@@ -49,22 +49,22 @@ const _softsign = cwise({
|
||||
})
|
||||
|
||||
/**
|
||||
* Softsign activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* Softsign activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
export function softsign (x) {
|
||||
_softsign(x.tensor)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* ReLU activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @param {Number} alpha
|
||||
* @param {Number} maxValue
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* ReLU activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @param {Number} alpha
|
||||
* @param {Number} maxValue
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
export function relu (x, opts = {}) {
|
||||
const { alpha = 0, maxValue = null } = opts
|
||||
let neg
|
||||
@@ -91,10 +91,10 @@ const _tanh = cwise({
|
||||
})
|
||||
|
||||
/**
|
||||
* Tanh activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* Tanh activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
export function tanh (x) {
|
||||
_tanh(x.tensor)
|
||||
return this
|
||||
@@ -108,10 +108,10 @@ const _sigmoid = cwise({
|
||||
})
|
||||
|
||||
/**
|
||||
* Sigmoid activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* Sigmoid activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
export function sigmoid (x) {
|
||||
_sigmoid(x.tensor)
|
||||
return this
|
||||
@@ -132,20 +132,20 @@ const _hardSigmoid = cwise({
|
||||
})
|
||||
|
||||
/**
|
||||
* Hard-sigmoid activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* Hard-sigmoid activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
export function hardSigmoid (x) {
|
||||
_hardSigmoid(x.tensor)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* Linear activation function. In-place operation.
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
export function linear (x) {
|
||||
return this
|
||||
}
|
||||
|
||||
+19
-19
@@ -2,13 +2,13 @@ import ndarray from 'ndarray'
|
||||
import squeeze from 'ndarray-squeeze'
|
||||
|
||||
/**
|
||||
* Layer class
|
||||
*/
|
||||
* Layer class
|
||||
*/
|
||||
export default class Layer {
|
||||
/**
|
||||
* Creates a layer
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
* Creates a layer
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
constructor (attrs = {}) {
|
||||
this.name = attrs.name
|
||||
}
|
||||
@@ -20,13 +20,13 @@ export default class Layer {
|
||||
weights = {}
|
||||
|
||||
/**
|
||||
* Method for setting layer weights
|
||||
* We store the weights as both Tensor instances,
|
||||
* as well as weblas pipeline tensors if possible (which are in GPU memory)
|
||||
* see https://github.com/waylonflinn/weblas/wiki/Pipeline
|
||||
*
|
||||
* @param {Tensor[]} weightsArr - array of weights which are instances of Tensor
|
||||
*/
|
||||
* Method for setting layer weights
|
||||
* We store the weights as both Tensor instances,
|
||||
* as well as weblas pipeline tensors if possible (which are in GPU memory)
|
||||
* see https://github.com/waylonflinn/weblas/wiki/Pipeline
|
||||
*
|
||||
* @param {Tensor[]} weightsArr - array of weights which are instances of Tensor
|
||||
*/
|
||||
setWeights = weightsArr => {
|
||||
this.params.forEach((p, i) => {
|
||||
this.weights[p] = weightsArr[i]
|
||||
@@ -34,9 +34,9 @@ export default class Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create weblas pipeline tensor weights
|
||||
* 2-D only
|
||||
*/
|
||||
* Create weblas pipeline tensor weights
|
||||
* 2-D only
|
||||
*/
|
||||
createWeblasWeights = () => {
|
||||
this.weblasWeights = {}
|
||||
|
||||
@@ -52,8 +52,8 @@ export default class Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer weblas pipeline tensor weights
|
||||
*/
|
||||
* Transfer weblas pipeline tensor weights
|
||||
*/
|
||||
transferWeblasWeights = () => {
|
||||
this.params.forEach((p, i) => {
|
||||
if (this.weblasWeights[p]) {
|
||||
@@ -65,8 +65,8 @@ export default class Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete weblas pipeline tensor weights
|
||||
*/
|
||||
* Delete weblas pipeline tensor weights
|
||||
*/
|
||||
deleteWeblasWeights = () => {
|
||||
this.params.forEach((p, i) => {
|
||||
if (this.weblasWeights[p]) {
|
||||
|
||||
@@ -2,13 +2,13 @@ import Layer from '../../engine/Layer'
|
||||
import cwise from 'cwise'
|
||||
|
||||
/**
|
||||
* ELU advanced activation layer class
|
||||
*/
|
||||
* ELU advanced activation layer class
|
||||
*/
|
||||
export default class ELU extends Layer {
|
||||
/**
|
||||
* Creates a ELU activation layer
|
||||
* @param {number} alpha - scale for the negative factor
|
||||
*/
|
||||
* Creates a ELU activation layer
|
||||
* @param {number} alpha - scale for the negative factor
|
||||
*/
|
||||
constructor (alpha = 1.0) {
|
||||
super({})
|
||||
this.alpha = alpha
|
||||
@@ -22,10 +22,10 @@ export default class ELU extends Layer {
|
||||
})
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
this._compute(x.tensor, this.alpha)
|
||||
return x
|
||||
|
||||
@@ -2,23 +2,23 @@ import Layer from '../../engine/Layer'
|
||||
import { relu } from '../../activations'
|
||||
|
||||
/**
|
||||
* LeakyReLU advanced activation layer class
|
||||
*/
|
||||
* LeakyReLU advanced activation layer class
|
||||
*/
|
||||
export default class LeakyReLU extends Layer {
|
||||
/**
|
||||
* Creates a LeakyReLU activation layer
|
||||
* @param {number} alpha - negative slope coefficient
|
||||
*/
|
||||
* Creates a LeakyReLU activation layer
|
||||
* @param {number} alpha - negative slope coefficient
|
||||
*/
|
||||
constructor (alpha = 0.3) {
|
||||
super({})
|
||||
this.alpha = alpha
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
relu(x, { alpha: this.alpha })
|
||||
return x
|
||||
|
||||
@@ -2,24 +2,22 @@ import Layer from '../../engine/Layer'
|
||||
import cwise from 'cwise'
|
||||
|
||||
/**
|
||||
* PReLU advanced activation layer class
|
||||
* reference code:
|
||||
* ```
|
||||
* pos = K.relu(x)
|
||||
* neg = self.alphas * (x - abs(x)) * 0.5
|
||||
* return pos + neg
|
||||
* ```
|
||||
*/
|
||||
* PReLU advanced activation layer class
|
||||
* reference code:
|
||||
* ```
|
||||
* pos = K.relu(x)
|
||||
* neg = self.alphas * (x - abs(x)) * 0.5
|
||||
* return pos + neg
|
||||
* ```
|
||||
*/
|
||||
export default class PReLU extends Layer {
|
||||
/**
|
||||
* Creates a PReLU activation layer
|
||||
*/
|
||||
* Creates a PReLU activation layer
|
||||
*/
|
||||
constructor () {
|
||||
super({})
|
||||
|
||||
/**
|
||||
* Layer weights specification
|
||||
*/
|
||||
// Layer weights specification
|
||||
this.params = ['alphas']
|
||||
}
|
||||
|
||||
@@ -31,10 +29,10 @@ export default class PReLU extends Layer {
|
||||
})
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
this._compute(x.tensor, this.weights.alphas.tensor)
|
||||
return x
|
||||
|
||||
@@ -2,19 +2,17 @@ import Layer from '../../engine/Layer'
|
||||
import cwise from 'cwise'
|
||||
|
||||
/**
|
||||
* ParametricSoftplus advanced activation layer class
|
||||
* alpha * log(1 + exp(beta * X))
|
||||
*/
|
||||
* ParametricSoftplus advanced activation layer class
|
||||
* alpha * log(1 + exp(beta * X))
|
||||
*/
|
||||
export default class ParametricSoftplus extends Layer {
|
||||
/**
|
||||
* Creates a ParametricSoftplus activation layer
|
||||
*/
|
||||
* Creates a ParametricSoftplus activation layer
|
||||
*/
|
||||
constructor () {
|
||||
super({})
|
||||
|
||||
/**
|
||||
* Layer weights specification
|
||||
*/
|
||||
// Layer weights specification
|
||||
this.params = ['alphas', 'betas']
|
||||
}
|
||||
|
||||
@@ -26,10 +24,10 @@ export default class ParametricSoftplus extends Layer {
|
||||
})
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
this._compute(x.tensor, this.weights.alphas.tensor, this.weights.betas.tensor)
|
||||
return x
|
||||
|
||||
@@ -2,19 +2,17 @@ import Layer from '../../engine/Layer'
|
||||
import cwise from 'cwise'
|
||||
|
||||
/**
|
||||
* SReLU advanced activation layer class
|
||||
* S-shaped Rectified Linear Unit
|
||||
*/
|
||||
* SReLU advanced activation layer class
|
||||
* S-shaped Rectified Linear Unit
|
||||
*/
|
||||
export default class SReLU extends Layer {
|
||||
/**
|
||||
* Creates a SReLU activation layer
|
||||
*/
|
||||
* Creates a SReLU activation layer
|
||||
*/
|
||||
constructor () {
|
||||
super({})
|
||||
|
||||
/**
|
||||
* Layer weights specification
|
||||
*/
|
||||
// Layer weights specification
|
||||
this.params = ['t_left', 'a_left', 't_right', 'a_right']
|
||||
}
|
||||
|
||||
@@ -31,10 +29,10 @@ export default class SReLU extends Layer {
|
||||
})
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
this._compute(
|
||||
x.tensor,
|
||||
|
||||
@@ -2,13 +2,13 @@ import Layer from '../../engine/Layer'
|
||||
import cwise from 'cwise'
|
||||
|
||||
/**
|
||||
* ThresholdedReLU advanced activation layer class
|
||||
*/
|
||||
* ThresholdedReLU advanced activation layer class
|
||||
*/
|
||||
export default class ThresholdedReLU extends Layer {
|
||||
/**
|
||||
* Creates a ThresholdedReLU activation layer
|
||||
* @param {number} theta - float >= 0. Threshold location of activation.
|
||||
*/
|
||||
* Creates a ThresholdedReLU activation layer
|
||||
* @param {number} theta - float >= 0. Threshold location of activation.
|
||||
*/
|
||||
constructor (theta = 1.0) {
|
||||
super({})
|
||||
this.theta = theta
|
||||
@@ -22,10 +22,10 @@ export default class ThresholdedReLU extends Layer {
|
||||
})
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
this._compute(x.tensor, this.theta)
|
||||
return x
|
||||
|
||||
@@ -7,16 +7,16 @@ import unpack from 'ndarray-unpack'
|
||||
import flattenDeep from 'lodash/flattenDeep'
|
||||
|
||||
/**
|
||||
* Convolution2D layer class
|
||||
*/
|
||||
* Convolution2D layer class
|
||||
*/
|
||||
export default class Convolution2D extends Layer {
|
||||
/**
|
||||
* Creates a Convolution2D layer
|
||||
* @param {number} nbFilter - Number of convolution filters to use.
|
||||
* @param {number} nbRow - Number of rows in the convolution kernel.
|
||||
* @param {number} nbCol - Number of columns in the convolution kernel.
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
* Creates a Convolution2D layer
|
||||
* @param {number} nbFilter - Number of convolution filters to use.
|
||||
* @param {number} nbRow - Number of rows in the convolution kernel.
|
||||
* @param {number} nbCol - Number of columns in the convolution kernel.
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
constructor (nbFilter, nbRow, nbCol, attrs = {}) {
|
||||
super(attrs)
|
||||
const {
|
||||
@@ -47,19 +47,18 @@ export default class Convolution2D extends Layer {
|
||||
|
||||
this.bias = bias
|
||||
|
||||
/**
|
||||
* Layer weights specification
|
||||
*/
|
||||
// Layer weights specification
|
||||
this.params = this.bias ? ['W', 'b'] : ['W']
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for computing output dimensions based on input dimensions, kernel size, and padding mode
|
||||
* For tensorflow implementation of padding, see:
|
||||
* https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/common_shape_fns.cc
|
||||
* @param {Tensor} x
|
||||
* @returns {number[]} [outputRows, outputCols, outputChannels]
|
||||
*/
|
||||
* Method for computing output dimensions and padding, based on input
|
||||
* dimensions, kernel size, and padding mode.
|
||||
* For tensorflow implementation of padding, see:
|
||||
* https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/common_shape_fns.cc
|
||||
* @param {Tensor} x
|
||||
* @returns {number[]} [outputRows, outputCols, outputChannels]
|
||||
*/
|
||||
_calcOutputShape = x => {
|
||||
const inputRows = x.tensor.shape[0]
|
||||
const inputCols = x.tensor.shape[1]
|
||||
@@ -89,10 +88,10 @@ export default class Convolution2D extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pad input tensor if necessary, for borderMode='same'
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Pad input tensor if necessary, for borderMode='same'
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
_padInput = x => {
|
||||
if (this.borderMode === 'same') {
|
||||
const [inputRows, inputCols, inputChannels] = x.tensor.shape
|
||||
@@ -112,10 +111,10 @@ export default class Convolution2D extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert input image to column matrix
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Convert input image to column matrix
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
_im2col = x => {
|
||||
const [inputRows, inputCols, inputChannels] = x.tensor.shape
|
||||
const nbRow = this.kernelShape[1]
|
||||
@@ -144,10 +143,10 @@ export default class Convolution2D extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert filter weights to row matrix
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Convert filter weights to row matrix
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
_w2row = x => {
|
||||
const inputChannels = x.tensor.shape[2]
|
||||
const [nbFilter, nbRow, nbCol] = this.kernelShape
|
||||
@@ -168,10 +167,10 @@ export default class Convolution2D extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
this._calcOutputShape(x)
|
||||
this._padInput(x)
|
||||
|
||||
@@ -2,23 +2,23 @@ import * as activations from '../../activations'
|
||||
import Layer from '../../engine/Layer'
|
||||
|
||||
/**
|
||||
* Activation layer class
|
||||
*/
|
||||
* Activation layer class
|
||||
*/
|
||||
export default class Activation extends Layer {
|
||||
/**
|
||||
* Creates an Activation layer
|
||||
* @param {string} activation - name of activation function
|
||||
*/
|
||||
* Creates an Activation layer
|
||||
* @param {string} activation - name of activation function
|
||||
*/
|
||||
constructor (activation, attrs = {}) {
|
||||
super({})
|
||||
this.activation = activations[activation]
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
this.activation(x)
|
||||
return x
|
||||
|
||||
+24
-28
@@ -5,14 +5,14 @@ import { gemv } from 'ndarray-blas-level2'
|
||||
import ops from 'ndarray-ops'
|
||||
|
||||
/**
|
||||
* Dense layer class
|
||||
*/
|
||||
* Dense layer class
|
||||
*/
|
||||
export default class Dense extends Layer {
|
||||
/**
|
||||
* Creates a Dense layer
|
||||
* @param {number} outputDim - output dimension size
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
* Creates a Dense layer
|
||||
* @param {number} outputDim - output dimension size
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
constructor (outputDim, attrs = {}) {
|
||||
super(attrs)
|
||||
const {
|
||||
@@ -26,36 +26,32 @@ export default class Dense extends Layer {
|
||||
this.inputDim = inputDim
|
||||
this.bias = bias
|
||||
|
||||
/**
|
||||
* Layer weights specification
|
||||
*/
|
||||
// Layer weights specification
|
||||
this.params = this.bias ? ['W', 'b'] : ['W']
|
||||
|
||||
/**
|
||||
* Input shape specification
|
||||
*/
|
||||
// Input shape specification
|
||||
if (this.inputDim) {
|
||||
this.inputShape = [this.inputDim]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
*
|
||||
* x = W^T * x + b
|
||||
*
|
||||
* weblas notes:
|
||||
* sgemm(M, N, K, alpha, A, B, beta, C), where A, B, C are Float32Array
|
||||
* - alpha * A * B + beta * C
|
||||
* - A has shape M x N
|
||||
* - B has shape N x K
|
||||
* - C has shape M x K
|
||||
* pipeline.sgemm(alpha, A, B, beta, C), where A, B, C are weblas.pipeline.Tensor here
|
||||
* - alpha * A * B^T + beta * C
|
||||
*
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
*
|
||||
* x = W^T * x + b
|
||||
*
|
||||
* weblas notes:
|
||||
* sgemm(M, N, K, alpha, A, B, beta, C), where A, B, C are Float32Array
|
||||
* - alpha * A * B + beta * C
|
||||
* - A has shape M x N
|
||||
* - B has shape N x K
|
||||
* - C has shape M x K
|
||||
* pipeline.sgemm(alpha, A, B, beta, C), where A, B, C are weblas.pipeline.Tensor here
|
||||
* - alpha * A * B^T + beta * C
|
||||
*
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
if (x._useWeblas) {
|
||||
// x is mutable, so create on every call
|
||||
|
||||
+10
-10
@@ -1,24 +1,24 @@
|
||||
import Layer from '../../engine/Layer'
|
||||
|
||||
/**
|
||||
* Dropout layer class
|
||||
* Note that this layer is here for compatibility, it's only applied during training time.
|
||||
*/
|
||||
* Dropout layer class
|
||||
* Note that this layer is here for compatibility, it's only applied during training time.
|
||||
*/
|
||||
export default class Dropout extends Layer {
|
||||
/**
|
||||
* Creates an Dropout layer
|
||||
* @param {number} p - fraction of the input units to drop (between 0 and 1)
|
||||
*/
|
||||
* Creates an Dropout layer
|
||||
* @param {number} p - fraction of the input units to drop (between 0 and 1)
|
||||
*/
|
||||
constructor (p) {
|
||||
super({})
|
||||
this.p = Math.min(Math.max(0, p), 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
return x
|
||||
}
|
||||
|
||||
+10
-10
@@ -4,23 +4,23 @@ import unpack from 'ndarray-unpack'
|
||||
import flattenDeep from 'lodash/flattenDeep'
|
||||
|
||||
/**
|
||||
* Flatten layer class
|
||||
* Turns tensor into 1-d. Note there is no concept of batch size in these layers (single-batch).
|
||||
* We use ndarray-unpack first, as ndarray striding/offsets precludes us from simply using x.tensor.data
|
||||
*/
|
||||
* Flatten layer class
|
||||
* Turns tensor into 1-d. Note there is no concept of batch size in these layers (single-batch).
|
||||
* We use ndarray-unpack first, as ndarray striding/offsets precludes us from simply using x.tensor.data
|
||||
*/
|
||||
export default class Flatten extends Layer {
|
||||
/**
|
||||
* Creates a Flatten layer
|
||||
*/
|
||||
* Creates a Flatten layer
|
||||
*/
|
||||
constructor () {
|
||||
super({})
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
if (x.tensor.shape.length > 1) {
|
||||
const shape = [x.tensor.shape.reduce((a, b) => a * b, 1)]
|
||||
|
||||
+13
-13
@@ -6,15 +6,15 @@ import ops from 'ndarray-ops'
|
||||
import cwise from 'cwise'
|
||||
|
||||
/**
|
||||
* Highway layer class
|
||||
* From Keras docs: Densely connected highway network, a natural extension of LSTMs to feedforward networks.
|
||||
*/
|
||||
* Highway layer class
|
||||
* From Keras docs: Densely connected highway network, a natural extension of LSTMs to feedforward networks.
|
||||
*/
|
||||
export default class Highway extends Layer {
|
||||
/**
|
||||
* Creates a Highway layer
|
||||
* @param {number} outputDim - output dimension size
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
* Creates a Highway layer
|
||||
* @param {number} outputDim - output dimension size
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
constructor (attrs = {}) {
|
||||
super(attrs)
|
||||
const {
|
||||
@@ -28,8 +28,8 @@ export default class Highway extends Layer {
|
||||
this.bias = bias
|
||||
|
||||
/**
|
||||
* Layer weights specification
|
||||
*/
|
||||
* Layer weights specification
|
||||
*/
|
||||
this.params = this.bias ? ['W', 'b', 'W_carry', 'b_carry'] : ['W', 'W_carry']
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ export default class Highway extends Layer {
|
||||
})
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
let y = new Tensor([], [this.weights.W.tensor.shape[1]])
|
||||
if (this.bias) {
|
||||
|
||||
@@ -4,18 +4,18 @@ import { gemv } from 'ndarray-blas-level2'
|
||||
import ops from 'ndarray-ops'
|
||||
|
||||
/**
|
||||
* MaxoutDense layer class
|
||||
* From Keras docs: takes the element-wise maximum of nb_feature Dense(input_dim, output_dim) linear layers
|
||||
* Note that `nb_feature` is implicit in the weights tensors, with shapes:
|
||||
* - W: [nb_feature, input_dim, output_dim]
|
||||
* - b: [nb_feature, output_dim]
|
||||
*/
|
||||
* MaxoutDense layer class
|
||||
* From Keras docs: takes the element-wise maximum of nb_feature Dense(input_dim, output_dim) linear layers
|
||||
* Note that `nb_feature` is implicit in the weights tensors, with shapes:
|
||||
* - W: [nb_feature, input_dim, output_dim]
|
||||
* - b: [nb_feature, output_dim]
|
||||
*/
|
||||
export default class MaxoutDense extends Layer {
|
||||
/**
|
||||
* Creates a MaxoutDense layer
|
||||
* @param {number} outputDim - output dimension size
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
* Creates a MaxoutDense layer
|
||||
* @param {number} outputDim - output dimension size
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
constructor (outputDim, attrs = {}) {
|
||||
super(attrs)
|
||||
const {
|
||||
@@ -26,17 +26,15 @@ export default class MaxoutDense extends Layer {
|
||||
this.inputDim = inputDim
|
||||
this.bias = bias
|
||||
|
||||
/**
|
||||
* Layer weights specification
|
||||
*/
|
||||
// Layer weights specification
|
||||
this.params = this.bias ? ['W', 'b'] : ['W']
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
const nbFeature = this.weights.W.tensor.shape[0]
|
||||
|
||||
|
||||
+13
-13
@@ -8,13 +8,13 @@ import isEqual from 'lodash/isEqual'
|
||||
import isInteger from 'lodash/isInteger'
|
||||
|
||||
/**
|
||||
* Merge layer class
|
||||
*/
|
||||
* Merge layer class
|
||||
*/
|
||||
export default class Merge extends Layer {
|
||||
/**
|
||||
* Creates a Merge layer
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
* Creates a Merge layer
|
||||
* @param {Object} [attrs] - layer attributes
|
||||
*/
|
||||
constructor (attrs = {}) {
|
||||
super(attrs)
|
||||
const {
|
||||
@@ -39,10 +39,10 @@ export default class Merge extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method for validating inputs
|
||||
* @param {Tensor[]} inputs
|
||||
* @returns {boolean} valid
|
||||
*/
|
||||
* Internal method for validating inputs
|
||||
* @param {Tensor[]} inputs
|
||||
* @returns {boolean} valid
|
||||
*/
|
||||
_validateInputs = inputs => {
|
||||
const shapes = inputs.map(x => x.tensor.shape.slice())
|
||||
if (['sum', 'mul', 'ave', 'cos', 'max'].indexOf(this.mode) > -1) {
|
||||
@@ -75,10 +75,10 @@ export default class Merge extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor[]} inputs
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor[]} inputs
|
||||
* @returns {Tensor} `this`
|
||||
*/
|
||||
call = inputs => {
|
||||
const valid = this._validateInputs(inputs)
|
||||
if (!valid) {
|
||||
|
||||
+11
-11
@@ -1,25 +1,25 @@
|
||||
import Layer from '../../engine/Layer'
|
||||
|
||||
/**
|
||||
* Permute layer class
|
||||
* Note there is no concept of batch size in these layers (single-batch), so dim numbers 1 less
|
||||
* i.e., dim 1 in keras corresponds to dim 0 here, etc.
|
||||
*/
|
||||
* Permute layer class
|
||||
* Note there is no concept of batch size in these layers (single-batch), so dim numbers 1 less
|
||||
* i.e., dim 1 in keras corresponds to dim 0 here, etc.
|
||||
*/
|
||||
export default class Permute extends Layer {
|
||||
/**
|
||||
* Creates a Permute layer
|
||||
* @param {number[]} dims
|
||||
*/
|
||||
* Creates a Permute layer
|
||||
* @param {number[]} dims
|
||||
*/
|
||||
constructor (dims) {
|
||||
super({})
|
||||
this.dims = dims.map(dim => dim - 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
if (this.dims.length !== x.tensor.shape.length) {
|
||||
throw new Error(`${this.name} [Permute layer] The specified dims permutation must match the number of dimensions.`)
|
||||
|
||||
@@ -3,25 +3,25 @@ import unsqueeze from 'ndarray-unsqueeze'
|
||||
import tile from 'ndarray-tile'
|
||||
|
||||
/**
|
||||
* RepeatVector layer class
|
||||
* Turns 2D tensors of shape [features] to 3D tensors of shape [n, features].
|
||||
* Note there is no concept of batch size in these layers (single-batch) so we're actually going from 1D to 2D.
|
||||
*/
|
||||
* RepeatVector layer class
|
||||
* Turns 2D tensors of shape [features] to 3D tensors of shape [n, features].
|
||||
* Note there is no concept of batch size in these layers (single-batch) so we're actually going from 1D to 2D.
|
||||
*/
|
||||
export default class RepeatVector extends Layer {
|
||||
/**
|
||||
* Creates a RepeatVector layer
|
||||
* @param {number} n
|
||||
*/
|
||||
* Creates a RepeatVector layer
|
||||
* @param {number} n
|
||||
*/
|
||||
constructor (n) {
|
||||
super({})
|
||||
this.n = n
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
if (x.tensor.shape.length !== 1) {
|
||||
throw new Error(`${this.name} [RepeatVector layer] Only 1D tensor inputs allowed.`)
|
||||
|
||||
+11
-11
@@ -4,25 +4,25 @@ import unpack from 'ndarray-unpack'
|
||||
import flattenDeep from 'lodash/flattenDeep'
|
||||
|
||||
/**
|
||||
* Reshape layer class
|
||||
* Note there is no concept of batch size in these layers (single-batch).
|
||||
* We use ndarray-unpack first, as ndarray striding/offsets precludes us from simply using x.tensor.data
|
||||
*/
|
||||
* Reshape layer class
|
||||
* Note there is no concept of batch size in these layers (single-batch).
|
||||
* We use ndarray-unpack first, as ndarray striding/offsets precludes us from simply using x.tensor.data
|
||||
*/
|
||||
export default class Reshape extends Layer {
|
||||
/**
|
||||
* Creates a Reshape layer
|
||||
* @param {number[]} shape
|
||||
*/
|
||||
* Creates a Reshape layer
|
||||
* @param {number[]} shape
|
||||
*/
|
||||
constructor (shape) {
|
||||
super({})
|
||||
this.shape = shape
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
* Method for layer computational logic
|
||||
* @param {Tensor} x
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call = x => {
|
||||
if (this.shape.reduce((a, b) => a * b, 1) !== x.tensor.size) {
|
||||
throw new Error(`${this.name} [Reshape layer] The total size of new array must be unchanged in reshape layer.`)
|
||||
|
||||
+5
-5
@@ -3,11 +3,11 @@ import flattenDeep from 'lodash/flattenDeep'
|
||||
import isFinite from 'lodash/isFinite'
|
||||
|
||||
/**
|
||||
* Compares an ndarray's data element-wise to dataExpected,
|
||||
* within a certain tolerance. We unpack the ndarray first since
|
||||
* stride/offset prevents us from comparing the array data
|
||||
* element-wise directly.
|
||||
*/
|
||||
* Compares an ndarray's data element-wise to dataExpected,
|
||||
* within a certain tolerance. We unpack the ndarray first since
|
||||
* stride/offset prevents us from comparing the array data
|
||||
* element-wise directly.
|
||||
*/
|
||||
export function approxEquals (ndarrayOut, dataExpected, tol = 1e-5) {
|
||||
const a = flattenDeep(unpack(ndarrayOut))
|
||||
const b = dataExpected
|
||||
|
||||
Reference in New Issue
Block a user