-
Notifications
You must be signed in to change notification settings - Fork 8
completed lstm_cell #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/lstm_cell.js
Outdated
| * @param {MLLstmCellOptions} options | ||
| * return {Tensor} | ||
| */ | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this blank line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
src/lstm_cell.js
Outdated
| validateLstmCellParams(...arguments); | ||
| const zero = new Scalar(0); | ||
| const inputSize = input.shape[1]; | ||
| const starts = layout === 'iofg' ? {i: 0, o: hiddenSize, f: 2* hiddenSize, g: 3*hiddenSize} : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const starts = layout === 'iofg' ? {i: 0, o: hiddenSize, f: 2* hiddenSize, g: 3*hiddenSize} : | |
| const starts = layout === 'iofg' ? {i: 0, o: hiddenSize, f: 2 * hiddenSize, g: 3 * hiddenSize} : | |
| {i: 0, f: hiddenSize, g: 2 * hiddenSize, o: 3 * hiddenSize}; |
test/lstm_cell_test.js
Outdated
| import * as utils from './utils.js'; | ||
|
|
||
| describe('test lstmCell', function() { | ||
| it.only('lstmCell lstmCell activations=[relu, relu, relu]', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use it() method.
| const hiddenSize = 2; | ||
| const input = new Tensor([batchSize, inputSize], [1, 2, 2, 1]); | ||
| const weight = new Tensor([4 * hiddenSize, inputSize], | ||
| new Float32Array([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer keep 2 space indentations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer keep 2 space indentations.
👍 Yeah, although I much prefer 4-space indents over 2-space indents to more clearly/accurately/quickly see the overall hierarchy of blocks, even more important is consistency within a codebase, and since the rest of the files are 2-space, then I'd do so here too (a mix of both 4-space and 2-space makes it harder to follow the levels too :'-( ).
There are lots of possible ways to do it, but picking one and sticking with it is better than switching between 3 different kinds of indentation. e.g.
Linear flow (uses more vertical space, but it's highly scannable for the eye to quickly locate code, efficient to glean overall block structure, consistently symmetric in constructs, and easily diffable)
const hiddenState = new Tensor( // ->
[batchSize, hiddenSize], // 0
new Float32Array(batchSize * hiddenSize).fill(0), // 1
); // <-
const cellState = new Tensor( // ->
[batchSize, hiddenSize], // 0
new Float32Array(batchSize * hiddenSize).fill(0), // 1
); // <-
const activations = [ // ->
relu, // 0
relu, // 1
relu, // 2
]; // <-
const outputs = lstmCell(
input,
weight,
recurrentWeight,
hiddenState,
cellState,
hiddenSize,
{bias, recurrentBias, peepholeWeight, activations}
);
Compact zig-zag ragged wrap with variable indent for nested lines (slower to scan and spot identifiers, and terrible for diffing, but shaves vertical space):
const hiddenState = new Tensor([batchSize, hiddenSize],
new Float32Array(batchSize * hiddenSize).fill(0));
const cellState = new Tensor([batchSize, hiddenSize],
new Float32Array(batchSize * hiddenSize).fill(0));
const activations = [relu, relu, relu];
const outputs = lstmCell(input, weight, recurrentWeight, hiddenState, cellState, hiddenSize,
{bias, recurrentBias, peepholeWeight, activations});
Compact zig-zag ragged wrap with uniform indentation for nested lines (slower to scan, bad for diffing albeit it a little less than #1, and shaves less vertical space):
const hiddenState = new Tensor(
[batchSize, hiddenSize],
new Float32Array(batchSize * hiddenSize).fill(0));
const cellState = new Tensor(
[batchSize, hiddenSize],
new Float32Array(batchSize * hiddenSize).fill(0));
const activations = [
relu, relu, relu];
const outputs = lstmCell(
input, weight, recurrentWeight, hiddenState, cellState, hiddenSize,
{bias, recurrentBias, peepholeWeight, activations});
|
Thanks @mei1127. |
fdwr
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments. Thanks Mei.
| const starts = layout === 'iofg' ? {i: 0, o: hiddenSize, f: 2 * hiddenSize, g: 3 *hiddenSize} : | ||
| {i: 0, f: hiddenSize, g: 2 * hiddenSize, o: 3 * hiddenSize}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be easier for future readers to read if indentation was aligned consistently:
| const starts = layout === 'iofg' ? {i: 0, o: hiddenSize, f: 2 * hiddenSize, g: 3 *hiddenSize} : | |
| {i: 0, f: hiddenSize, g: 2 * hiddenSize, o: 3 * hiddenSize}; | |
| const starts = layout === 'iofg' ? {i: 0, o: hiddenSize, f: 2 * hiddenSize, g: 3 *hiddenSize} : | |
| {i: 0, f: hiddenSize, g: 2 * hiddenSize, o: 3 * hiddenSize}; |
| const hiddenSize = 2; | ||
| const input = new Tensor([batchSize, inputSize], [1, 2, 2, 1]); | ||
| const weight = new Tensor([4 * hiddenSize, inputSize], | ||
| new Float32Array([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer keep 2 space indentations.
👍 Yeah, although I much prefer 4-space indents over 2-space indents to more clearly/accurately/quickly see the overall hierarchy of blocks, even more important is consistency within a codebase, and since the rest of the files are 2-space, then I'd do so here too (a mix of both 4-space and 2-space makes it harder to follow the levels too :'-( ).
There are lots of possible ways to do it, but picking one and sticking with it is better than switching between 3 different kinds of indentation. e.g.
Linear flow (uses more vertical space, but it's highly scannable for the eye to quickly locate code, efficient to glean overall block structure, consistently symmetric in constructs, and easily diffable)
const hiddenState = new Tensor( // ->
[batchSize, hiddenSize], // 0
new Float32Array(batchSize * hiddenSize).fill(0), // 1
); // <-
const cellState = new Tensor( // ->
[batchSize, hiddenSize], // 0
new Float32Array(batchSize * hiddenSize).fill(0), // 1
); // <-
const activations = [ // ->
relu, // 0
relu, // 1
relu, // 2
]; // <-
const outputs = lstmCell(
input,
weight,
recurrentWeight,
hiddenState,
cellState,
hiddenSize,
{bias, recurrentBias, peepholeWeight, activations}
);
Compact zig-zag ragged wrap with variable indent for nested lines (slower to scan and spot identifiers, and terrible for diffing, but shaves vertical space):
const hiddenState = new Tensor([batchSize, hiddenSize],
new Float32Array(batchSize * hiddenSize).fill(0));
const cellState = new Tensor([batchSize, hiddenSize],
new Float32Array(batchSize * hiddenSize).fill(0));
const activations = [relu, relu, relu];
const outputs = lstmCell(input, weight, recurrentWeight, hiddenState, cellState, hiddenSize,
{bias, recurrentBias, peepholeWeight, activations});
Compact zig-zag ragged wrap with uniform indentation for nested lines (slower to scan, bad for diffing albeit it a little less than #1, and shaves less vertical space):
const hiddenState = new Tensor(
[batchSize, hiddenSize],
new Float32Array(batchSize * hiddenSize).fill(0));
const cellState = new Tensor(
[batchSize, hiddenSize],
new Float32Array(batchSize * hiddenSize).fill(0));
const activations = [
relu, relu, relu];
const outputs = lstmCell(
input, weight, recurrentWeight, hiddenState, cellState, hiddenSize,
{bias, recurrentBias, peepholeWeight, activations});
| // output hidden state (ht) | ||
| const ht = mul(o, activation2(ct)); | ||
|
|
||
| return [ht, ct]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Full names are nice, like return [hiddenState, cellState]. Plus you already spell these names hiddenState and cellStates elsewhere below, which would be more consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe hiddenStateNew could be better for understand and differentiate from the previous state?
| throw new Error(`The hiddenState (rank ${hiddenState.rank}) is not a 2-D tensor.`); | ||
| } | ||
| if (hiddenState.shape[0] !== batchSize || hiddenState.shape[1] !== hiddenSize) { | ||
| throw new Error(`The shape of hiddenState |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message is split.
@huningxin @fdwr @shiyi9801 @BruceDai PTAL, thanks!