1 parent
c4269bbd3a
commit
c83fab32a9
999 files changed
-318037
No files matched your search
Generated
Vendored
-97
@@ -1,97 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { TensorContainer } from '@tensorflow/tfjs-core';
|
||||
import { Dataset } from '../dataset';
|
||||
import { DataSource } from '../datasource';
|
||||
import { LazyIterator } from '../iterators/lazy_iterator';
|
||||
import { CSVConfig } from '../types';
|
||||
import { TextLineDataset } from './text_line_dataset';
|
||||
/**
|
||||
* Represents a potentially large collection of delimited text records.
|
||||
*
|
||||
* The produced `TensorContainer`s each contain one key-value pair for
|
||||
* every column of the table. When a field is empty in the incoming data, the
|
||||
* resulting value is `undefined`, or throw error if it is required. Values
|
||||
* that can be parsed as numbers are emitted as type `number`, other values
|
||||
* are parsed as `string`.
|
||||
*
|
||||
* The results are not batched.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes', namespace: 'data'}
|
||||
*/
|
||||
export declare class CSVDataset extends Dataset<TensorContainer> {
|
||||
protected readonly input: DataSource;
|
||||
base: TextLineDataset;
|
||||
private hasHeader;
|
||||
private fullColumnNames;
|
||||
private columnNamesValidated;
|
||||
private columnConfigs;
|
||||
private configuredColumnsOnly;
|
||||
private delimiter;
|
||||
private delimWhitespace;
|
||||
/**
|
||||
* Returns column names of the csv dataset. If `configuredColumnsOnly` is
|
||||
* true, return column names in `columnConfigs`. If `configuredColumnsOnly` is
|
||||
* false and `columnNames` is provided, `columnNames`. If
|
||||
* `configuredColumnsOnly` is false and `columnNames` is not provided, return
|
||||
* all column names parsed from the csv file. For example usage please go to
|
||||
* `tf.data.csv`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
columnNames(): Promise<string[]>;
|
||||
private setColumnNames;
|
||||
private maybeReadHeaderLine;
|
||||
/**
|
||||
* Create a `CSVDataset`.
|
||||
*
|
||||
* @param input A `DataSource` providing a chunked, UTF8-encoded byte stream.
|
||||
* @param csvConfig (Optional) A CSVConfig object that contains configurations
|
||||
* of reading and decoding from CSV file(s).
|
||||
*
|
||||
* hasHeader: (Optional) A boolean value that indicates whether the first
|
||||
* row of provided CSV file is a header line with column names, and should
|
||||
* not be included in the data. Defaults to `true`.
|
||||
*
|
||||
* columnNames: (Optional) A list of strings that corresponds to
|
||||
* the CSV column names, in order. If provided, it ignores the column
|
||||
* names inferred from the header row. If not provided, infers the column
|
||||
* names from the first row of the records. If hasHeader is false and
|
||||
* columnNames is not provided, this method throws an error.
|
||||
*
|
||||
* columnConfigs: (Optional) A dictionary whose key is column names, value
|
||||
* is an object stating if this column is required, column's data type,
|
||||
* default value, and if this column is label. If provided, keys must
|
||||
* correspond to names provided in columnNames or inferred from the file
|
||||
* header lines. If isLabel is true any column, returns an array of two
|
||||
* items: the first item is a dict of features key/value pairs, the second
|
||||
* item is a dict of labels key/value pairs. If no feature is marked as
|
||||
* label, returns a dict of features only.
|
||||
*
|
||||
* configuredColumnsOnly (Optional) If true, only columns provided in
|
||||
* columnConfigs will be parsed and provided during iteration.
|
||||
*
|
||||
* delimiter (Optional) The string used to parse each line of the input
|
||||
* file. Defaults to `,`.
|
||||
*/
|
||||
constructor(input: DataSource, csvConfig?: CSVConfig);
|
||||
iterator(): Promise<LazyIterator<TensorContainer>>;
|
||||
makeDataElement(line: string): TensorContainer;
|
||||
private getBoolean;
|
||||
private parseRow;
|
||||
}
|
||||
Generated
Vendored
-379
@@ -1,379 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { util } from '@tensorflow/tfjs-core';
|
||||
import { Dataset } from '../dataset';
|
||||
import { TextLineDataset } from './text_line_dataset';
|
||||
const CODE_QUOTE = '"';
|
||||
const STATE_OUT = Symbol('out');
|
||||
const STATE_FIELD = Symbol('field');
|
||||
const STATE_QUOTE = Symbol('quote');
|
||||
const STATE_QUOTE_AFTER_QUOTE = Symbol('quoteafterquote');
|
||||
const STATE_WITHIN_QUOTE_IN_QUOTE = Symbol('quoteinquote');
|
||||
/**
|
||||
* Represents a potentially large collection of delimited text records.
|
||||
*
|
||||
* The produced `TensorContainer`s each contain one key-value pair for
|
||||
* every column of the table. When a field is empty in the incoming data, the
|
||||
* resulting value is `undefined`, or throw error if it is required. Values
|
||||
* that can be parsed as numbers are emitted as type `number`, other values
|
||||
* are parsed as `string`.
|
||||
*
|
||||
* The results are not batched.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes', namespace: 'data'}
|
||||
*/
|
||||
export class CSVDataset extends Dataset {
|
||||
/**
|
||||
* Create a `CSVDataset`.
|
||||
*
|
||||
* @param input A `DataSource` providing a chunked, UTF8-encoded byte stream.
|
||||
* @param csvConfig (Optional) A CSVConfig object that contains configurations
|
||||
* of reading and decoding from CSV file(s).
|
||||
*
|
||||
* hasHeader: (Optional) A boolean value that indicates whether the first
|
||||
* row of provided CSV file is a header line with column names, and should
|
||||
* not be included in the data. Defaults to `true`.
|
||||
*
|
||||
* columnNames: (Optional) A list of strings that corresponds to
|
||||
* the CSV column names, in order. If provided, it ignores the column
|
||||
* names inferred from the header row. If not provided, infers the column
|
||||
* names from the first row of the records. If hasHeader is false and
|
||||
* columnNames is not provided, this method throws an error.
|
||||
*
|
||||
* columnConfigs: (Optional) A dictionary whose key is column names, value
|
||||
* is an object stating if this column is required, column's data type,
|
||||
* default value, and if this column is label. If provided, keys must
|
||||
* correspond to names provided in columnNames or inferred from the file
|
||||
* header lines. If isLabel is true any column, returns an array of two
|
||||
* items: the first item is a dict of features key/value pairs, the second
|
||||
* item is a dict of labels key/value pairs. If no feature is marked as
|
||||
* label, returns a dict of features only.
|
||||
*
|
||||
* configuredColumnsOnly (Optional) If true, only columns provided in
|
||||
* columnConfigs will be parsed and provided during iteration.
|
||||
*
|
||||
* delimiter (Optional) The string used to parse each line of the input
|
||||
* file. Defaults to `,`.
|
||||
*/
|
||||
constructor(input, csvConfig) {
|
||||
super();
|
||||
this.input = input;
|
||||
this.hasHeader = true;
|
||||
this.fullColumnNames = null;
|
||||
this.columnNamesValidated = false;
|
||||
this.columnConfigs = null;
|
||||
this.configuredColumnsOnly = false;
|
||||
this.delimiter = ',';
|
||||
this.delimWhitespace = false;
|
||||
this.base = new TextLineDataset(input);
|
||||
if (!csvConfig) {
|
||||
csvConfig = {};
|
||||
}
|
||||
this.hasHeader = csvConfig.hasHeader === false ? false : true;
|
||||
this.fullColumnNames = csvConfig.columnNames;
|
||||
this.columnConfigs = csvConfig.columnConfigs;
|
||||
this.configuredColumnsOnly = csvConfig.configuredColumnsOnly;
|
||||
if (csvConfig.delimWhitespace) {
|
||||
util.assert(csvConfig.delimiter == null, () => 'Delimiter should not be provided when delimWhitespace is true.');
|
||||
this.delimWhitespace = true;
|
||||
this.delimiter = ' ';
|
||||
}
|
||||
else {
|
||||
this.delimiter = csvConfig.delimiter ? csvConfig.delimiter : ',';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns column names of the csv dataset. If `configuredColumnsOnly` is
|
||||
* true, return column names in `columnConfigs`. If `configuredColumnsOnly` is
|
||||
* false and `columnNames` is provided, `columnNames`. If
|
||||
* `configuredColumnsOnly` is false and `columnNames` is not provided, return
|
||||
* all column names parsed from the csv file. For example usage please go to
|
||||
* `tf.data.csv`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
async columnNames() {
|
||||
if (!this.columnNamesValidated) {
|
||||
await this.setColumnNames();
|
||||
}
|
||||
return this.configuredColumnsOnly ? Object.keys(this.columnConfigs) :
|
||||
this.fullColumnNames;
|
||||
}
|
||||
/* 1) If `columnNames` is provided as string[], use this string[] as output
|
||||
* keys in corresponding order. The length must match the number of inferred
|
||||
* columns if `hasHeader` is true .
|
||||
* 2) If `columnNames` is not provided, parse header line as `columnNames` if
|
||||
* hasHeader is true. If `hasHeader` is false, throw an error.
|
||||
* 3) If `columnConfigs` is provided, all the keys in `columnConfigs` must
|
||||
* exist in parsed `columnNames`.
|
||||
*/
|
||||
async setColumnNames() {
|
||||
const columnNamesFromFile = await this.maybeReadHeaderLine();
|
||||
if (!this.fullColumnNames && !columnNamesFromFile) {
|
||||
// Throw an error if columnNames is not provided and no header line.
|
||||
throw new Error('Column names must be provided if there is no header line.');
|
||||
}
|
||||
else if (this.fullColumnNames && columnNamesFromFile) {
|
||||
// Check provided columnNames match header line.
|
||||
util.assert(columnNamesFromFile.length === this.fullColumnNames.length, () => 'The length of provided columnNames (' +
|
||||
this.fullColumnNames.length.toString() +
|
||||
') does not match the length of the header line read from ' +
|
||||
'file (' + columnNamesFromFile.length.toString() + ').');
|
||||
}
|
||||
if (!this.fullColumnNames) {
|
||||
this.fullColumnNames = columnNamesFromFile;
|
||||
}
|
||||
// Check if there are duplicate column names.
|
||||
const counts = this.fullColumnNames.reduce((countAcc, name) => {
|
||||
countAcc[name] = (countAcc[name] + 1) || 1;
|
||||
return countAcc;
|
||||
}, {});
|
||||
const duplicateNames = Object.keys(counts).filter((name) => (counts[name] > 1));
|
||||
util.assert(duplicateNames.length === 0, () => 'Duplicate column names found: ' + duplicateNames.toString());
|
||||
// Check if keys in columnConfigs match columnNames.
|
||||
if (this.columnConfigs) {
|
||||
for (const key of Object.keys(this.columnConfigs)) {
|
||||
const index = this.fullColumnNames.indexOf(key);
|
||||
if (index === -1) {
|
||||
throw new Error('The key "' + key +
|
||||
'" provided in columnConfigs does not match any of the column ' +
|
||||
'names (' + this.fullColumnNames.toString() + ').');
|
||||
}
|
||||
}
|
||||
}
|
||||
this.columnNamesValidated = true;
|
||||
}
|
||||
async maybeReadHeaderLine() {
|
||||
if (this.hasHeader) {
|
||||
const iter = await this.base.iterator();
|
||||
const firstElement = await iter.next();
|
||||
if (firstElement.done) {
|
||||
throw new Error('No data was found for CSV parsing.');
|
||||
}
|
||||
const firstLine = firstElement.value;
|
||||
const headers = this.parseRow(firstLine, false);
|
||||
return headers;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async iterator() {
|
||||
if (!this.columnNamesValidated) {
|
||||
await this.setColumnNames();
|
||||
}
|
||||
let lines = await this.base.iterator();
|
||||
if (this.hasHeader) {
|
||||
// We previously read the first line to get the columnNames.
|
||||
// Now that we're providing data, skip it.
|
||||
lines = lines.skip(1);
|
||||
}
|
||||
return lines.map(x => this.makeDataElement(x));
|
||||
}
|
||||
makeDataElement(line) {
|
||||
const values = this.parseRow(line);
|
||||
const features = {};
|
||||
const labels = {};
|
||||
for (let i = 0; i < this.fullColumnNames.length; i++) {
|
||||
const key = this.fullColumnNames[i];
|
||||
const config = this.columnConfigs ? this.columnConfigs[key] : null;
|
||||
if (this.configuredColumnsOnly && !config) {
|
||||
// This column is not selected.
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
const value = values[i];
|
||||
let parsedValue = null;
|
||||
if (value === '') {
|
||||
// If default value is provided, use it. If default value is not
|
||||
// provided, set as undefined.
|
||||
if (config && config.default !== undefined) {
|
||||
parsedValue = config.default;
|
||||
}
|
||||
else if (config && (config.required || config.isLabel)) {
|
||||
throw new Error(`Required column ${key} is empty in this line: ${line}`);
|
||||
}
|
||||
else {
|
||||
parsedValue = undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// A value is present, so parse it based on type
|
||||
const valueAsNum = Number(value);
|
||||
if (isNaN(valueAsNum)) {
|
||||
// The value is a string and this column is declared as boolean
|
||||
// in config, parse it as boolean.
|
||||
if (config && config.dtype === 'bool') {
|
||||
parsedValue = this.getBoolean(value);
|
||||
}
|
||||
else {
|
||||
// Set value as string
|
||||
parsedValue = value;
|
||||
}
|
||||
}
|
||||
else if (!config || !config.dtype) {
|
||||
// If this value is a number and no type config is provided, return
|
||||
// it as number.
|
||||
parsedValue = valueAsNum;
|
||||
}
|
||||
else {
|
||||
// If this value is a number and data type is provided, parse it
|
||||
// according to provided data type.
|
||||
switch (config.dtype) {
|
||||
case 'float32':
|
||||
parsedValue = valueAsNum;
|
||||
break;
|
||||
case 'int32':
|
||||
parsedValue = Math.floor(valueAsNum);
|
||||
break;
|
||||
case 'bool':
|
||||
parsedValue = this.getBoolean(value);
|
||||
break;
|
||||
default:
|
||||
parsedValue = valueAsNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if this column is label.
|
||||
(config && config.isLabel) ? labels[key] = parsedValue :
|
||||
features[key] = parsedValue;
|
||||
}
|
||||
}
|
||||
// If label exists, return an object of features and labels as {xs:features,
|
||||
// ys:labels}, otherwise return features only.
|
||||
if (Object.keys(labels).length === 0) {
|
||||
return features;
|
||||
}
|
||||
else {
|
||||
return { xs: features, ys: labels };
|
||||
}
|
||||
}
|
||||
getBoolean(value) {
|
||||
if (value === '1' || value.toLowerCase() === 'true') {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// adapted from https://beta.observablehq.com/@mbostock/streaming-csv
|
||||
parseRow(line, validateElementCount = true) {
|
||||
const result = [];
|
||||
let readOffset = 0;
|
||||
const readLength = line.length;
|
||||
let currentState = STATE_OUT;
|
||||
// Goes through the line to parse quote.
|
||||
for (let i = 0; i < readLength; i++) {
|
||||
switch (currentState) {
|
||||
// Before enter a new field
|
||||
case STATE_OUT:
|
||||
switch (line.charAt(i)) {
|
||||
// Enter a quoted field
|
||||
case CODE_QUOTE:
|
||||
readOffset = i + 1;
|
||||
currentState = STATE_QUOTE;
|
||||
break;
|
||||
// Read an empty field
|
||||
case this.delimiter:
|
||||
readOffset = i + 1;
|
||||
// If delimiter is white space and configured to collapse
|
||||
// multiple white spaces, ignore this white space.
|
||||
if (this.delimiter === ' ' && this.delimWhitespace) {
|
||||
break;
|
||||
}
|
||||
result.push('');
|
||||
currentState = STATE_OUT;
|
||||
break;
|
||||
// Enter an unquoted field
|
||||
default:
|
||||
currentState = STATE_FIELD;
|
||||
readOffset = i;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// In an unquoted field
|
||||
case STATE_FIELD:
|
||||
switch (line.charAt(i)) {
|
||||
// Exit an unquoted field, add it to result
|
||||
case this.delimiter:
|
||||
result.push(line.substring(readOffset, i));
|
||||
currentState = STATE_OUT;
|
||||
readOffset = i + 1;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
break;
|
||||
// In a quoted field
|
||||
case STATE_QUOTE:
|
||||
switch (line.charAt(i)) {
|
||||
// Read a quote after a quote
|
||||
case CODE_QUOTE:
|
||||
currentState = STATE_QUOTE_AFTER_QUOTE;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
break;
|
||||
// This state means it's right after a second quote in a field
|
||||
case STATE_QUOTE_AFTER_QUOTE:
|
||||
switch (line.charAt(i)) {
|
||||
// Finished a quoted field
|
||||
case this.delimiter:
|
||||
result.push(line.substring(readOffset, i - 1));
|
||||
currentState = STATE_OUT;
|
||||
readOffset = i + 1;
|
||||
break;
|
||||
// Finished a quoted part in a quoted field
|
||||
case CODE_QUOTE:
|
||||
currentState = STATE_QUOTE;
|
||||
break;
|
||||
// In a quoted part in a quoted field
|
||||
default:
|
||||
currentState = STATE_WITHIN_QUOTE_IN_QUOTE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case STATE_WITHIN_QUOTE_IN_QUOTE:
|
||||
switch (line.charAt(i)) {
|
||||
// Exit a quoted part in a quoted field
|
||||
case CODE_QUOTE:
|
||||
currentState = STATE_QUOTE;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
// Adds last item based on if it is quoted.
|
||||
if (currentState === STATE_QUOTE_AFTER_QUOTE) {
|
||||
result.push(line.substring(readOffset, readLength - 1));
|
||||
}
|
||||
else {
|
||||
result.push(line.substring(readOffset));
|
||||
}
|
||||
// Check if each row has the same number of elements as column names.
|
||||
if (validateElementCount && result.length !== this.fullColumnNames.length) {
|
||||
throw new Error(`Invalid row in csv file. Should have ${this.fullColumnNames.length} elements in a row, but got ${result}`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// TODO(soergel): add more basic datasets for parity with tf.data
|
||||
// tf.data.FixedLengthRecordDataset()
|
||||
// tf.data.TFRecordDataset()
|
||||
//# sourceMappingURL=csv_dataset.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"csv_dataset.js","sourceRoot":"","sources":["../../src/datasets/csv_dataset.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"csv_dataset_test.js","sourceRoot":"","sources":["../../src/datasets/csv_dataset_test.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-35
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { Dataset } from '../dataset';
|
||||
import { DataSource } from '../datasource';
|
||||
import { LazyIterator } from '../iterators/lazy_iterator';
|
||||
/**
|
||||
* Represents a potentially large collection of text lines.
|
||||
*
|
||||
* The results are not batched.
|
||||
*/
|
||||
export declare class TextLineDataset extends Dataset<string> {
|
||||
protected readonly input: DataSource;
|
||||
/**
|
||||
* Create a `TextLineDataset`.
|
||||
*
|
||||
* @param input A `DataSource` providing a chunked, UTF8-encoded byte stream.
|
||||
*/
|
||||
constructor(input: DataSource);
|
||||
iterator(): Promise<LazyIterator<string>>;
|
||||
}
|
||||
Generated
Vendored
-47
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { Dataset } from '../dataset';
|
||||
/**
|
||||
* Represents a potentially large collection of text lines.
|
||||
*
|
||||
* The results are not batched.
|
||||
*/
|
||||
export class TextLineDataset extends Dataset {
|
||||
/**
|
||||
* Create a `TextLineDataset`.
|
||||
*
|
||||
* @param input A `DataSource` providing a chunked, UTF8-encoded byte stream.
|
||||
*/
|
||||
constructor(input) {
|
||||
super();
|
||||
this.input = input;
|
||||
}
|
||||
async iterator() {
|
||||
const inputIterator = await this.input.iterator();
|
||||
const utf8Iterator = inputIterator.decodeUTF8();
|
||||
const lineIterator = utf8Iterator.split('\n').map(line => {
|
||||
// Windows/DOS format text file has extra line breaker at the end of line.
|
||||
if (line.endsWith('\r')) {
|
||||
line = line.slice(0, -1);
|
||||
}
|
||||
return line;
|
||||
});
|
||||
return lineIterator;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=text_line_dataset.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"text_line_dataset.js","sourceRoot":"","sources":["../../src/datasets/text_line_dataset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAC;AAInC;;;;GAIG;AACH,MAAM,OAAO,eAAgB,SAAQ,OAAe;IAClD;;;;OAIG;IACH,YAA+B,KAAiB;QAC9C,KAAK,EAAE,CAAC;QADqB,UAAK,GAAL,KAAK,CAAY;IAEhD,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAClD,MAAM,YAAY,GAAG,aAAa,CAAC,UAAU,EAAE,CAAC;QAChD,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YACvD,0EAA0E;YAC1E,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;gBACvB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;aAC1B;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QACH,OAAO,YAAY,CAAC;IACtB,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {Dataset} from '../dataset';\nimport {DataSource} from '../datasource';\nimport {LazyIterator} from '../iterators/lazy_iterator';\n\n/**\n * Represents a potentially large collection of text lines.\n *\n * The results are not batched.\n */\nexport class TextLineDataset extends Dataset<string> {\n /**\n * Create a `TextLineDataset`.\n *\n * @param input A `DataSource` providing a chunked, UTF8-encoded byte stream.\n */\n constructor(protected readonly input: DataSource) {\n super();\n }\n\n async iterator(): Promise<LazyIterator<string>> {\n const inputIterator = await this.input.iterator();\n const utf8Iterator = inputIterator.decodeUTF8();\n const lineIterator = utf8Iterator.split('\\n').map(line => {\n // Windows/DOS format text file has extra line breaker at the end of line.\n if (line.endsWith('\\r')) {\n line = line.slice(0, -1);\n }\n return line;\n });\n return lineIterator;\n }\n}\n"]}
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"text_line_dataset_test.js","sourceRoot":"","sources":["../../src/datasets/text_line_dataset_test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,GAAG,EAAC,MAAM,uBAAuB,CAAC;AAC1C,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAC,eAAe,EAAC,MAAM,qBAAqB,CAAC;AAEpD,MAAM,KAAK,GAAG;;sCAEwB,CAAC;AAEvC,MAAM,qBAAqB,GAAG,gCAAgC,CAAC;AAE/D,MAAM,QAAQ,GACV,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAErE,MAAM,yBAAyB,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IACvD,IAAI,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAEvC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,iEAAiE,EACjE,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE,EAAC,SAAS,EAAE,EAAE,EAAC,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAE3C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,+BAA+B;YAC/B,2CAA2C;YAC3C,uCAAuC;SACxC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEN,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,MAAM,GACR,IAAI,cAAc,CAAC,yBAAyB,EAAE,EAAC,SAAS,EAAE,EAAE,EAAC,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAE3C,yCAAyC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {env} from '@tensorflow/tfjs-core';\nimport {FileDataSource} from '../sources/file_data_source';\nimport {TextLineDataset} from './text_line_dataset';\n\nconst runes = `ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ\nᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ\nᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬`;\n\nconst textWithDOSLineBreaks = 'abc\\rdefg\\r\\nhijklmn\\r\\nopqrst';\n\nconst testBlob =\n env().get('IS_BROWSER') ? new Blob([runes]) : Buffer.from(runes);\n\nconst textBlobWithDOSLineBreaks = env().get('IS_BROWSER') ?\n new Blob([textWithDOSLineBreaks]) :\n Buffer.from(textWithDOSLineBreaks);\n\ndescribe('TextLineDataset', () => {\n it('Produces a stream of strings containing UTF8-decoded text lines',\n async () => {\n const source = new FileDataSource(testBlob, {chunkSize: 10});\n const dataset = new TextLineDataset(source);\n const iter = await dataset.iterator();\n const result = await iter.toArrayForTest();\n\n expect(result).toEqual([\n 'ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ',\n 'ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ',\n 'ᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬',\n ]);\n });\n\n it('Parses lines from windows/DOS text correctly', async () => {\n const source =\n new FileDataSource(textBlobWithDOSLineBreaks, {chunkSize: 10});\n const dataset = new TextLineDataset(source);\n const iter = await dataset.iterator();\n const result = await iter.toArrayForTest();\n\n // \\r is retained when not followed by \\n\n expect(result[0]).toEqual('abc\\rdefg');\n expect(result[1]).toEqual('hijklmn');\n expect(result[2]).toEqual('opqrst');\n });\n});\n"]}
|
||||
Generated
Vendored
-31
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { LazyIterator } from './lazy_iterator';
|
||||
import { StringIterator } from './string_iterator';
|
||||
export declare abstract class ByteChunkIterator extends LazyIterator<Uint8Array> {
|
||||
/**
|
||||
* Decode a stream of UTF8-encoded byte arrays to a stream of strings.
|
||||
*
|
||||
* The byte arrays producetd from the ByteChunkIterator on which this is
|
||||
* called will be interpreted as concatenated. No assumptions are made about
|
||||
* the boundaries of the incoming chunks, so a multi-byte UTF8 encoding of a
|
||||
* character may span the boundary between chunks. This naturally happens,
|
||||
* for instance, when reading fixed-size byte arrays from a file.
|
||||
*/
|
||||
decodeUTF8(): StringIterator;
|
||||
}
|
||||
Generated
Vendored
-115
@@ -1,115 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { env } from '@tensorflow/tfjs-core';
|
||||
import { LazyIterator, OneToManyIterator } from './lazy_iterator';
|
||||
import { StringIterator } from './string_iterator';
|
||||
export class ByteChunkIterator extends LazyIterator {
|
||||
/**
|
||||
* Decode a stream of UTF8-encoded byte arrays to a stream of strings.
|
||||
*
|
||||
* The byte arrays producetd from the ByteChunkIterator on which this is
|
||||
* called will be interpreted as concatenated. No assumptions are made about
|
||||
* the boundaries of the incoming chunks, so a multi-byte UTF8 encoding of a
|
||||
* character may span the boundary between chunks. This naturally happens,
|
||||
* for instance, when reading fixed-size byte arrays from a file.
|
||||
*/
|
||||
decodeUTF8() {
|
||||
return new Utf8Iterator(this);
|
||||
}
|
||||
}
|
||||
// ============================================================================
|
||||
// The following private classes serve to implement the chainable methods
|
||||
// on ByteChunkIterator. Unfortunately they can't be placed in separate files,
|
||||
// due to resulting trouble with circular imports.
|
||||
// ============================================================================
|
||||
// We wanted multiple inheritance, e.g.
|
||||
// class Utf8Iterator extends QueueIterator<string>, StringIterator
|
||||
// but the TypeScript mixin approach is a bit hacky, so we take this adapter
|
||||
// approach instead.
|
||||
class Utf8Iterator extends StringIterator {
|
||||
constructor(upstream) {
|
||||
super();
|
||||
this.upstream = upstream;
|
||||
this.impl = new Utf8IteratorImpl(upstream);
|
||||
}
|
||||
summary() {
|
||||
return this.impl.summary();
|
||||
}
|
||||
async next() {
|
||||
return this.impl.next();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Decode a stream of UTF8-encoded byte arrays to a stream of strings.
|
||||
*
|
||||
* This is tricky because the incoming byte array boundaries may disrupt a
|
||||
* multi-byte UTF8 character. Thus any incomplete character data at the end of
|
||||
* a chunk must be carried over and prepended to the next chunk before
|
||||
* decoding. Luckily with native decoder, TextDecoder in browser and
|
||||
* string_decoder in node, byte array boundaries are handled automatically.
|
||||
*
|
||||
* In the context of an input pipeline for machine learning, UTF8 decoding is
|
||||
* needed to parse text files containing training examples or prediction
|
||||
* requests (e.g., formatted as CSV or JSON). We cannot use the built-in
|
||||
* decoding provided by FileReader.readAsText() because here we are in a
|
||||
* streaming context, which FileReader does not support.
|
||||
*
|
||||
* @param upstream A `LazyIterator` of `Uint8Arrays` containing UTF8-encoded
|
||||
* text, which should be interpreted as concatenated. No assumptions are
|
||||
* made about the boundaries of the incoming chunks, so a multi-byte UTF8
|
||||
* encoding of a character may span the boundary between chunks. This
|
||||
* naturally happens, for instance, when reading fixed-size byte arrays from a
|
||||
* file.
|
||||
*/
|
||||
class Utf8IteratorImpl extends OneToManyIterator {
|
||||
constructor(upstream) {
|
||||
super();
|
||||
this.upstream = upstream;
|
||||
if (env().get('IS_BROWSER')) {
|
||||
this.decoder = new TextDecoder('utf-8');
|
||||
}
|
||||
else {
|
||||
// tslint:disable-next-line:no-require-imports
|
||||
const { StringDecoder } = require('string_decoder');
|
||||
this.decoder = new StringDecoder('utf8');
|
||||
}
|
||||
}
|
||||
summary() {
|
||||
return `${this.upstream.summary()} -> Utf8`;
|
||||
}
|
||||
async pump() {
|
||||
const chunkResult = await this.upstream.next();
|
||||
let chunk;
|
||||
if (chunkResult.done) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
chunk = chunkResult.value;
|
||||
}
|
||||
let text;
|
||||
if (env().get('IS_BROWSER')) {
|
||||
text = this.decoder.decode(chunk, { stream: true });
|
||||
}
|
||||
else {
|
||||
text = this.decoder.write(Buffer.from(chunk.buffer));
|
||||
}
|
||||
this.outputQueue.push(text);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=byte_chunk_iterator.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"byte_chunk_iterator.js","sourceRoot":"","sources":["../../src/iterators/byte_chunk_iterator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,GAAG,EAAC,MAAM,uBAAuB,CAAC;AAC1C,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAEjD,MAAM,OAAgB,iBAAkB,SAAQ,YAAwB;IACtE;;;;;;;;OAQG;IACH,UAAU;QACR,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;CACF;AAED,+EAA+E;AAC/E,yEAAyE;AACzE,+EAA+E;AAC/E,kDAAkD;AAClD,+EAA+E;AAE/E,uCAAuC;AACvC,qEAAqE;AACrE,4EAA4E;AAC5E,oBAAoB;AAEpB,MAAM,YAAa,SAAQ,cAAc;IAGvC,YAAsB,QAAkC;QACtD,KAAK,EAAE,CAAC;QADY,aAAQ,GAAR,QAAQ,CAA0B;QAEtD,IAAI,CAAC,IAAI,GAAG,IAAI,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,gBAAiB,SAAQ,iBAAyB;IAMtD,YAA+B,QAAkC;QAC/D,KAAK,EAAE,CAAC;QADqB,aAAQ,GAAR,QAAQ,CAA0B;QAE/D,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;YAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;SACzC;aAAM;YACL,8CAA8C;YAC9C,MAAM,EAAC,aAAa,EAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;SAC1C;IACH,CAAC;IACD,OAAO;QACL,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,KAAK,CAAC;QACV,IAAI,WAAW,CAAC,IAAI,EAAE;YACpB,OAAO,KAAK,CAAC;SACd;aAAM;YACL,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;SAC3B;QAED,IAAI,IAAY,CAAC;QACjB,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;YAC3B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAC;SACnD;aAAM;YACL,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;SACtD;QACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {env} from '@tensorflow/tfjs-core';\nimport {LazyIterator, OneToManyIterator} from './lazy_iterator';\nimport {StringIterator} from './string_iterator';\n\nexport abstract class ByteChunkIterator extends LazyIterator<Uint8Array> {\n /**\n * Decode a stream of UTF8-encoded byte arrays to a stream of strings.\n *\n * The byte arrays producetd from the ByteChunkIterator on which this is\n * called will be interpreted as concatenated. No assumptions are made about\n * the boundaries of the incoming chunks, so a multi-byte UTF8 encoding of a\n * character may span the boundary between chunks. This naturally happens,\n * for instance, when reading fixed-size byte arrays from a file.\n */\n decodeUTF8(): StringIterator {\n return new Utf8Iterator(this);\n }\n}\n\n// ============================================================================\n// The following private classes serve to implement the chainable methods\n// on ByteChunkIterator. Unfortunately they can't be placed in separate files,\n// due to resulting trouble with circular imports.\n// ============================================================================\n\n// We wanted multiple inheritance, e.g.\n// class Utf8Iterator extends QueueIterator<string>, StringIterator\n// but the TypeScript mixin approach is a bit hacky, so we take this adapter\n// approach instead.\n\nclass Utf8Iterator extends StringIterator {\n private impl: Utf8IteratorImpl;\n\n constructor(protected upstream: LazyIterator<Uint8Array>) {\n super();\n this.impl = new Utf8IteratorImpl(upstream);\n }\n\n summary() {\n return this.impl.summary();\n }\n\n async next() {\n return this.impl.next();\n }\n}\n\n/**\n * Decode a stream of UTF8-encoded byte arrays to a stream of strings.\n *\n * This is tricky because the incoming byte array boundaries may disrupt a\n * multi-byte UTF8 character. Thus any incomplete character data at the end of\n * a chunk must be carried over and prepended to the next chunk before\n * decoding. Luckily with native decoder, TextDecoder in browser and\n * string_decoder in node, byte array boundaries are handled automatically.\n *\n * In the context of an input pipeline for machine learning, UTF8 decoding is\n * needed to parse text files containing training examples or prediction\n * requests (e.g., formatted as CSV or JSON). We caLine truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"byte_chunk_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/byte_chunk_iterator_test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,GAAG,EAAC,MAAM,uBAAuB,CAAC;AAC1C,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AAExD,MAAM,KAAK,GAAG;;sCAEwB,CAAC;AAEvC,MAAM,QAAQ,GACV,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAErE,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,QAAQ,EAAE,EAAC,SAAS,EAAE,EAAE,EAAC,CAAC,CAAC;QAC3E,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAE,QAAiB,CAAC,IAAI,CAAC,CAAC;YACxB,QAAmB,CAAC,UAAU,CAAC,CAAC;aAC9D,OAAO,CAAC,GAAG,CAAC,CAAC;QAClB,MAAM,YAAY,GAAG,iBAAiB,CAAC,UAAU,EAAE,CAAC;QAEpD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QACnD,mEAAmE;QACnE,qEAAqE;QACrE,sEAAsE;QACtE,qEAAqE;QACrE,sBAAsB;QACtB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {env} from '@tensorflow/tfjs-core';\nimport {FileChunkIterator} from './file_chunk_iterator';\n\nconst runes = `ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ\nᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ\nᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬`;\n\nconst testData =\n env().get('IS_BROWSER') ? new Blob([runes]) : Buffer.from(runes);\n\ndescribe('ByteChunkIterator.decodeUTF8()', () => {\n it('Correctly reassembles split characters', async () => {\n const byteChunkIterator = new FileChunkIterator(testData, {chunkSize: 50});\n expect((env().get('IS_BROWSER') ? (testData as Blob).size :\n (testData as Buffer).byteLength))\n .toEqual(323);\n const utf8Iterator = byteChunkIterator.decodeUTF8();\n\n const result = await utf8Iterator.toArrayForTest();\n // The test string is 109 characters long; its UTF8 encoding is 323\n // bytes. We read it in chunks of 50 bytes, so there were 7 chunks of\n // bytes. The UTF decoder slightly adjusted the boundaries between the\n // chunks to allow decoding, but did not change the number of chunks,\n // so 7 chunks remain.\n expect(result.length).toEqual(7);\n const totalCharacters = result.map(x => x.length).reduce((a, b) => a + b);\n expect(totalCharacters).toEqual(109);\n expect(result.join('')).toEqual(runes);\n });\n});\n"]}
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"chained_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/chained_iterator_test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAC,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AAEzD,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,eAAe,GAAG,IAAI,eAAe,CACvC,iBAAiB,CAAC,CAAC,IAAI,mBAAmB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;QAEvE,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;gBAC5C,cAAc,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aACjD;SACF;QAED,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,iBAAiB,CAAC;YAC5D,IAAI,mBAAmB,CAAC,mBAAmB,CAAC;YAC5C,IAAI,mBAAmB,CAAC,mBAAmB,CAAC;YAC5C,IAAI,mBAAmB,CAAC,mBAAmB,CAAC;SAC7C,CAAC,CAAC,CAAC;QAEJ,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;gBAC5C,cAAc,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aACjD;SACF;QAED,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {ChainedIterator} from './lazy_iterator';\nimport {iteratorFromItems} from './lazy_iterator';\nimport {TestIntegerIterator} from './lazy_iterator_test';\n\nconst SHORT_STREAM_LENGTH = 15;\n\ndescribe('ChainedIterator', () => {\n it('produces a single underlying stream as expected', async () => {\n const chainedIterator = new ChainedIterator(\n iteratorFromItems([new TestIntegerIterator(SHORT_STREAM_LENGTH)]));\n\n const expectedResult: number[] = [];\n for (let i = 0; i < 1; i++) {\n for (let j = 0; j < SHORT_STREAM_LENGTH; j++) {\n expectedResult[i * SHORT_STREAM_LENGTH + j] = j;\n }\n }\n\n const result = await chainedIterator.toArrayForTest();\n expect(result).toEqual(expectedResult);\n });\n it('produces multiple underlying streams as expected', async () => {\n const chainedIterator = new ChainedIterator(iteratorFromItems([\n new TestIntegerIterator(SHORT_STREAM_LENGTH),\n new TestIntegerIterator(SHORT_STREAM_LENGTH),\n new TestIntegerIterator(SHORT_STREAM_LENGTH)\n ]));\n\n const expectedResult: number[] = [];\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < SHORT_STREAM_LENGTH; j++) {\n expectedResult[i * SHORT_STREAM_LENGTH + j] = j;\n }\n }\n\n const result = await chainedIterator.toArrayForTest();\n expect(result).toEqual(expectedResult);\n });\n});\n"]}
|
||||
Generated
Vendored
-41
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { FileElement } from '../types';
|
||||
import { ByteChunkIterator } from './byte_chunk_iterator';
|
||||
export interface FileChunkIteratorOptions {
|
||||
/** The byte offset at which to begin reading the File or Blob. Default 0. */
|
||||
offset?: number;
|
||||
/** The number of bytes to read at a time. Default 1MB. */
|
||||
chunkSize?: number;
|
||||
}
|
||||
/**
|
||||
* Provide a stream of chunks from a File, Blob, or Uint8Array.
|
||||
* @param file The source File, Blob or Uint8Array.
|
||||
* @param options Optional settings controlling file reading.
|
||||
* @returns a lazy Iterator of Uint8Arrays containing sequential chunks of the
|
||||
* input File, Blob or Uint8Array.
|
||||
*/
|
||||
export declare class FileChunkIterator extends ByteChunkIterator {
|
||||
protected file: FileElement;
|
||||
protected options: FileChunkIteratorOptions;
|
||||
offset: number;
|
||||
chunkSize: number;
|
||||
constructor(file: FileElement, options?: FileChunkIteratorOptions);
|
||||
summary(): string;
|
||||
next(): Promise<IteratorResult<Uint8Array>>;
|
||||
}
|
||||
Generated
Vendored
-94
@@ -1,94 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
// inspired by https://github.com/maxogden/filereader-stream
|
||||
import { env, util } from '@tensorflow/tfjs-core';
|
||||
import { ByteChunkIterator } from './byte_chunk_iterator';
|
||||
/**
|
||||
* Provide a stream of chunks from a File, Blob, or Uint8Array.
|
||||
* @param file The source File, Blob or Uint8Array.
|
||||
* @param options Optional settings controlling file reading.
|
||||
* @returns a lazy Iterator of Uint8Arrays containing sequential chunks of the
|
||||
* input File, Blob or Uint8Array.
|
||||
*/
|
||||
export class FileChunkIterator extends ByteChunkIterator {
|
||||
constructor(file, options = {}) {
|
||||
super();
|
||||
this.file = file;
|
||||
this.options = options;
|
||||
util.assert((file instanceof Uint8Array) ||
|
||||
(env().get('IS_BROWSER') ?
|
||||
(file instanceof File || file instanceof Blob) :
|
||||
false), () => 'FileChunkIterator only supports File, Blob and Uint8Array ' +
|
||||
'right now.');
|
||||
this.offset = options.offset || 0;
|
||||
// default 1MB chunk has tolerable perf on large files
|
||||
this.chunkSize = options.chunkSize || 1024 * 1024;
|
||||
}
|
||||
summary() {
|
||||
return `FileChunks ${this.file}`;
|
||||
}
|
||||
async next() {
|
||||
if (this.offset >= ((this.file instanceof Uint8Array) ?
|
||||
this.file.byteLength :
|
||||
this.file.size)) {
|
||||
return { value: null, done: true };
|
||||
}
|
||||
const chunk = new Promise((resolve, reject) => {
|
||||
const end = this.offset + this.chunkSize;
|
||||
if (this.file instanceof Uint8Array) {
|
||||
// Note if end > this.uint8Array.byteLength, we just get a small last
|
||||
// chunk.
|
||||
resolve(new Uint8Array(this.file.slice(this.offset, end)));
|
||||
}
|
||||
else {
|
||||
// This branch assumes that this.file type is File or Blob, which
|
||||
// means it is in the browser environment.
|
||||
// TODO(soergel): is this a performance issue?
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = (event) => {
|
||||
let data = fileReader.result;
|
||||
// Not sure we can trust the return type of
|
||||
// FileReader.readAsArrayBuffer See e.g.
|
||||
// https://github.com/node-file-api/FileReader/issues/2
|
||||
if (data instanceof ArrayBuffer) {
|
||||
data = new Uint8Array(data);
|
||||
}
|
||||
if (!(data instanceof Uint8Array)) {
|
||||
return reject(new TypeError('FileReader returned unknown type.'));
|
||||
}
|
||||
resolve(data);
|
||||
};
|
||||
fileReader.onabort = (event) => {
|
||||
return reject(new Error('Aborted'));
|
||||
};
|
||||
fileReader.onerror = (event) => {
|
||||
return reject(new Error(event.type));
|
||||
};
|
||||
// TODO(soergel): better handle onabort, onerror
|
||||
// Note if end > this.file.size, we just get a small last chunk.
|
||||
const slice = this.file.slice(this.offset, end);
|
||||
// We can't use readAsText here (even if we know the file is text)
|
||||
// because the slice boundary may fall within a multi-byte character.
|
||||
fileReader.readAsArrayBuffer(slice);
|
||||
}
|
||||
this.offset = end;
|
||||
});
|
||||
return { value: (await chunk), done: false };
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=file_chunk_iterator.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"file_chunk_iterator.js","sourceRoot":"","sources":["../../src/iterators/file_chunk_iterator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,4DAA4D;AAC5D,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AASxD;;;;;;GAMG;AACH,MAAM,OAAO,iBAAkB,SAAQ,iBAAiB;IAItD,YACc,IAAiB,EACjB,UAAoC,EAAE;QAClD,KAAK,EAAE,CAAC;QAFI,SAAI,GAAJ,IAAI,CAAa;QACjB,YAAO,GAAP,OAAO,CAA+B;QAElD,IAAI,CAAC,MAAM,CACP,CAAC,IAAI,YAAY,UAAU,CAAC;YACxB,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;gBACrB,CAAC,IAAI,YAAY,IAAI,IAAI,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC;gBAChD,KAAK,CAAC,EACf,GAAG,EAAE,CAAC,4DAA4D;YAC9D,YAAY,CAAC,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QAClC,sDAAsD;QACtD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,GAAG,IAAI,CAAC;IACpD,CAAC;IAED,OAAO;QACL,OAAO,cAAc,IAAI,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACvC,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAC,CAAC;SAClC;QACD,MAAM,KAAK,GAAG,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;YACzC,IAAI,IAAI,CAAC,IAAI,YAAY,UAAU,EAAE;gBACnC,qEAAqE;gBACrE,SAAS;gBACT,OAAO,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;aAC5D;iBAAM;gBACL,iEAAiE;gBACjE,0CAA0C;gBAE1C,8CAA8C;gBAC9C,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;gBACpC,UAAU,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,EAAE;oBAC5B,IAAI,IAAI,GAAkC,UAAU,CAAC,MAAM,CAAC;oBAC5D,2CAA2C;oBAC3C,wCAAwC;oBACxC,uDAAuD;oBACvD,IAAI,IAAI,YAAY,WAAW,EAAE;wBAC/B,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;qBAC7B;oBACD,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC,EAAE;wBACjC,OAAO,MAAM,CAAC,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC,CAAC;qBACnE;oBACD,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC,CAAC;gBACF,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;oBAC7B,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;gBACtC,CAAC,CAAC;gBACF,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;oBAC7B,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvC,CAAC,CAAC;gBACF,gDAAgD;gBAChD,gEAAgE;gBAChE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBAChD,kEAAkE;gBAClE,qEAAqE;gBACrE,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;aACrC;YACD,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,OAAO,EAAC,KAAK,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC;IAC7C,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\n// inspired by https://github.com/maxogden/filereader-stream\nimport {env, util} from '@tensorflow/tfjs-core';\nimport {FileElement} from '../types';\nimport {ByteChunkIterator} from './byte_chunk_iterator';\n\nexport interface FileChunkIteratorOptions {\n /** The byte offset at which to begin reading the File or Blob. Default 0. */\n offset?: number;\n /** The number of bytes to read at a time. Default 1MB. */\n chunkSize?: number;\n}\n\n/**\n * Provide a stream of chunks from a File, Blob, or Uint8Array.\n * @param file The source File, Blob or Uint8Array.\n * @param options Optional settings controlling file reading.\n * @returns a lazy Iterator of Uint8Arrays containing sequential chunks of the\n * input File, Blob or Uint8Array.\n */\nexport class FileChunkIterator extends ByteChunkIterator {\n offset: number;\n chunkSize: number;\n\n constructor(\n protected file: FileElement,\n protected options: FileChunkIteratorOptions = {}) {\n super();\n util.assert(\n (file instanceof Uint8Array) ||\n (env().get('IS_BROWSER') ?\n (file instanceof File || file instanceof Blob) :\n false),\n () => 'FileChunkIterator only supports File, Blob and Uint8Array ' +\n 'right now.');\n this.offset = options.offset || 0;\n // default 1MB chunk has tolerable perf on large files\n this.chunkSize = options.chunkSize || 1024 * 1024;\n }\n\n summary() {\n return `FileChunks ${this.file}`;\n }\n\n async next(): Promise<IteratorResult<Uint8Array>> {\n if (this.offset >= ((this.file instanceof Uint8Array) ?\n this.file.byteLength :\n this.file.size)) {\n return {value: null, done: true};\n Line truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"file_chunk_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/file_chunk_iterator_test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {env} from '@tensorflow/tfjs-core';\nimport {FileChunkIterator} from './file_chunk_iterator';\n\nconst range = (start: number, end: number) => {\n return Array.from({length: (end - start)}, (v, k) => k + start);\n};\n\nconst testData = env().get('IS_BROWSER') ?\n new Blob([new Uint8Array(range(0, 55))]) :\n new Uint8Array(range(0, 55));\n\ndescribe('FileChunkIterator', () => {\n it('Reads the entire file and then closes the stream', async () => {\n const readIterator = new FileChunkIterator(testData, {chunkSize: 10});\n const result = await readIterator.toArrayForTest();\n expect(result.length).toEqual(6);\n const totalBytes = result.map(x => x.length).reduce((a, b) => a + b);\n expect(totalBytes).toEqual(55);\n });\n\n it('Reads chunks in order', async () => {\n const readIterator = new FileChunkIterator(testData, {chunkSize: 10});\n const result = await readIterator.toArrayForTest();\n expect(result[0][0]).toEqual(0);\n expect(result[1][0]).toEqual(10);\n expect(result[2][0]).toEqual(20);\n expect(result[3][0]).toEqual(30);\n expect(result[4][0]).toEqual(40);\n expect(result[5][0]).toEqual(50);\n });\n\n it('Reads chunks of expected sizes', async () => {\n const readIterator = new FileChunkIterator(testData, {chunkSize: 10});\n const result = await readIterator.toArrayForTest();\n expect(result[0].length).toEqual(10);\n expect(result[1].leLine truncated
|
||||
Generated
Vendored
-422
@@ -1,422 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import * as tf from '@tensorflow/tfjs-core';
|
||||
import { Container } from '../types';
|
||||
import { DeepMapResult } from '../util/deep_map';
|
||||
import { RingBuffer } from '../util/ring_buffer';
|
||||
/**
|
||||
* A nested structure of LazyIterators, used as the input to zip().
|
||||
*/
|
||||
export declare type IteratorContainer = Container<LazyIterator<tf.TensorContainer>>;
|
||||
/**
|
||||
* Create a `LazyIterator` from an array of items.
|
||||
*/
|
||||
export declare function iteratorFromItems<T>(items: T[]): LazyIterator<T>;
|
||||
/**
|
||||
* Create a `LazyIterator` of incrementing integers.
|
||||
*/
|
||||
export declare function iteratorFromIncrementing(start: number): LazyIterator<number>;
|
||||
/**
|
||||
* Create a `LazyIterator` from a function.
|
||||
*
|
||||
* ```js
|
||||
* let i = -1;
|
||||
* const func = () =>
|
||||
* ++i < 5 ? {value: i, done: false} : {value: null, done: true};
|
||||
* const iter = tf.data.iteratorFromFunction(func);
|
||||
* await iter.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param func A function that produces data on each call.
|
||||
*/
|
||||
export declare function iteratorFromFunction<T>(func: () => IteratorResult<T> | Promise<IteratorResult<T>>): LazyIterator<T>;
|
||||
/**
|
||||
* Create a `LazyIterator` by concatenating underlying streams, which are
|
||||
* themselves provided as a stream.
|
||||
*
|
||||
* This can also be thought of as a "stream flatten" operation.
|
||||
*
|
||||
* @param baseIterators A stream of streams to be concatenated.
|
||||
* @param baseErrorHandler An optional function that can intercept `Error`s
|
||||
* raised during a `next()` call on the base stream. This function can decide
|
||||
* whether the error should be propagated, whether the error should be
|
||||
* ignored, or whether the base stream should be terminated.
|
||||
*/
|
||||
export declare function iteratorFromConcatenated<T>(baseIterators: LazyIterator<LazyIterator<T>>, baseErrorHandler?: (e: Error) => boolean): LazyIterator<T>;
|
||||
/**
|
||||
* Create a `LazyIterator` by concatenating streams produced by calling a
|
||||
* stream-generating function a given number of times.
|
||||
*
|
||||
* Since a `LazyIterator` is read-once, it cannot be repeated, but this
|
||||
* function can be used to achieve a similar effect:
|
||||
*
|
||||
* LazyIterator.ofConcatenatedFunction(() => new MyIterator(), 6);
|
||||
*
|
||||
* @param iteratorFunc: A function that produces a new stream on each call.
|
||||
* @param count: The number of times to call the function.
|
||||
* @param baseErrorHandler An optional function that can intercept `Error`s
|
||||
* raised during a `next()` call on the base stream. This function can decide
|
||||
* whether the error should be propagated, whether the error should be
|
||||
* ignored, or whether the base stream should be terminated.
|
||||
*/
|
||||
export declare function iteratorFromConcatenatedFunction<T>(iteratorFunc: () => IteratorResult<LazyIterator<T>>, count: number, baseErrorHandler?: (e: Error) => boolean): LazyIterator<T>;
|
||||
/**
|
||||
* Create a `LazyIterator` by zipping together an array, dict, or nested
|
||||
* structure of `LazyIterator`s (and perhaps additional constants).
|
||||
*
|
||||
* The underlying streams must provide elements in a consistent order such
|
||||
* that they correspond.
|
||||
*
|
||||
* Typically, the underlying streams should have the same number of
|
||||
* elements. If they do not, the behavior is determined by the
|
||||
* `mismatchMode` argument.
|
||||
*
|
||||
* The nested structure of the `iterators` argument determines the
|
||||
* structure of elements in the resulting iterator.
|
||||
*
|
||||
* @param iterators: An array or object containing LazyIterators at the
|
||||
* leaves.
|
||||
* @param mismatchMode: Determines what to do when one underlying iterator
|
||||
* is exhausted before the others. `ZipMismatchMode.FAIL` (the default)
|
||||
* causes an error to be thrown in this case. `ZipMismatchMode.SHORTEST`
|
||||
* causes the zipped iterator to terminate with the furst underlying
|
||||
* streams, so elements remaining on the longer streams are ignored.
|
||||
* `ZipMismatchMode.LONGEST` causes the zipped stream to continue, filling
|
||||
* in nulls for the exhausted streams, until all streams are exhausted.
|
||||
*/
|
||||
export declare function iteratorFromZipped<O extends tf.TensorContainer>(iterators: IteratorContainer, mismatchMode?: ZipMismatchMode): LazyIterator<O>;
|
||||
/**
|
||||
* An asynchronous iterator, providing lazy access to a potentially
|
||||
* unbounded stream of elements.
|
||||
*
|
||||
* Iterator can be obtained from a dataset:
|
||||
* `const iter = await dataset.iterator();`
|
||||
*/
|
||||
export declare abstract class LazyIterator<T> {
|
||||
abstract summary(): string;
|
||||
/**
|
||||
* Returns a `Promise` for the next element in the stream.
|
||||
*
|
||||
* When an item can be provided successfully, the return value is
|
||||
* `{value:T, done:false}`.
|
||||
*
|
||||
* Calling next() on a closed stream returns `{value:null, done:true}`.
|
||||
*/
|
||||
abstract next(): Promise<IteratorResult<T>>;
|
||||
/**
|
||||
* Collect all remaining elements of a bounded stream into an array.
|
||||
* Obviously this will succeed only for small streams that fit in memory.
|
||||
* Useful for testing.
|
||||
*
|
||||
* @returns A Promise for an array of stream elements, which will resolve
|
||||
* when the stream is exhausted.
|
||||
*/
|
||||
toArray(): Promise<T[]>;
|
||||
/**
|
||||
* Collect all elements of this dataset into an array with prefetching 100
|
||||
* elements. This is useful for testing, because the prefetch changes the
|
||||
* order in which the Promises are resolved along the processing pipeline.
|
||||
* This may help expose bugs where results are dependent on the order of
|
||||
* Promise resolution rather than on the logical order of the stream (i.e.,
|
||||
* due to hidden mutable state).
|
||||
*
|
||||
* @returns A Promise for an array of stream elements, which will resolve
|
||||
* when the stream is exhausted.
|
||||
*/
|
||||
toArrayForTest(): Promise<T[]>;
|
||||
/**
|
||||
* Draw items from the stream until it is exhausted.
|
||||
*
|
||||
* This can be useful when the stream has side effects but no output. In
|
||||
* that case, calling this function guarantees that the stream will be
|
||||
* fully processed.
|
||||
*/
|
||||
resolveFully(): Promise<void>;
|
||||
/**
|
||||
* Draw items from the stream until it is exhausted, or a predicate fails.
|
||||
*
|
||||
* This can be useful when the stream has side effects but no output. In
|
||||
* that case, calling this function guarantees that the stream will be
|
||||
* fully processed.
|
||||
*/
|
||||
resolveWhile(predicate: (r: T) => boolean): Promise<void>;
|
||||
/**
|
||||
* Handles errors thrown on this stream using a provided handler function.
|
||||
*
|
||||
* @param handler A function that handles any `Error` thrown during a `next()`
|
||||
* call and returns true if the stream should continue (dropping the failed
|
||||
* call) or false if the stream should quietly terminate. If the handler
|
||||
* itself throws (or rethrows) an `Error`, that will be propagated.
|
||||
*
|
||||
* @returns A `LazyIterator` of elements passed through from upstream,
|
||||
* possibly filtering or terminating on upstream `next()` calls that
|
||||
* throw an `Error`.
|
||||
*/
|
||||
handleErrors(handler: (error: Error) => boolean): LazyIterator<T>;
|
||||
/**
|
||||
* Filters this stream according to `predicate`.
|
||||
*
|
||||
* @param predicate A function mapping a stream element to a boolean or a
|
||||
* `Promise` for one.
|
||||
*
|
||||
* @returns A `LazyIterator` of elements for which the predicate was true.
|
||||
*/
|
||||
filter(predicate: (value: T) => boolean): LazyIterator<T>;
|
||||
/**
|
||||
* Maps this stream through a 1-to-1 transform.
|
||||
*
|
||||
* @param transform A function mapping a stream element to a transformed
|
||||
* element.
|
||||
*
|
||||
* @returns A `LazyIterator` of transformed elements.
|
||||
*/
|
||||
map<O>(transform: (value: T) => O): LazyIterator<O>;
|
||||
/**
|
||||
* Maps this stream through an async 1-to-1 transform.
|
||||
*
|
||||
* @param transform A function mapping a stream element to a `Promise` for a
|
||||
* transformed stream element.
|
||||
*
|
||||
* @returns A `LazyIterator` of transformed elements.
|
||||
*/
|
||||
mapAsync<O>(transform: (value: T) => Promise<O>): LazyIterator<O>;
|
||||
/**
|
||||
* Maps this stream through a 1-to-1 transform, forcing serial execution.
|
||||
*
|
||||
* @param transform A function mapping a stream element to a transformed
|
||||
* element.
|
||||
*
|
||||
* @returns A `LazyIterator` of transformed elements.
|
||||
*/
|
||||
serialMapAsync<O>(transform: (value: T) => Promise<O>): LazyIterator<O>;
|
||||
/**
|
||||
* Maps this stream through a 1-to-many transform.
|
||||
*
|
||||
* @param transform A function mapping a stream element to an array of
|
||||
* transformed elements.
|
||||
*
|
||||
* @returns A `DataStream` of transformed elements.
|
||||
*/
|
||||
flatmap<O>(transform: (value: T) => O[]): LazyIterator<O>;
|
||||
/**
|
||||
* Apply a function to every element of the stream.
|
||||
*
|
||||
* @param f A function to apply to each stream element.
|
||||
*/
|
||||
forEachAsync(f: (value: T) => void): Promise<void>;
|
||||
/**
|
||||
* Apply a function to every element of the stream, forcing serial execution.
|
||||
*
|
||||
* @param f A function to apply to each stream element. Should return 'true'
|
||||
* to indicate that the stream should continue, or 'false' to cause it to
|
||||
* terminate.
|
||||
*/
|
||||
serialForEach(f: (value: T) => Promise<boolean>): Promise<void>;
|
||||
/**
|
||||
* Groups elements into batches, represented as arrays of elements.
|
||||
*
|
||||
* We can think of the elements of this iterator as 'rows' (even if they are
|
||||
* nested structures). By the same token, consecutive values for a given
|
||||
* key within the elements form a 'column'. This matches the usual sense of
|
||||
* 'row' and 'column' when processing tabular data (e.g., parsing a CSV).
|
||||
*
|
||||
* Thus, "Row-major" means that the resulting batch is simply a collection of
|
||||
* rows: `[row1, row2, row3, ...]`. This is contrast to the column-major
|
||||
* form, which is needed for vectorized computation.
|
||||
*
|
||||
* @param batchSize The number of elements desired per batch.
|
||||
* @param smallLastBatch Whether to emit the final batch when it has fewer
|
||||
* than batchSize elements. Default true.
|
||||
* @returns A `LazyIterator` of batches of elements, represented as arrays
|
||||
* of the original element type.
|
||||
*/
|
||||
rowMajorBatch(batchSize: number, smallLastBatch?: boolean): LazyIterator<T[]>;
|
||||
/**
|
||||
* Groups elements into batches, represented in column-major form.
|
||||
*
|
||||
* We can think of the elements of this iterator as 'rows' (even if they are
|
||||
* nested structures). By the same token, consecutive values for a given
|
||||
* key within the elements form a 'column'. This matches the usual sense of
|
||||
* 'row' and 'column' when processing tabular data (e.g., parsing a CSV).
|
||||
*
|
||||
* Thus, "column-major" means that the resulting batch is a (potentially
|
||||
* nested) structure representing the columns. Each column entry, then,
|
||||
* contains a collection of the values found in that column for a range of
|
||||
* input elements. This representation allows for vectorized computation, in
|
||||
* contrast to the row-major form.
|
||||
*
|
||||
* The inputs should all have the same nested structure (i.e., of arrays and
|
||||
* dicts). The result is a single object with the same nested structure,
|
||||
* where the leaves are arrays collecting the values of the inputs at that
|
||||
* location (or, optionally, the result of a custom function applied to those
|
||||
* arrays).
|
||||
*
|
||||
* @param batchSize The number of elements desired per batch.
|
||||
* @param smallLastBatch Whether to emit the final batch when it has fewer
|
||||
* than batchSize elements. Default true.
|
||||
* @param zipFn: (optional) A function that expects an array of elements at a
|
||||
* single node of the object tree, and returns a `DeepMapResult`. The
|
||||
* `DeepMapResult` either provides a result value for that node (i.e.,
|
||||
* representing the subtree), or indicates that the node should be processed
|
||||
* recursively. The default zipFn recurses as far as possible and places
|
||||
* arrays at the leaves.
|
||||
* @returns A `LazyIterator` of batches of elements, represented as an object
|
||||
* with collections at the leaves.
|
||||
*/
|
||||
columnMajorBatch(batchSize: number, smallLastBatch?: boolean, zipFn?: (xs: any[]) => DeepMapResult): LazyIterator<tf.TensorContainer>;
|
||||
/**
|
||||
* Concatenate this `LazyIterator` with another.
|
||||
*
|
||||
* @param iterator A `LazyIterator` to be concatenated onto this one.
|
||||
* @param baseErrorHandler An optional function that can intercept `Error`s
|
||||
* raised during a `next()` call on the base stream. This function can
|
||||
* decide whether the error should be propagated, whether the error should
|
||||
* be ignored, or whether the base stream should be terminated.
|
||||
* @returns A `LazyIterator`.
|
||||
*/
|
||||
concatenate(iterator: LazyIterator<T>, baseErrorHandler?: (e: Error) => boolean): LazyIterator<T>;
|
||||
/**
|
||||
* Limits this stream to return at most `count` items.
|
||||
*
|
||||
* @param count The maximum number of items to provide from the stream. If
|
||||
* a negative or undefined value is given, the entire stream is returned
|
||||
* unaltered.
|
||||
*/
|
||||
take(count: number): LazyIterator<T>;
|
||||
/**
|
||||
* Skips the first `count` items in this stream.
|
||||
*
|
||||
* @param count The number of items to skip. If a negative or undefined
|
||||
* value is given, the entire stream is returned unaltered.
|
||||
*/
|
||||
skip(count: number): LazyIterator<T>;
|
||||
/**
|
||||
* Prefetch the first `bufferSize` items in this stream.
|
||||
*
|
||||
* Note this prefetches Promises, but makes no guarantees about when those
|
||||
* Promises resolve.
|
||||
*
|
||||
* @param bufferSize: An integer specifying the number of elements to be
|
||||
* prefetched.
|
||||
*/
|
||||
prefetch(bufferSize: number): LazyIterator<T>;
|
||||
/**
|
||||
* Randomly shuffles the elements of this stream.
|
||||
*
|
||||
* @param bufferSize: An integer specifying the number of elements from
|
||||
* this stream from which the new stream will sample.
|
||||
* @param seed: (Optional.) An integer specifying the random seed that
|
||||
* will be used to create the distribution.
|
||||
*/
|
||||
shuffle(windowSize: number, seed?: string): LazyIterator<T>;
|
||||
/**
|
||||
* Force an iterator to execute serially: each next() call will await the
|
||||
* prior one, so that they cannot execute concurrently.
|
||||
*/
|
||||
serial(): LazyIterator<T>;
|
||||
}
|
||||
/**
|
||||
* A base class for transforming streams that operate by maintaining an
|
||||
* output queue of elements that are ready to return via next(). This is
|
||||
* commonly required when the transformation is 1-to-many: A call to next()
|
||||
* may trigger a call to the underlying stream, which will produce many
|
||||
* mapped elements of this stream-- of which we need to return only one, so
|
||||
* we have to queue the rest.
|
||||
*/
|
||||
export declare abstract class OneToManyIterator<T> extends LazyIterator<T> {
|
||||
private lastRead;
|
||||
protected outputQueue: RingBuffer<T>;
|
||||
constructor();
|
||||
next(): Promise<IteratorResult<T>>;
|
||||
/**
|
||||
* Read one or more chunks from upstream and process them, possibly
|
||||
* reading or writing a carryover, and adding processed items to the
|
||||
* output queue. Note it's possible that no items are added to the queue
|
||||
* on a given pump() call, even if the upstream stream is not closed
|
||||
* (e.g., because items are filtered).
|
||||
*
|
||||
* @return `true` if any action was taken, i.e. fetching items from the
|
||||
* upstream source OR adding items to the output queue. `false` if the
|
||||
* upstream source is exhausted AND nothing was added to the queue
|
||||
* (i.e., any remaining carryover).
|
||||
*/
|
||||
protected abstract pump(): Promise<boolean>;
|
||||
serialNext(): Promise<IteratorResult<T>>;
|
||||
}
|
||||
/**
|
||||
* Provides a `LazyIterator` that concatenates a stream of underlying
|
||||
* streams.
|
||||
*
|
||||
* Doing this in a concurrency-safe way requires some trickery. In
|
||||
* particular, we want this stream to return the elements from the
|
||||
* underlying streams in the correct order according to when next() was
|
||||
* called, even if the resulting Promises resolve in a different order.
|
||||
*/
|
||||
export declare class ChainedIterator<T> extends LazyIterator<T> {
|
||||
private readonly baseErrorHandler?;
|
||||
private lastRead;
|
||||
private iterator;
|
||||
private moreIterators;
|
||||
constructor(iterators: LazyIterator<LazyIterator<T>>, baseErrorHandler?: (e: Error) => boolean);
|
||||
summary(): string;
|
||||
next(): Promise<IteratorResult<T>>;
|
||||
private readFromChain;
|
||||
}
|
||||
export declare enum ZipMismatchMode {
|
||||
FAIL = 0,
|
||||
SHORTEST = 1,
|
||||
LONGEST = 2
|
||||
}
|
||||
/**
|
||||
* A stream that prefetches a given number of items from an upstream source,
|
||||
* returning them in FIFO order.
|
||||
*
|
||||
* Note this prefetches Promises, but makes no guarantees about when those
|
||||
* Promises resolve.
|
||||
*/
|
||||
export declare class PrefetchIterator<T> extends LazyIterator<T> {
|
||||
protected upstream: LazyIterator<T>;
|
||||
protected bufferSize: number;
|
||||
protected buffer: RingBuffer<Promise<IteratorResult<T>>>;
|
||||
constructor(upstream: LazyIterator<T>, bufferSize: number);
|
||||
summary(): string;
|
||||
/**
|
||||
* Refill the prefetch buffer. Returns only after the buffer is full, or
|
||||
* the upstream source is exhausted.
|
||||
*/
|
||||
protected refill(): void;
|
||||
next(): Promise<IteratorResult<T>>;
|
||||
}
|
||||
/**
|
||||
* A stream that performs a sliding-window random shuffle on an upstream
|
||||
* source. This is like a `PrefetchIterator` except that the items are
|
||||
* returned in randomized order. Mixing naturally improves as the buffer
|
||||
* size increases.
|
||||
*/
|
||||
export declare class ShuffleIterator<T> extends PrefetchIterator<T> {
|
||||
protected upstream: LazyIterator<T>;
|
||||
protected windowSize: number;
|
||||
private readonly random;
|
||||
private lastRead;
|
||||
private upstreamExhausted;
|
||||
constructor(upstream: LazyIterator<T>, windowSize: number, seed?: string);
|
||||
next(): Promise<IteratorResult<T>>;
|
||||
private randomInt;
|
||||
protected chooseIndex(): number;
|
||||
serialNext(): Promise<IteratorResult<T>>;
|
||||
}
|
||||
Generated
Vendored
-1006
File diff suppressed because it is too large.
Load diff
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"lazy_iterator.js","sourceRoot":"","sources":["../../src/iterators/lazy_iterator.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"lazy_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/lazy_iterator_test.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-58
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { Tensor, Tensor2D, Tensor3D, TensorContainer } from '@tensorflow/tfjs-core';
|
||||
import { MicrophoneConfig } from '../types';
|
||||
import { LazyIterator } from './lazy_iterator';
|
||||
/**
|
||||
* Provide a stream of tensors from microphone audio stream. The tensors are
|
||||
* representing audio data as frequency-domain spectrogram generated with
|
||||
* browser's native FFT. Tensors representing time-domain waveform is available
|
||||
* based on configuration. Only works in browser environment.
|
||||
*/
|
||||
export declare class MicrophoneIterator extends LazyIterator<TensorContainer> {
|
||||
protected readonly microphoneConfig: MicrophoneConfig;
|
||||
private isClosed;
|
||||
private stream;
|
||||
private readonly fftSize;
|
||||
private readonly columnTruncateLength;
|
||||
private freqData;
|
||||
private timeData;
|
||||
private readonly numFrames;
|
||||
private analyser;
|
||||
private audioContext;
|
||||
private sampleRateHz;
|
||||
private readonly audioTrackConstraints;
|
||||
private readonly smoothingTimeConstant;
|
||||
private readonly includeSpectrogram;
|
||||
private readonly includeWaveform;
|
||||
private constructor();
|
||||
summary(): string;
|
||||
static create(microphoneConfig?: MicrophoneConfig): Promise<MicrophoneIterator>;
|
||||
start(): Promise<void>;
|
||||
next(): Promise<IteratorResult<TensorContainer>>;
|
||||
capture(): Promise<{
|
||||
spectrogram: Tensor3D;
|
||||
waveform: Tensor2D;
|
||||
}>;
|
||||
private getAudioData;
|
||||
stop(): void;
|
||||
toArray(): Promise<Tensor[]>;
|
||||
getSampleRate(): number;
|
||||
private flattenQueue;
|
||||
private getTensorFromAudioDataArray;
|
||||
}
|
||||
Generated
Vendored
-187
@@ -1,187 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { env, tensor, util } from '@tensorflow/tfjs-core';
|
||||
import { LazyIterator } from './lazy_iterator';
|
||||
/**
|
||||
* Provide a stream of tensors from microphone audio stream. The tensors are
|
||||
* representing audio data as frequency-domain spectrogram generated with
|
||||
* browser's native FFT. Tensors representing time-domain waveform is available
|
||||
* based on configuration. Only works in browser environment.
|
||||
*/
|
||||
export class MicrophoneIterator extends LazyIterator {
|
||||
constructor(microphoneConfig) {
|
||||
super();
|
||||
this.microphoneConfig = microphoneConfig;
|
||||
this.isClosed = false;
|
||||
this.fftSize = microphoneConfig.fftSize || 1024;
|
||||
const fftSizeLog2 = Math.log2(this.fftSize);
|
||||
if (this.fftSize < 0 || fftSizeLog2 < 4 || fftSizeLog2 > 14 ||
|
||||
!Number.isInteger(fftSizeLog2)) {
|
||||
throw new Error(`Invalid fftSize: it must be a power of 2 between ` +
|
||||
`2 to 4 and 2 to 14, but got ${this.fftSize}`);
|
||||
}
|
||||
this.numFrames = microphoneConfig.numFramesPerSpectrogram || 43;
|
||||
this.sampleRateHz = microphoneConfig.sampleRateHz;
|
||||
this.columnTruncateLength =
|
||||
microphoneConfig.columnTruncateLength || this.fftSize;
|
||||
this.audioTrackConstraints = microphoneConfig.audioTrackConstraints;
|
||||
this.smoothingTimeConstant = microphoneConfig.smoothingTimeConstant || 0;
|
||||
this.includeSpectrogram =
|
||||
microphoneConfig.includeSpectrogram === false ? false : true;
|
||||
this.includeWaveform =
|
||||
microphoneConfig.includeWaveform === true ? true : false;
|
||||
if (!this.includeSpectrogram && !this.includeWaveform) {
|
||||
throw new Error('Both includeSpectrogram and includeWaveform are false. ' +
|
||||
'At least one type of data should be returned.');
|
||||
}
|
||||
}
|
||||
summary() {
|
||||
return `microphone`;
|
||||
}
|
||||
// Construct a MicrophoneIterator and start the audio stream.
|
||||
static async create(microphoneConfig = {}) {
|
||||
if (env().get('IS_NODE')) {
|
||||
throw new Error('microphone API is only supported in browser environment.');
|
||||
}
|
||||
const microphoneIterator = new MicrophoneIterator(microphoneConfig);
|
||||
// Call async function start() to initialize the audio stream.
|
||||
await microphoneIterator.start();
|
||||
return microphoneIterator;
|
||||
}
|
||||
// Start the audio stream and FFT.
|
||||
async start() {
|
||||
try {
|
||||
this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: this.audioTrackConstraints == null ? true :
|
||||
this.audioTrackConstraints,
|
||||
video: false
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error thrown while initializing video stream: ${e.message}`);
|
||||
}
|
||||
if (!this.stream) {
|
||||
throw new Error('Could not obtain audio from microphone.');
|
||||
}
|
||||
const ctxConstructor =
|
||||
// tslint:disable-next-line:no-any
|
||||
window.AudioContext || window.webkitAudioContext;
|
||||
this.audioContext = new ctxConstructor();
|
||||
if (!this.sampleRateHz) {
|
||||
// If sample rate is not provided, use the available sample rate on
|
||||
// device.
|
||||
this.sampleRateHz = this.audioContext.sampleRate;
|
||||
}
|
||||
else if (this.audioContext.sampleRate !== this.sampleRateHz) {
|
||||
throw new Error(`Mismatch in sampling rate: ` +
|
||||
`Expected: ${this.sampleRateHz}; ` +
|
||||
`Actual: ${this.audioContext.sampleRate}`);
|
||||
}
|
||||
const streamSource = this.audioContext.createMediaStreamSource(this.stream);
|
||||
this.analyser = this.audioContext.createAnalyser();
|
||||
this.analyser.fftSize = this.fftSize * 2;
|
||||
this.analyser.smoothingTimeConstant = this.smoothingTimeConstant;
|
||||
streamSource.connect(this.analyser);
|
||||
this.freqData = new Float32Array(this.fftSize);
|
||||
this.timeData = new Float32Array(this.fftSize);
|
||||
return;
|
||||
}
|
||||
async next() {
|
||||
if (this.isClosed) {
|
||||
return { value: null, done: true };
|
||||
}
|
||||
let spectrogramTensor;
|
||||
let waveformTensor;
|
||||
const audioDataQueue = await this.getAudioData();
|
||||
if (this.includeSpectrogram) {
|
||||
const freqData = this.flattenQueue(audioDataQueue.freqDataQueue);
|
||||
spectrogramTensor = this.getTensorFromAudioDataArray(freqData, [this.numFrames, this.columnTruncateLength, 1]);
|
||||
}
|
||||
if (this.includeWaveform) {
|
||||
const timeData = this.flattenQueue(audioDataQueue.timeDataQueue);
|
||||
waveformTensor = this.getTensorFromAudioDataArray(timeData, [this.numFrames * this.fftSize, 1]);
|
||||
}
|
||||
return {
|
||||
value: { 'spectrogram': spectrogramTensor, 'waveform': waveformTensor },
|
||||
done: false
|
||||
};
|
||||
}
|
||||
// Capture one result from the audio stream, and extract the value from
|
||||
// iterator.next() result.
|
||||
async capture() {
|
||||
return (await this.next()).value;
|
||||
}
|
||||
async getAudioData() {
|
||||
const freqDataQueue = [];
|
||||
const timeDataQueue = [];
|
||||
let currentFrames = 0;
|
||||
return new Promise(resolve => {
|
||||
const intervalID = setInterval(() => {
|
||||
if (this.includeSpectrogram) {
|
||||
this.analyser.getFloatFrequencyData(this.freqData);
|
||||
// If the audio stream is initializing, return empty queue.
|
||||
if (this.freqData[0] === -Infinity) {
|
||||
resolve({ freqDataQueue, timeDataQueue });
|
||||
}
|
||||
freqDataQueue.push(this.freqData.slice(0, this.columnTruncateLength));
|
||||
}
|
||||
if (this.includeWaveform) {
|
||||
this.analyser.getFloatTimeDomainData(this.timeData);
|
||||
timeDataQueue.push(this.timeData.slice());
|
||||
}
|
||||
// Clean interval and return when all frames have been collected
|
||||
if (++currentFrames === this.numFrames) {
|
||||
clearInterval(intervalID);
|
||||
resolve({ freqDataQueue, timeDataQueue });
|
||||
}
|
||||
}, this.fftSize / this.sampleRateHz * 1e3);
|
||||
});
|
||||
}
|
||||
// Stop the audio stream and pause the iterator.
|
||||
stop() {
|
||||
if (!this.isClosed) {
|
||||
this.isClosed = true;
|
||||
this.analyser.disconnect();
|
||||
this.audioContext.close();
|
||||
if (this.stream != null && this.stream.getTracks().length > 0) {
|
||||
this.stream.getTracks()[0].stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Override toArray() function to prevent collecting.
|
||||
toArray() {
|
||||
throw new Error('Can not convert infinite audio stream to array.');
|
||||
}
|
||||
// Return audio sampling rate in Hz
|
||||
getSampleRate() {
|
||||
return this.sampleRateHz;
|
||||
}
|
||||
flattenQueue(queue) {
|
||||
const frameSize = queue[0].length;
|
||||
const freqData = new Float32Array(queue.length * frameSize);
|
||||
queue.forEach((data, i) => freqData.set(data, i * frameSize));
|
||||
return freqData;
|
||||
}
|
||||
getTensorFromAudioDataArray(freqData, shape) {
|
||||
const vals = new Float32Array(util.sizeFromShape(shape));
|
||||
// If the data is less than the output shape, the rest is padded with zeros.
|
||||
vals.set(freqData, vals.length - freqData.length);
|
||||
return tensor(vals, shape);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=microphone_iterator.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"microphone_iterator.js","sourceRoot":"","sources":["../../src/iterators/microphone_iterator.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"microphone_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/microphone_iterator_test.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"prefetch_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/prefetch_iterator_test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,gCAAgC,EAAC,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AAEzD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,gBAAgB,GAClB,IAAI,gBAAgB,CAAC,IAAI,mBAAmB,EAAE,EAAE,GAAG,CAAC,CAAC;QACzD,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;YAC5B,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACvB;QAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EACjE,KAAK,IAAI,EAAE;QACT,MAAM,YAAY,GAAG,gCAAgC,CACjD,GAAG,EAAE,CAAC,CAAC,EAAC,KAAK,EAAE,IAAI,mBAAmB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEhE,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAEjE,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;gBAC5B,cAAc,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aACjC;SACF;QAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEN,EAAE,CAAC,iEAAiE,EACjE,KAAK,IAAI,EAAE;QACT,MAAM,YAAY,GAAG,gCAAgC,CACjD,GAAG,EAAE,CAAC,CAAC,EAAC,KAAK,EAAE,IAAI,mBAAmB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEhE,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;gBAC5B,cAAc,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aACjC;SACF;QAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACR,CAAC,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {iteratorFromConcatenatedFunction} from './lazy_iterator';\nimport {PrefetchIterator} from './lazy_iterator';\nimport {TestIntegerIterator} from './lazy_iterator_test';\n\ndescribe('PrefetchIterator', () => {\n it('fetches a stream completely (stream size < buffer size)', async () => {\n const prefetchIterator =\n new PrefetchIterator(new TestIntegerIterator(), 500);\n const expectedResult: number[] = [];\n for (let j = 0; j < 100; j++) {\n expectedResult[j] = j;\n }\n\n const result = await prefetchIterator.toArray();\n expect(result).toEqual(expectedResult);\n });\n\n it('fetches a chained stream completely (stream size < buffer size)',\n async () => {\n const baseIterator = iteratorFromConcatenatedFunction(\n () => ({value: new TestIntegerIterator(), done: false}), 3);\n\n const prefetchIterator = new PrefetchIterator(baseIterator, 500);\n\n const expectedResult: number[] = [];\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 100; j++) {\n expectedResult[i * 100 + j] = j;\n }\n }\n\n const result = await prefetchIterator.toArray();\n expect(result).toEqual(expectedResult);\n });\n\n it('fetches a chained stream completely (stream size > buffer size)',\n async () => {\n const baseIterator = iteratorFromConcatenatedFunction(\n () => ({value: new TestIntegerIterator(), done: false}), 3);\n\n const prefetchIterator = new PrefetchIterator(baseIterator, 122);\n const expectedResult: number[] = [];\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 100; j++) {\n expectedResult[i * 100 + j] = j;\n }\n }\n\n const result = await prefetchIterator.toArray();\n expect(result).toEqual(expectedResult);\n });\n});\n"]}
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"shuffle_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/shuffle_iterator_test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,eAAe,EAAE,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAC,gCAAgC,EAAC,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AAEzD,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,YAAY,GAAG,IAAI,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;QACjE,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAChE,MAAM,iBAAiB,GAAa,EAAE,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC,EAAE,EAAE;gBAC3C,iBAAiB,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aACnD;SACF;QACD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,KAAK,CAAS,kBAAkB,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACnB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC,EAAE,EAAE;YAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SAC9B;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,YAAY,GAAG,IAAI,eAAe,CACpC,iBAAiB,CAAC,CAAC,IAAI,mBAAmB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAChE,MAAM,iBAAiB,GAAa,EAAE,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;gBAC5C,iBAAiB,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aACpD;SACF;QACD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,KAAK,CAAS,mBAAmB,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACnB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SAC9B;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,YAAY,GAAG,gCAAgC,CACjD,GAAG,EAAE,CAAC,CACF,EAAC,KAAK,EAAE,IAAI,mBAAmB,CAAC,mBAAmB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC,EACvE,CAAC,CAAC,CAAC;QACP,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAChE,MAAM,iBAAiB,GAAa,EAAE,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;gBAC5C,iBAAiB,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aACpD;SACF;QACD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,KAAK,CAAS,mBAAmB,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACnB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SAC9B;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {ChainedIterator, iteratorFromItems} from './lazy_iterator';\nimport {iteratorFromConcatenatedFunction} from './lazy_iterator';\nimport {ShuffleIterator} from './lazy_iterator';\nimport {TestIntegerIterator} from './lazy_iterator_test';\n\nconst LONG_STREAM_LENGTH = 100;\nconst SHORT_STREAM_LENGTH = 15;\n\ndescribe('ShuffleIterator', () => {\n it('shuffles a stream without replacement', async () => {\n const baseIterator = new TestIntegerIterator(LONG_STREAM_LENGTH);\n const shuffleIterator = new ShuffleIterator(baseIterator, 1000);\n const notExpectedResult: number[] = [];\n for (let i = 0; i < 1; i++) {\n for (let j = 0; j < LONG_STREAM_LENGTH; j++) {\n nLine truncated
|
||||
Generated
Vendored
-39
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { LazyIterator } from './lazy_iterator';
|
||||
export declare abstract class StringIterator extends LazyIterator<string> {
|
||||
/**
|
||||
* Splits a string stream on a given separator.
|
||||
*
|
||||
* It is assumed that the incoming chunk boundaries have no semantic meaning,
|
||||
* so conceptually the incoming stream is treated simply as the concatenation
|
||||
* of its elements.
|
||||
*
|
||||
* The outgoing stream provides chunks corresponding to the results of the
|
||||
* standard string split() operation (even if such a chunk spanned incoming
|
||||
* chunks). The separators are not included.
|
||||
*
|
||||
* A typical usage is to split a text file (represented as a stream with
|
||||
* arbitrary chunk boundaries) into lines.
|
||||
*
|
||||
* @param upstream A readable stream of strings that can be treated as
|
||||
* concatenated.
|
||||
* @param separator A character to split on.
|
||||
*/
|
||||
split(separator: string): StringIterator;
|
||||
}
|
||||
Generated
Vendored
-99
@@ -1,99 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { LazyIterator, OneToManyIterator } from './lazy_iterator';
|
||||
export class StringIterator extends LazyIterator {
|
||||
/**
|
||||
* Splits a string stream on a given separator.
|
||||
*
|
||||
* It is assumed that the incoming chunk boundaries have no semantic meaning,
|
||||
* so conceptually the incoming stream is treated simply as the concatenation
|
||||
* of its elements.
|
||||
*
|
||||
* The outgoing stream provides chunks corresponding to the results of the
|
||||
* standard string split() operation (even if such a chunk spanned incoming
|
||||
* chunks). The separators are not included.
|
||||
*
|
||||
* A typical usage is to split a text file (represented as a stream with
|
||||
* arbitrary chunk boundaries) into lines.
|
||||
*
|
||||
* @param upstream A readable stream of strings that can be treated as
|
||||
* concatenated.
|
||||
* @param separator A character to split on.
|
||||
*/
|
||||
split(separator) {
|
||||
return new SplitIterator(this, separator);
|
||||
}
|
||||
}
|
||||
// ============================================================================
|
||||
// The following private classes serve to implement the chainable methods
|
||||
// on StringIterator. Unfortunately they can't be placed in separate files, due
|
||||
// to resulting trouble with circular imports.
|
||||
// ============================================================================
|
||||
// We wanted multiple inheritance, e.g.
|
||||
// class SplitIterator extends QueueIterator<string>, StringIterator
|
||||
// but the TypeScript mixin approach is a bit hacky, so we take this adapter
|
||||
// approach instead.
|
||||
class SplitIterator extends StringIterator {
|
||||
constructor(upstream, separator) {
|
||||
super();
|
||||
this.upstream = upstream;
|
||||
this.impl = new SplitIteratorImpl(upstream, separator);
|
||||
}
|
||||
summary() {
|
||||
return this.impl.summary();
|
||||
}
|
||||
async next() {
|
||||
return this.impl.next();
|
||||
}
|
||||
}
|
||||
class SplitIteratorImpl extends OneToManyIterator {
|
||||
constructor(upstream, separator) {
|
||||
super();
|
||||
this.upstream = upstream;
|
||||
this.separator = separator;
|
||||
// A partial string at the end of an upstream chunk
|
||||
this.carryover = '';
|
||||
}
|
||||
summary() {
|
||||
return `${this.upstream.summary()} -> Split('${this.separator}')`;
|
||||
}
|
||||
async pump() {
|
||||
const chunkResult = await this.upstream.next();
|
||||
if (chunkResult.done) {
|
||||
if (this.carryover === '') {
|
||||
return false;
|
||||
}
|
||||
// Pretend that the pump succeeded in order to emit the small last batch.
|
||||
// The next pump() call will actually fail.
|
||||
this.outputQueue.push(this.carryover);
|
||||
this.carryover = '';
|
||||
return true;
|
||||
}
|
||||
const lines = chunkResult.value.split(this.separator);
|
||||
// Note the behavior: " ab ".split(' ') === ['', 'ab', '']
|
||||
// Thus the carryover may be '' if the separator falls on a chunk
|
||||
// boundary; this produces the correct result.
|
||||
lines[0] = this.carryover + lines[0];
|
||||
for (const line of lines.slice(0, -1)) {
|
||||
this.outputQueue.push(line);
|
||||
}
|
||||
this.carryover = lines[lines.length - 1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=string_iterator.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"string_iterator.js","sourceRoot":"","sources":["../../src/iterators/string_iterator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAEhE,MAAM,OAAgB,cAAe,SAAQ,YAAoB;IAC/D;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,SAAiB;QACrB,OAAO,IAAI,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;CACF;AAED,+EAA+E;AAC/E,yEAAyE;AACzE,gFAAgF;AAChF,8CAA8C;AAC9C,+EAA+E;AAE/E,uCAAuC;AACvC,sEAAsE;AACtE,4EAA4E;AAC5E,oBAAoB;AAEpB,MAAM,aAAc,SAAQ,cAAc;IAGxC,YAAsB,QAA8B,EAAE,SAAiB;QACrE,KAAK,EAAE,CAAC;QADY,aAAQ,GAAR,QAAQ,CAAsB;QAElD,IAAI,CAAC,IAAI,GAAG,IAAI,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACzD,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,iBAAkB,SAAQ,iBAAyB;IAIvD,YACc,QAA8B,EAAY,SAAiB;QACvE,KAAK,EAAE,CAAC;QADI,aAAQ,GAAR,QAAQ,CAAsB;QAAY,cAAS,GAAT,SAAS,CAAQ;QAJzE,mDAAmD;QACnD,cAAS,GAAG,EAAE,CAAC;IAKf,CAAC;IAED,OAAO;QACL,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,IAAI,CAAC,SAAS,IAAI,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,WAAW,CAAC,IAAI,EAAE;YACpB,IAAI,IAAI,CAAC,SAAS,KAAK,EAAE,EAAE;gBACzB,OAAO,KAAK,CAAC;aACd;YAED,yEAAyE;YACzE,2CAA2C;YAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;SACb;QACD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtD,0DAA0D;QAC1D,iEAAiE;QACjE,8CAA8C;QAE9C,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;YACrC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC7B;QACD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEzC,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {LazyIterator, OneToManyIterator} from './lazy_iterator';\n\nexport abstract class StringIterator extends LazyIterator<string> {\n /**\n * Splits a string stream on a given separator.\n *\n * It is assumed that the incoming chunk boundaries have no semantic meaning,\n * so conceptually the incoming stream is treated simply as the concatenation\n * of its elements.\n *\n * The outgoing stream provides chunks corresponding to the results of the\n * standard string split() operation (even if such a chunk spanned incoming\n * chunks). The separators are not included.\n *\n * A typical usage is to split a text file (represented as a stream with\n * arbitrary chunk boundaries) into lines.\n *\n * @param upstream A readable stream of strings that can be treated as\n * concatenated.\n * @param separator A character to split on.\n */\n split(separator: string): StringIterator {\n return new SplitIterator(this, separator);\n }\n}\n\n// ============================================================================\n// The following private classes serve to implement the chainable methods\n// on StringIterator. Unfortunately they can't be placed in separate files, due\n// to resulting trouble with circular imports.\n// ============================================================================\n\n// We wanted multiple inheritance, e.g.\n// class SplitIterator extends QueueIterator<string>, StringIterator\n// but the TypeScript mixin approach is a bit hacky, so we take this adapter\n// approach instead.\n\nclass SplitIterator extends StringIterator {\n private impl: SplitIteratorImpl;\n\n constructor(protected upstream: LazyIterator<string>, separator: string) {\n super();\n this.impl = new SplitIteratorImpl(upstream, separator);\n }\n\n summary() {\n return this.impl.summary();\n }\n\n async next() {\n return this.impl.next();\n }\n}\n\nclass SplitIteratorImpl extends OneToManyIterator<string> {\n // A partial string at the end of an upstream chunk\n carryover = '';\n\n constructor(\n protected upstream: LazyIterator<string>, protected separator: string) {\n super();\n }\n\n summary() {\n return `${this.upstream.summary()} -> Split('${this.separator}')`;\n }\n\n async pump(): Promise<boolean> {\n const chunkResult = await this.upstream.next();\n if (chunkResult.done) {\n if (this.carryLine truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"string_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/string_iterator_test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {env} from '@tensorflow/tfjs-core';\nimport {FileChunkIterator} from './file_chunk_iterator';\n\nconst lorem = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\neiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim\nveniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum\ndolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,\nsunt in culpa qui officia deserunt mollit anim id est laborum.`;\n\nconst testData =\n env().get('IS_BROWSER') ? new Blob([lorem]) : Buffer.from(lorem);\n\ndescribe('StringIterator.split()', () => {\n it('Correctly splits lines', async () => {\n const byteIterator = new FileChunkIterator(testData, {chunkSize: 50});\n const utf8Iterator = byteIterator.decodeUTF8();\n const lineIterator = utf8Iterator.split('\\n');\n const expected = lorem.split('\\n');\n\n const result = await lineIterator.toArrayForTest();\n expect(result.length).toEqual(6);\n const totalCharacters = result.map(x => x.length).reduce((a, b) => a + b);\n expect(totalCharacters).toEqual(440);\n expect(result).toEqual(expected);\n expect(result.join('\\n')).toEqual(lorem);\n });\n\n it('Correctly splits strings even when separators fall on chunk boundaries',\n async () => {\n const byteIterator = new FileChunkIterator(\n env().get('IS_BROWSER') ? new Blob(['ab def hi pq']) :\n Buffer.from('ab def hi pq'),\n {chunkSize: 3});\n // Note the initial chunking will be\n // ['ab ', 'def', ' hi', ' ', ' ', 'pq],\n // so here we are testing for correct behavior when\n // * a separator is the last character in a chunk (the first chunk),\n // * it is the first character (the third chunk), and\Line truncated
|
||||
Generated
Vendored
-26
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { FileChunkIterator, FileChunkIteratorOptions } from './file_chunk_iterator';
|
||||
/**
|
||||
* Provide a stream of chunks from a URL.
|
||||
*
|
||||
* Note this class first downloads the entire file into memory before providing
|
||||
* the first element from the stream. This is because the Fetch API does not
|
||||
* yet reliably provide a reader stream for the response body.
|
||||
*/
|
||||
export declare function urlChunkIterator(url: RequestInfo, options?: FileChunkIteratorOptions): Promise<FileChunkIterator>;
|
||||
Generated
Vendored
-61
@@ -1,61 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { util } from '@tensorflow/tfjs-core';
|
||||
import { FileChunkIterator } from './file_chunk_iterator';
|
||||
/**
|
||||
* Provide a stream of chunks from a URL.
|
||||
*
|
||||
* Note this class first downloads the entire file into memory before providing
|
||||
* the first element from the stream. This is because the Fetch API does not
|
||||
* yet reliably provide a reader stream for the response body.
|
||||
*/
|
||||
export async function urlChunkIterator(url, options = {}) {
|
||||
let urlString;
|
||||
let requestInit;
|
||||
if ((typeof url) === 'string') {
|
||||
urlString = url;
|
||||
}
|
||||
else {
|
||||
urlString = url.url;
|
||||
requestInit = getRequestInitFromRequest(url);
|
||||
}
|
||||
const response = await util.fetch(urlString, requestInit);
|
||||
if (response.ok) {
|
||||
const uint8Array = new Uint8Array(await response.arrayBuffer());
|
||||
return new FileChunkIterator(uint8Array, options);
|
||||
}
|
||||
else {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
}
|
||||
// Generate RequestInit from Request to match tf.util.fetch signature.
|
||||
const getRequestInitFromRequest = (request) => {
|
||||
const init = {
|
||||
method: request.method,
|
||||
headers: request.headers,
|
||||
body: request.body,
|
||||
mode: request.mode,
|
||||
credentials: request.credentials,
|
||||
cache: request.cache,
|
||||
redirect: request.redirect,
|
||||
referrer: request.referrer,
|
||||
integrity: request.integrity,
|
||||
};
|
||||
return init;
|
||||
};
|
||||
//# sourceMappingURL=url_chunk_iterator.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"url_chunk_iterator.js","sourceRoot":"","sources":["../../src/iterators/url_chunk_iterator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,IAAI,EAAC,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EAAC,iBAAiB,EAA2B,MAAM,uBAAuB,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAClC,GAAgB,EAAE,UAAoC,EAAE;IAC1D,IAAI,SAAS,CAAC;IACd,IAAI,WAAW,CAAC;IAChB,IAAI,CAAC,OAAO,GAAG,CAAC,KAAK,QAAQ,EAAE;QAC7B,SAAS,GAAG,GAAa,CAAC;KAC3B;SAAM;QACL,SAAS,GAAI,GAAe,CAAC,GAAG,CAAC;QACjC,WAAW,GAAG,yBAAyB,CAAC,GAAc,CAAC,CAAC;KACzD;IACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC1D,IAAI,QAAQ,CAAC,EAAE,EAAE;QACf,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;QAChE,OAAO,IAAI,iBAAiB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;KACnD;SAAM;QACL,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;KACtC;AACH,CAAC;AAED,sEAAsE;AACtE,MAAM,yBAAyB,GAAG,CAAC,OAAgB,EAAE,EAAE;IACrD,MAAM,IAAI,GAAG;QACX,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {util} from '@tensorflow/tfjs-core';\nimport {FileChunkIterator, FileChunkIteratorOptions} from './file_chunk_iterator';\n\n/**\n * Provide a stream of chunks from a URL.\n *\n * Note this class first downloads the entire file into memory before providing\n * the first element from the stream. This is because the Fetch API does not\n * yet reliably provide a reader stream for the response body.\n */\nexport async function urlChunkIterator(\n url: RequestInfo, options: FileChunkIteratorOptions = {}) {\n let urlString;\n let requestInit;\n if ((typeof url) === 'string') {\n urlString = url as string;\n } else {\n urlString = (url as Request).url;\n requestInit = getRequestInitFromRequest(url as Request);\n }\n const response = await util.fetch(urlString, requestInit);\n if (response.ok) {\n const uint8Array = new Uint8Array(await response.arrayBuffer());\n return new FileChunkIterator(uint8Array, options);\n } else {\n throw new Error(response.statusText);\n }\n}\n\n// Generate RequestInit from Request to match tf.util.fetch signature.\nconst getRequestInitFromRequest = (request: Request) => {\n const init = {\n method: request.method,\n headers: request.headers,\n body: request.body,\n mode: request.mode,\n credentials: request.credentials,\n cache: request.cache,\n redirect: request.redirect,\n referrer: request.referrer,\n integrity: request.integrity,\n };\n return init;\n};\n"]}
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"url_chunk_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/url_chunk_iterator_test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {util} from '@tensorflow/tfjs-core';\nimport {urlChunkIterator} from './url_chunk_iterator';\n\nconst TEST_STRING = 'abcdefghijklmnopqrstuvwxyz';\n\ndescribe('URLChunkIterator', () => {\n beforeAll(() => {\n spyOn(util, 'fetch').and.callFake((path: string) => {\n const buf = new ArrayBuffer(TEST_STRING.length);\n const bufView = new Uint8Array(buf);\n for (let i = 0, strLen = TEST_STRING.length; i < strLen; i++) {\n bufView[i] = TEST_STRING.charCodeAt(i);\n }\n\n return {\n ok: true,\n arrayBuffer: async () => {\n return buf;\n }\n };\n });\n });\n\n it('Reads the entire file and then closes the stream', async () => {\n const readIterator = await urlChunkIterator('', {chunkSize: 10});\n const result = await readIterator.toArrayForTest();\n expect(result.length).toEqual(3);\n const totalBytes = result.map(x => x.length).reduce((a, b) => a + b);\n expect(totalBytes).toEqual(26);\n });\n\n it('Reads chunks in order', async () => {\n const readIterator = await urlChunkIterator('', {chunkSize: 10});\n\n const result = await readIterator.toArrayForTest();\n expect(result[0][0]).toEqual('a'.charCodeAt(0));\n expect(result[1][0]).toEqual('k'.charCodeAt(0));\n expect(result[2][0]).toEqual('u'.charCodeAt(0));\n });\n\n it('Reads chunks of expected sizes', async () => {\n const readIterator = await urlChunkIterator('', {chunkSize: 10});\n\n const result = await readIterator.toArrayForTest();\n expect(result[0].length).toEqual(10);\n expect(result[1].length).toEqual(10);\n expect(result[2].length).toEqual(6);\n });\n});\n"]}
|
||||
Generated
Vendored
-44
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { Tensor3D } from '@tensorflow/tfjs-core';
|
||||
import { WebcamConfig } from '../types';
|
||||
import { LazyIterator } from './lazy_iterator';
|
||||
/**
|
||||
* Provide a stream of image tensors from webcam video stream. Only works in
|
||||
* browser environment.
|
||||
*/
|
||||
export declare class WebcamIterator extends LazyIterator<Tensor3D> {
|
||||
protected readonly webcamVideoElement: HTMLVideoElement;
|
||||
protected readonly webcamConfig: WebcamConfig;
|
||||
private isClosed;
|
||||
private stream;
|
||||
private resize;
|
||||
private cropSize;
|
||||
private cropBox;
|
||||
private cropBoxInd;
|
||||
private constructor();
|
||||
summary(): string;
|
||||
static create(webcamVideoElement?: HTMLVideoElement, webcamConfig?: WebcamConfig): Promise<WebcamIterator>;
|
||||
start(): Promise<void>;
|
||||
next(): Promise<IteratorResult<Tensor3D>>;
|
||||
private needToResize;
|
||||
cropAndResizeFrame(img: Tensor3D): Tensor3D;
|
||||
capture(): Promise<Tensor3D>;
|
||||
stop(): void;
|
||||
toArray(): Promise<Tensor3D[]>;
|
||||
}
|
||||
Generated
Vendored
-192
@@ -1,192 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { browser, cast, env, expandDims, image, reshape, tensor1d, tensor2d, tidy, util } from '@tensorflow/tfjs-core';
|
||||
import { LazyIterator } from './lazy_iterator';
|
||||
/**
|
||||
* Provide a stream of image tensors from webcam video stream. Only works in
|
||||
* browser environment.
|
||||
*/
|
||||
export class WebcamIterator extends LazyIterator {
|
||||
constructor(webcamVideoElement, webcamConfig) {
|
||||
super();
|
||||
this.webcamVideoElement = webcamVideoElement;
|
||||
this.webcamConfig = webcamConfig;
|
||||
this.isClosed = true;
|
||||
this.resize = false;
|
||||
if (this.needToResize()) {
|
||||
this.resize = true;
|
||||
this.cropSize =
|
||||
[this.webcamConfig.resizeHeight, this.webcamConfig.resizeWidth];
|
||||
this.cropBoxInd = tensor1d([0], 'int32');
|
||||
if (this.webcamConfig.centerCrop) {
|
||||
// Calculate the box based on resizing shape.
|
||||
const widthCroppingRatio = this.webcamConfig.resizeWidth * 1.0 / this.webcamVideoElement.width;
|
||||
const heightCroppingRatio = this.webcamConfig.resizeHeight * 1.0 /
|
||||
this.webcamVideoElement.height;
|
||||
const widthCropStart = (1 - widthCroppingRatio) / 2;
|
||||
const heightCropStart = (1 - heightCroppingRatio) / 2;
|
||||
const widthCropEnd = widthCropStart + widthCroppingRatio;
|
||||
const heightCropEnd = heightCroppingRatio + heightCropStart;
|
||||
this.cropBox = tensor2d([heightCropStart, widthCropStart, heightCropEnd, widthCropEnd], [1, 4]);
|
||||
}
|
||||
else {
|
||||
this.cropBox = tensor2d([0, 0, 1, 1], [1, 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
summary() {
|
||||
return `webcam`;
|
||||
}
|
||||
// Construct a WebcamIterator and start it's video stream.
|
||||
static async create(webcamVideoElement, webcamConfig = {}) {
|
||||
if (env().get('IS_NODE')) {
|
||||
throw new Error('tf.data.webcam is only supported in browser environment.');
|
||||
}
|
||||
if (!webcamVideoElement) {
|
||||
// If webcam video element is not provided, create a hidden video element
|
||||
// with provided width and height.
|
||||
webcamVideoElement = document.createElement('video');
|
||||
if (!webcamConfig.resizeWidth || !webcamConfig.resizeHeight) {
|
||||
throw new Error('Please provide webcam video element, or resizeWidth and ' +
|
||||
'resizeHeight to create a hidden video element.');
|
||||
}
|
||||
webcamVideoElement.width = webcamConfig.resizeWidth;
|
||||
webcamVideoElement.height = webcamConfig.resizeHeight;
|
||||
}
|
||||
const webcamIterator = new WebcamIterator(webcamVideoElement, webcamConfig);
|
||||
// Call async function to initialize the video stream.
|
||||
await webcamIterator.start();
|
||||
return webcamIterator;
|
||||
}
|
||||
// Async function to start video stream.
|
||||
async start() {
|
||||
if (this.webcamConfig.facingMode) {
|
||||
util.assert((this.webcamConfig.facingMode === 'user') ||
|
||||
(this.webcamConfig.facingMode === 'environment'), () => `Invalid webcam facing mode: ${this.webcamConfig.facingMode}. ` +
|
||||
`Please provide 'user' or 'environment'`);
|
||||
}
|
||||
try {
|
||||
this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: {
|
||||
deviceId: this.webcamConfig.deviceId,
|
||||
facingMode: this.webcamConfig.facingMode ?
|
||||
this.webcamConfig.facingMode :
|
||||
'user',
|
||||
width: this.webcamVideoElement.width,
|
||||
height: this.webcamVideoElement.height
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
// Modify the error message but leave the stack trace intact
|
||||
e.message = `Error thrown while initializing video stream: ${e.message}`;
|
||||
throw e;
|
||||
}
|
||||
if (!this.stream) {
|
||||
throw new Error('Could not obtain video from webcam.');
|
||||
}
|
||||
// Older browsers may not have srcObject
|
||||
try {
|
||||
this.webcamVideoElement.srcObject = this.stream;
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
this.webcamVideoElement.src = window.URL.createObjectURL(this.stream);
|
||||
}
|
||||
// Start the webcam video stream
|
||||
this.webcamVideoElement.play();
|
||||
this.isClosed = false;
|
||||
return new Promise(resolve => {
|
||||
// Add event listener to make sure the webcam has been fully initialized.
|
||||
this.webcamVideoElement.onloadedmetadata = () => {
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}
|
||||
async next() {
|
||||
if (this.isClosed) {
|
||||
return { value: null, done: true };
|
||||
}
|
||||
let img;
|
||||
try {
|
||||
img = browser.fromPixels(this.webcamVideoElement);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error thrown converting video to pixels: ${JSON.stringify(e)}`);
|
||||
}
|
||||
if (this.resize) {
|
||||
try {
|
||||
return { value: this.cropAndResizeFrame(img), done: false };
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error thrown cropping the video: ${e.message}`);
|
||||
}
|
||||
finally {
|
||||
img.dispose();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return { value: img, done: false };
|
||||
}
|
||||
}
|
||||
needToResize() {
|
||||
// If resizeWidth and resizeHeight are provided, and different from the
|
||||
// width and height of original HTMLVideoElement, then resizing and cropping
|
||||
// is required.
|
||||
if (this.webcamConfig.resizeWidth && this.webcamConfig.resizeHeight &&
|
||||
(this.webcamVideoElement.width !== this.webcamConfig.resizeWidth ||
|
||||
this.webcamVideoElement.height !== this.webcamConfig.resizeHeight)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Cropping and resizing each frame based on config
|
||||
cropAndResizeFrame(img) {
|
||||
return tidy(() => {
|
||||
const expandedImage = expandDims(cast(img, 'float32'), (0));
|
||||
let resizedImage;
|
||||
resizedImage = image.cropAndResize(expandedImage, this.cropBox, this.cropBoxInd, this.cropSize, 'bilinear');
|
||||
// Extract image from batch cropping.
|
||||
const shape = resizedImage.shape;
|
||||
return reshape(resizedImage, shape.slice(1));
|
||||
});
|
||||
}
|
||||
// Capture one frame from the video stream, and extract the value from
|
||||
// iterator.next() result.
|
||||
async capture() {
|
||||
return (await this.next()).value;
|
||||
}
|
||||
// Stop the video stream and pause webcam iterator.
|
||||
stop() {
|
||||
const tracks = this.stream.getTracks();
|
||||
tracks.forEach(track => track.stop());
|
||||
try {
|
||||
this.webcamVideoElement.srcObject = null;
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
this.webcamVideoElement.src = null;
|
||||
}
|
||||
this.isClosed = true;
|
||||
}
|
||||
// Override toArray() function to prevent collecting.
|
||||
toArray() {
|
||||
throw new Error('Can not convert infinite video stream to array.');
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=webcam_iterator.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"webcam_iterator.js","sourceRoot":"","sources":["../../src/iterators/webcam_iterator.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"webcam_iterator_test.js","sourceRoot":"","sources":["../../src/iterators/webcam_iterator_test.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* =============================================================================
|
||||
*/
|
||||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@tensorflow/tfjs-core")):"function"==typeof define&&define.amd?define(["exports","@tensorflow/tfjs-core"],e):e(((t=t||self).tf=t.tf||{},t.tf.data=t.tf.data||{}),t.tf)}(this,(function(t,e){"use strict";var n=function(t,e){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)};function r(t,e){function r(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}function i(t,e,n,r){return new(n||(n=Promise))((function(i,o){function s(t){try{a(r.next(t))}catch(t){o(t)}}function u(t){try{a(r.throw(t))}catch(t){o(t)}}function a(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,u)}a((r=r.apply(t,e||[])).next())}))}function o(t,e){var n,r,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(o){return function(u){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return s.label++,{value:o[1],done:!1};case 5:s.label++,r=o[1],o=[0];continue;case 7:o=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]<i[3])){s.label=o[1];break}if(6===o[0]&&s.label<i[1]){s.label=i[1],i=o;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(o);break}i[2]&&s.ops.pop(),s.trys.pop();continue}o=e.call(t,s)}catch(t){o=[6,t],r=0}finally{n=i=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,u])}}}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function s(t,e){return t(e={exports:{}},e.exports),e.exports}var u=s((function(t){!function(t,e,n){function r(t){var e,n=this,r=(e=4022871197,function(t){t=t.toString();for(var n=0;n<t.length;n++){var r=.02519603282416938*(e+=t.charCodeAt(n));r-=e=r>>>0,e=(r*=e)>>>0,e+=4294967296*(r-=e)}return 2.3283064365386963e-10*(e>>>0)});n.next=function(){var t=2091639*n.s0+2.3283064365386963e-10*n.c;return n.s0=n.s1,n.s1=n.s2,n.s2=t-(n.c=0|t)},n.c=1,n.s0=r(" "),n.s1=r(" "),n.s2=r(" "),n.s0-=r(t),n.s0<0&&(n.s0+=1),n.s1-=r(t),n.s1<0&&(n.s1+=1),n.s2-=r(t),n.s2<0&&(n.s2+=1),r=null}function i(t,e){return e.c=t.c,e.s0=t.s0,e.s1=t.s1,e.s2=t.s2,e}function o(t,e){var n=new r(t),o=e&&e.state,s=n.next;return s.int32=function(){return 4294967296*n.next()|0},s.double=function(){return s()+11102230246251565e-32*(2097152*s()|0)},s.quick=s,o&&("object"==typeof o&&i(o,n),s.state=function(){return i(n,{})}),s}e&&e.exports?e.exports=o:n&&n.amd?n((function(){return o})):this.alea=o}(0,t,!1)})),a=s((function(t){!function(t,e,n){function r(t){var e=this,n="";e.x=0,e.y=0,e.z=0,e.w=0,e.next=function(){var t=e.x^e.x<<11;return e.x=e.y,e.y=e.z,e.z=e.w,e.w^=e.w>>>19^t^t>>>8},t===(0|t)?e.x=t:n+=t;for(var r=0;r<n.length+64;r++)e.x^=0|n.charCodeAt(r),e.next()}function i(t,e){return e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e}function o(t,e){var n=new r(t),o=e&&e.state,s=function(){return(n.next()>>>0)/4294967296};return s.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21)}while(0===t);return t},s.int32=n.next,s.quick=s,o&&("object"==typeof o&&i(o,n),s.state=function(){return i(n,{})}),s}e&&e.exports?e.exports=o:n&&n.amd?n((function(){return o})):this.xor128=o}(0,t,!1)})),c=s((function(t){!function(t,e,n){function r(t){var e=this,n="";e.next=function(){var t=e.x^e.x>>>2;return e.x=e.y,e.y=e.z,e.z=e.w,e.w=e.v,(e.d=e.d+362437|0)+(e.v=e.v^e.v<<4^t^t<<1)|0},e.x=0,e.y=0,e.z=0,e.w=0,e.v=0,t===(0|t)?e.x=t:n+=t;for(var r=0;r<n.length+64;r++)e.x^=0|n.charCodeAt(r),r==n.length&&(e.d=e.x<<10^e.x>>>4),e.next()}function i(t,e){return e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e.v=t.v,e.d=t.d,e}function o(t,e){var n=new r(t),o=e&&e.state,s=function(){return(n.next()>>>0)/4294967296};return s.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21)}while(0===t);return t},s.int32=n.next,s.quick=s,o&&("object"==typeof o&&i(o,n),s.state=function(){return i(n,{})}),s}e&&e.exports?e.exports=o:n&&n.amd?n((function(){return o})):this.xorwow=o}(0,t,!1)})),h=s((function(t){!function(t,e,n){function r(t){var e=this;e.next=function(){var t,n,r=e.x,i=e.i;return t=r[i],n=(t^=t>>>7)^t<<24,n^=(t=r[i+1&7])^t>>>10,n^=(t=r[i+3&7])^t>>>3,n^=(t=r[i+4&7])^t<<7,t=r[i+7&7],n^=(t^=t<<13)^t<<9,r[i]=n,e.i=i+1&7,n},function(t,e){var n,r=[];if(e===(0|e))r[0]=e;else for(e=""+e,n=0;n<e.length;++n)r[7&n]=r[7&n]<<15^e.charCodeAt(n)+r[n+1&7]<<13;for(;r.length<8;)r.push(0);for(n=0;n<8&&0===r[n];++n);for(8==n?r[7]=-Line truncated
|
||||
//# sourceMappingURL=tf-data.min.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"tf-data.min.js","sources":["../node_modules/seedrandom/lib/alea.js","../node_modules/seedrandom/lib/xor128.js","../node_modules/seedrandom/lib/xorwow.js","../node_modules/seedrandom/lib/xorshift7.js","../node_modules/seedrandom/lib/xor4096.js","../node_modules/seedrandom/lib/tychei.js","../node_modules/seedrandom/seedrandom.js","../node_modules/seedrandom/index.js","../src/util/deep_map.ts","../src/util/deep_clone.ts","../src/util/ring_buffer.ts","../src/util/growing_ring_buffer.ts","../src/iterators/lazy_iterator.ts","../src/dataset.ts","../src/datasets/text_line_dataset.ts","../src/datasets/csv_dataset.ts","../src/iterators/microphone_iterator.ts","../src/iterators/webcam_iterator.ts","../src/datasource.ts","../src/iterators/string_iterator.ts","../src/iterators/byte_chunk_iterator.ts","../src/iterators/file_chunk_iterator.ts","../src/iterators/url_chunk_iterator.ts","../src/util/source_util.ts","../src/sources/file_data_source.ts","../src/sources/url_data_source.ts","../src/readers.ts","../src/version.ts"],"sourcesContent":["// A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010\n// http://baagoe.com/en/RandomMusings/javascript/\n// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror\n// Original work is under MIT license -\n\n// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n\n\n(function(global, module, define) {\n\nfunction Alea(seed) {\n var me = this, mash = Mash();\n\n me.next = function() {\n var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32\n me.s0 = me.s1;\n me.s1 = me.s2;\n return me.s2 = t - (me.c = t | 0);\n };\n\n // Apply the seeding algorithm from Baagoe.\n me.c = 1;\n me.s0 = mash(' ');\n me.s1 = mash(' ');\n me.s2 = mash(' ');\n me.s0 -= mash(seed);\n if (me.s0 < 0) { me.s0 += 1; }\n me.s1 -= mash(seed);\n if (me.s1 < 0) { me.s1 += 1; }\n me.s2 -= mash(seed);\n if (me.s2 < 0) { me.s2 += 1; }\n mash = null;\n}\n\nfunction copy(f, t) {\n t.c = f.c;\n t.s0 = f.s0;\n t.s1 = f.s1;\n t.s2 = f.s2;\n return t;\n}\n\nfunction impl(seed, opts) {\n var xg = new Alea(seed),\n state = opts && opts.state,\n prng = xg.next;\n prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }\n prng.double = function() {\n return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53\n };\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nfunction Mash() {\n var n = 0xefc8249d;\n\n var mash = function(data) {\n data = data.toString();\n for (var i = 0; i < data.length; i++) {\n n += data.charCodeAt(i);\n var h = 0.02519603282416938 * n;\n n = h >>> 0;\n h -= n;\n h *= n;\n n = h >>> 0;\n h -= n;\n n += h * 0x100000000; // 2^32\n }\n return (n >>> 0) * 2.3283064365386963e-10; // 2^-32\n };\n\n return mash;\n}\n\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.alea = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","// A Javascript implementaion of the \"xor128\" prng algorithm by\n// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this, strseed = '';\n\n me.x = 0;\n me.y = 0;\n me.z = 0;\n me.w = 0;\n\n // Set up generator function.\n me.next = function() {\n var t = me.x ^ (me.x << 11);\n me.x = me.y;\n me.y = me.z;\n me.z = me.w;\n return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8);\n };\n\n if (seed === (seed | 0)) {\n // Integer seed.\n me.x = seed;\n } elsLine truncated
|
||||
Generated
Vendored
-39
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { DataSource } from '../datasource';
|
||||
import { ByteChunkIterator } from '../iterators/byte_chunk_iterator';
|
||||
import { FileChunkIteratorOptions } from '../iterators/file_chunk_iterator';
|
||||
import { FileElement } from '../types';
|
||||
/**
|
||||
* Represents a file, blob, or Uint8Array readable as a stream of binary data
|
||||
* chunks.
|
||||
*/
|
||||
export declare class FileDataSource extends DataSource {
|
||||
protected input: FileElement | string;
|
||||
protected readonly options: FileChunkIteratorOptions;
|
||||
/**
|
||||
* Create a `FileDataSource`.
|
||||
*
|
||||
* @param input Local file path, or `File`/`Blob`/`Uint8Array` object to
|
||||
* read. Local file only works in node environment.
|
||||
* @param options Options passed to the underlying `FileChunkIterator`s,
|
||||
* such as {chunksize: 1024}.
|
||||
*/
|
||||
constructor(input: FileElement | string, options?: FileChunkIteratorOptions);
|
||||
iterator(): Promise<ByteChunkIterator>;
|
||||
}
|
||||
Generated
Vendored
-51
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { env } from '@tensorflow/tfjs-core';
|
||||
import { DataSource } from '../datasource';
|
||||
import { FileChunkIterator } from '../iterators/file_chunk_iterator';
|
||||
import { isLocalPath } from '../util/source_util';
|
||||
/**
|
||||
* Represents a file, blob, or Uint8Array readable as a stream of binary data
|
||||
* chunks.
|
||||
*/
|
||||
export class FileDataSource extends DataSource {
|
||||
/**
|
||||
* Create a `FileDataSource`.
|
||||
*
|
||||
* @param input Local file path, or `File`/`Blob`/`Uint8Array` object to
|
||||
* read. Local file only works in node environment.
|
||||
* @param options Options passed to the underlying `FileChunkIterator`s,
|
||||
* such as {chunksize: 1024}.
|
||||
*/
|
||||
constructor(input, options = {}) {
|
||||
super();
|
||||
this.input = input;
|
||||
this.options = options;
|
||||
}
|
||||
async iterator() {
|
||||
if (isLocalPath(this.input) && env().get('IS_NODE')) {
|
||||
// tslint:disable-next-line:no-require-imports
|
||||
const fs = require('fs');
|
||||
this.input = fs.readFileSync(this.input.substr(7));
|
||||
}
|
||||
// TODO(kangyizhang): Add LocalFileChunkIterator to split local streaming
|
||||
// with file in browser.
|
||||
return new FileChunkIterator(this.input, this.options);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=file_data_source.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"file_data_source.js","sourceRoot":"","sources":["../../src/sources/file_data_source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,GAAG,EAAC,MAAM,uBAAuB,CAAC;AAC1C,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAC,iBAAiB,EAA2B,MAAM,kCAAkC,CAAC;AAE7F,OAAO,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAEhD;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,UAAU;IAC5C;;;;;;;OAOG;IACH,YACc,KAAyB,EAChB,UAAoC,EAAE;QAC3D,KAAK,EAAE,CAAC;QAFI,UAAK,GAAL,KAAK,CAAoB;QAChB,YAAO,GAAP,OAAO,CAA+B;IAE7D,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YACnD,8CAA8C;YAC9C,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,YAAY,CAAE,IAAI,CAAC,KAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;SAChE;QACD,yEAAyE;QACzE,wBAAwB;QACxB,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAoB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACxE,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {env} from '@tensorflow/tfjs-core';\nimport {DataSource} from '../datasource';\nimport {ByteChunkIterator} from '../iterators/byte_chunk_iterator';\nimport {FileChunkIterator, FileChunkIteratorOptions} from '../iterators/file_chunk_iterator';\nimport {FileElement} from '../types';\nimport {isLocalPath} from '../util/source_util';\n\n/**\n * Represents a file, blob, or Uint8Array readable as a stream of binary data\n * chunks.\n */\nexport class FileDataSource extends DataSource {\n /**\n * Create a `FileDataSource`.\n *\n * @param input Local file path, or `File`/`Blob`/`Uint8Array` object to\n * read. Local file only works in node environment.\n * @param options Options passed to the underlying `FileChunkIterator`s,\n * such as {chunksize: 1024}.\n */\n constructor(\n protected input: FileElement|string,\n protected readonly options: FileChunkIteratorOptions = {}) {\n super();\n }\n\n async iterator(): Promise<ByteChunkIterator> {\n if (isLocalPath(this.input) && env().get('IS_NODE')) {\n // tslint:disable-next-line:no-require-imports\n const fs = require('fs');\n this.input = fs.readFileSync((this.input as string).substr(7));\n }\n // TODO(kangyizhang): Add LocalFileChunkIterator to split local streaming\n // with file in browser.\n return new FileChunkIterator(this.input as FileElement, this.options);\n }\n}\n"]}
|
||||
Generated
Vendored
-33
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { DataSource } from '../datasource';
|
||||
import { ByteChunkIterator } from '../iterators/byte_chunk_iterator';
|
||||
import { FileChunkIteratorOptions } from '../iterators/file_chunk_iterator';
|
||||
export declare class URLDataSource extends DataSource {
|
||||
protected readonly url: RequestInfo;
|
||||
protected readonly fileOptions: FileChunkIteratorOptions;
|
||||
/**
|
||||
* Create a `URLDataSource`.
|
||||
*
|
||||
* @param url A source URL string, or a `Request` object.
|
||||
* @param options Options passed to the underlying `FileChunkIterator`s,
|
||||
* such as {chunksize: 1024}.
|
||||
*/
|
||||
constructor(url: RequestInfo, fileOptions?: FileChunkIteratorOptions);
|
||||
iterator(): Promise<ByteChunkIterator>;
|
||||
}
|
||||
Generated
Vendored
-52
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { DataSource } from '../datasource';
|
||||
import { urlChunkIterator } from '../iterators/url_chunk_iterator';
|
||||
import { isLocalPath } from '../util/source_util';
|
||||
import { FileDataSource } from './file_data_source';
|
||||
/*
|
||||
* Represents a URL readable as a stream of binary data chunks.
|
||||
*/
|
||||
export class URLDataSource extends DataSource {
|
||||
/**
|
||||
* Create a `URLDataSource`.
|
||||
*
|
||||
* @param url A source URL string, or a `Request` object.
|
||||
* @param options Options passed to the underlying `FileChunkIterator`s,
|
||||
* such as {chunksize: 1024}.
|
||||
*/
|
||||
constructor(url, fileOptions = {}) {
|
||||
super();
|
||||
this.url = url;
|
||||
this.fileOptions = fileOptions;
|
||||
}
|
||||
// TODO(soergel): provide appropriate caching options. Currently this
|
||||
// will download the URL anew for each call to iterator(). Since we have
|
||||
// to treat the downloaded file as a blob/buffer anyway, we may as well retain
|
||||
// it-- but that raises GC issues. Also we may want a persistent disk cache.
|
||||
async iterator() {
|
||||
if (isLocalPath(this.url)) {
|
||||
return (new FileDataSource(this.url, this.fileOptions))
|
||||
.iterator();
|
||||
}
|
||||
else {
|
||||
return urlChunkIterator(this.url, this.fileOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=url_data_source.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"url_data_source.js","sourceRoot":"","sources":["../../src/sources/url_data_source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAC,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAElD;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,UAAU;IAC3C;;;;;;OAMG;IACH,YACuB,GAAgB,EAChB,cAAwC,EAAE;QAC/D,KAAK,EAAE,CAAC;QAFa,QAAG,GAAH,GAAG,CAAa;QAChB,gBAAW,GAAX,WAAW,CAA+B;IAEjE,CAAC;IAED,sEAAsE;IACtE,yEAAyE;IACzE,8EAA8E;IAC9E,6EAA6E;IAC7E,KAAK,CAAC,QAAQ;QACZ,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YACzB,OAAO,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,GAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;iBAC5D,QAAQ,EAAE,CAAC;SACjB;aAAM;YACL,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;SACrD;IACH,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {DataSource} from '../datasource';\nimport {ByteChunkIterator} from '../iterators/byte_chunk_iterator';\nimport {FileChunkIteratorOptions} from '../iterators/file_chunk_iterator';\nimport {urlChunkIterator} from '../iterators/url_chunk_iterator';\nimport {isLocalPath} from '../util/source_util';\nimport {FileDataSource} from './file_data_source';\n\n/*\n * Represents a URL readable as a stream of binary data chunks.\n */\nexport class URLDataSource extends DataSource {\n /**\n * Create a `URLDataSource`.\n *\n * @param url A source URL string, or a `Request` object.\n * @param options Options passed to the underlying `FileChunkIterator`s,\n * such as {chunksize: 1024}.\n */\n constructor(\n protected readonly url: RequestInfo,\n protected readonly fileOptions: FileChunkIteratorOptions = {}) {\n super();\n }\n\n // TODO(soergel): provide appropriate caching options. Currently this\n // will download the URL anew for each call to iterator(). Since we have\n // to treat the downloaded file as a blob/buffer anyway, we may as well retain\n // it-- but that raises GC issues. Also we may want a persistent disk cache.\n async iterator(): Promise<ByteChunkIterator> {\n if (isLocalPath(this.url)) {\n return (new FileDataSource(this.url as string, this.fileOptions))\n .iterator();\n } else {\n return urlChunkIterator(this.url, this.fileOptions);\n }\n }\n}\n"]}
|
||||
Generated
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
export declare function deepClone<T>(container: T): T;
|
||||
Generated
Vendored
-35
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import * as tf from '@tensorflow/tfjs-core';
|
||||
import { deepMap, isIterable } from './deep_map';
|
||||
export function deepClone(container) {
|
||||
return deepMap(container, cloneIfTensor);
|
||||
}
|
||||
// tslint:disable-next-line: no-any
|
||||
function cloneIfTensor(item) {
|
||||
if (item instanceof tf.Tensor) {
|
||||
return ({ value: item.clone(), recurse: false });
|
||||
}
|
||||
else if (isIterable(item)) {
|
||||
return { value: null, recurse: true };
|
||||
}
|
||||
else {
|
||||
return { value: item, recurse: false };
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=deep_clone.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"deep_clone.js","sourceRoot":"","sources":["../../src/util/deep_clone.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAC,OAAO,EAAiB,UAAU,EAAC,MAAM,YAAY,CAAC;AAE9D,MAAM,UAAU,SAAS,CAAI,SAAY;IACvC,OAAO,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED,mCAAmC;AACnC,SAAS,aAAa,CAAC,IAAS;IAC9B,IAAI,IAAI,YAAY,EAAE,CAAC,MAAM,EAAE;QAC7B,OAAO,CAAC,EAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC;KAChD;SAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;QAC3B,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC;KACrC;SAAM;QACL,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAC,CAAC;KACtC;AACH,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport * as tf from '@tensorflow/tfjs-core';\nimport {deepMap, DeepMapResult, isIterable} from './deep_map';\n\nexport function deepClone<T>(container: T): T {\n return deepMap(container, cloneIfTensor);\n}\n\n// tslint:disable-next-line: no-any\nfunction cloneIfTensor(item: any): DeepMapResult {\n if (item instanceof tf.Tensor) {\n return ({value: item.clone(), recurse: false});\n } else if (isIterable(item)) {\n return {value: null, recurse: true};\n } else {\n return {value: item, recurse: false};\n }\n}\n"]}
|
||||
Generated
Vendored
-117
@@ -1,117 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
/**
|
||||
* A return value for a mapping function that can be applied via deepMap.
|
||||
*
|
||||
* If recurse is true, the value should be empty, and iteration will continue
|
||||
* into the object or array.
|
||||
*/
|
||||
export declare type DeepMapResult = {
|
||||
value: any;
|
||||
recurse: boolean;
|
||||
};
|
||||
/**
|
||||
* Apply a mapping function to a nested structure in a recursive manner.
|
||||
*
|
||||
* The result of the mapping is an object with the same nested structure (i.e.,
|
||||
* of arrays and dicts) as the input, except that some subtrees are replaced,
|
||||
* according to the results of the mapping function.
|
||||
*
|
||||
* Mappings are memoized. Thus, if the nested structure contains the same
|
||||
* object in multiple positions, the output will contain the same mapped object
|
||||
* in those positions. Cycles are not supported, however.
|
||||
*
|
||||
* @param input: The object to which to apply the mapping function.
|
||||
* @param mapFn: A function that expects a single node of the object tree, and
|
||||
* returns a `DeepMapResult`. The `DeepMapResult` either provides a
|
||||
* replacement value for that node (i.e., replacing the subtree), or indicates
|
||||
* that the node should be processed recursively.
|
||||
*/
|
||||
export declare function deepMap(input: any, mapFn: (x: any) => DeepMapResult): any | any[];
|
||||
/**
|
||||
* Zip nested structures together in a recursive manner.
|
||||
*
|
||||
* This has the effect of transposing or pivoting data, e.g. converting it from
|
||||
* a row-major representation to a column-major representation.
|
||||
*
|
||||
* For example, `deepZip([{a: 1, b: 2}, {a: 3, b: 4}])` returns
|
||||
* `{a: [1, 3], b: [2, 4]}`.
|
||||
*
|
||||
* The inputs should all have the same nested structure (i.e., of arrays and
|
||||
* dicts). The result is a single object with the same nested structure, where
|
||||
* the leaves are arrays collecting the values of the inputs at that location
|
||||
* (or, optionally, the result of a custom function applied to those arrays).
|
||||
*
|
||||
* @param inputs: An array of the objects to zip together.
|
||||
* @param zipFn: (optional) A function that expects an array of elements at a
|
||||
* single node of the object tree, and returns a `DeepMapResult`. The
|
||||
* `DeepMapResult` either provides a result value for that node (i.e.,
|
||||
* representing the subtree), or indicates that the node should be processed
|
||||
* recursively. The default zipFn recurses as far as possible and places
|
||||
* arrays at the leaves.
|
||||
*/
|
||||
export declare function deepZip(inputs: any[], zipFn?: (xs: any[]) => DeepMapResult): any | any[];
|
||||
export declare function zipToList(x: any[]): DeepMapResult;
|
||||
/**
|
||||
* A return value for an async map function for use with deepMapAndAwaitAll.
|
||||
*
|
||||
* If recurse is true, the value should be empty, and iteration will continue
|
||||
* into the object or array.
|
||||
*/
|
||||
export declare type DeepMapAsyncResult = {
|
||||
value: Promise<any>;
|
||||
recurse: boolean;
|
||||
};
|
||||
/**
|
||||
* Apply an async mapping function to a nested structure in a recursive manner.
|
||||
*
|
||||
* This first creates a nested structure of Promises, and then awaits all of
|
||||
* those, resulting in a single Promise for a resolved nested structure.
|
||||
*
|
||||
* The result of the mapping is an object with the same nested structure (i.e.,
|
||||
* of arrays and dicts) as the input, except that some subtrees are replaced,
|
||||
* according to the results of the mapping function.
|
||||
*
|
||||
* Mappings are memoized. Thus, if the nested structure contains the same
|
||||
* object in multiple positions, the output will contain the same mapped object
|
||||
* in those positions. Cycles are not supported, however.
|
||||
*
|
||||
* @param input: The object to which to apply the mapping function.
|
||||
* @param mapFn: A function that expects a single node of the object tree, and
|
||||
* returns a `DeepMapAsyncResult`. The `DeepMapAsyncResult` either provides
|
||||
* a `Promise` for a replacement value for that node (i.e., replacing the
|
||||
* subtree), or indicates that the node should be processed recursively. Note
|
||||
* that the decision whether or not to recurse must be made immediately; only
|
||||
* the mapped value may be promised.
|
||||
*/
|
||||
export declare function deepMapAndAwaitAll(input: any, mapFn: (x: any) => DeepMapAsyncResult): Promise<any | any[]>;
|
||||
/**
|
||||
* Determine whether the argument is iterable.
|
||||
*
|
||||
* @returns true if the argument is an array or any non-Tensor object.
|
||||
*/
|
||||
export declare function isIterable(obj: any): boolean;
|
||||
/**
|
||||
* Determine whether the argument can be converted to Tensor.
|
||||
*
|
||||
* Tensors, primitives, arrays, and TypedArrays all qualify; anything else does
|
||||
* not.
|
||||
*
|
||||
* @returns true if the argument can be converted to Tensor.
|
||||
*/
|
||||
export declare function canTensorify(obj: any): boolean;
|
||||
Generated
Vendored
-229
@@ -1,229 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import * as tf from '@tensorflow/tfjs-core';
|
||||
/**
|
||||
* Apply a mapping function to a nested structure in a recursive manner.
|
||||
*
|
||||
* The result of the mapping is an object with the same nested structure (i.e.,
|
||||
* of arrays and dicts) as the input, except that some subtrees are replaced,
|
||||
* according to the results of the mapping function.
|
||||
*
|
||||
* Mappings are memoized. Thus, if the nested structure contains the same
|
||||
* object in multiple positions, the output will contain the same mapped object
|
||||
* in those positions. Cycles are not supported, however.
|
||||
*
|
||||
* @param input: The object to which to apply the mapping function.
|
||||
* @param mapFn: A function that expects a single node of the object tree, and
|
||||
* returns a `DeepMapResult`. The `DeepMapResult` either provides a
|
||||
* replacement value for that node (i.e., replacing the subtree), or indicates
|
||||
* that the node should be processed recursively.
|
||||
*/
|
||||
export function deepMap(input, mapFn) {
|
||||
return deepMapInternal(input, mapFn);
|
||||
}
|
||||
/**
|
||||
* @param seen: A Map of known object mappings (i.e., memoized results of
|
||||
* `mapFn()`)
|
||||
* @param containedIn: An set containing objects on the reference path currently
|
||||
* being processed (used to detect cycles).
|
||||
*/
|
||||
function deepMapInternal(input, mapFn, seen = new Map(), containedIn = new Set()) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
if (containedIn.has(input)) {
|
||||
throw new Error('Circular references are not supported.');
|
||||
}
|
||||
if (seen.has(input)) {
|
||||
return seen.get(input);
|
||||
}
|
||||
const result = mapFn(input);
|
||||
if (result.recurse && result.value !== null) {
|
||||
throw new Error('A deep map function may not return both a value and recurse=true.');
|
||||
}
|
||||
if (!result.recurse) {
|
||||
seen.set(input, result.value);
|
||||
return result.value;
|
||||
}
|
||||
else if (isIterable(input)) {
|
||||
// tslint:disable-next-line:no-any
|
||||
const mappedIterable = Array.isArray(input) ? [] : {};
|
||||
containedIn.add(input);
|
||||
for (const k in input) {
|
||||
const child = input[k];
|
||||
const childResult = deepMapInternal(child, mapFn, seen, containedIn);
|
||||
mappedIterable[k] = childResult;
|
||||
}
|
||||
containedIn.delete(input);
|
||||
return mappedIterable;
|
||||
}
|
||||
else {
|
||||
throw new Error(`Can't recurse into non-iterable type: ${input}`);
|
||||
}
|
||||
}
|
||||
// TODO(soergel, kangyizhang) Reconsider naming of deepZip() to avoid confusion
|
||||
// with zip()
|
||||
/**
|
||||
* Zip nested structures together in a recursive manner.
|
||||
*
|
||||
* This has the effect of transposing or pivoting data, e.g. converting it from
|
||||
* a row-major representation to a column-major representation.
|
||||
*
|
||||
* For example, `deepZip([{a: 1, b: 2}, {a: 3, b: 4}])` returns
|
||||
* `{a: [1, 3], b: [2, 4]}`.
|
||||
*
|
||||
* The inputs should all have the same nested structure (i.e., of arrays and
|
||||
* dicts). The result is a single object with the same nested structure, where
|
||||
* the leaves are arrays collecting the values of the inputs at that location
|
||||
* (or, optionally, the result of a custom function applied to those arrays).
|
||||
*
|
||||
* @param inputs: An array of the objects to zip together.
|
||||
* @param zipFn: (optional) A function that expects an array of elements at a
|
||||
* single node of the object tree, and returns a `DeepMapResult`. The
|
||||
* `DeepMapResult` either provides a result value for that node (i.e.,
|
||||
* representing the subtree), or indicates that the node should be processed
|
||||
* recursively. The default zipFn recurses as far as possible and places
|
||||
* arrays at the leaves.
|
||||
*/
|
||||
export function deepZip(inputs, zipFn = zipToList) {
|
||||
return deepZipInternal(inputs, zipFn);
|
||||
}
|
||||
/**
|
||||
* @param containedIn: An set containing objects on the reference path currently
|
||||
* being processed (used to detect cycles).
|
||||
*/
|
||||
function deepZipInternal(inputs, zipFn, containedIn = new Set()) {
|
||||
// The recursion follows the structure of input 0; it's assumed that all the
|
||||
// other inputs have the same structure.
|
||||
const input = inputs[0];
|
||||
if (containedIn.has(input)) {
|
||||
throw new Error('Circular references are not supported.');
|
||||
}
|
||||
const result = zipFn(inputs);
|
||||
if (result.recurse && result.value !== null) {
|
||||
throw new Error('A deep zip function may not return both a value and recurse=true.');
|
||||
}
|
||||
if (!result.recurse) {
|
||||
return result.value;
|
||||
}
|
||||
else if (isIterable(input)) {
|
||||
// tslint:disable-next-line:no-any
|
||||
const mappedIterable = Array.isArray(input) ? [] : {};
|
||||
containedIn.add(input);
|
||||
for (const k in input) {
|
||||
const children = inputs.map(x => x[k]);
|
||||
const childResult = deepZipInternal(children, zipFn, containedIn);
|
||||
mappedIterable[k] = childResult;
|
||||
}
|
||||
containedIn.delete(input);
|
||||
return mappedIterable;
|
||||
}
|
||||
else {
|
||||
throw new Error(`Can't recurse into non-iterable type: ${input}`);
|
||||
}
|
||||
}
|
||||
// tslint:disable-next-line:no-any
|
||||
export function zipToList(x) {
|
||||
if (x === null) {
|
||||
return null;
|
||||
}
|
||||
// TODO(soergel): validate array type?
|
||||
if (isIterable(x[0])) {
|
||||
return { value: null, recurse: true };
|
||||
}
|
||||
else {
|
||||
return { value: x, recurse: false };
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Apply an async mapping function to a nested structure in a recursive manner.
|
||||
*
|
||||
* This first creates a nested structure of Promises, and then awaits all of
|
||||
* those, resulting in a single Promise for a resolved nested structure.
|
||||
*
|
||||
* The result of the mapping is an object with the same nested structure (i.e.,
|
||||
* of arrays and dicts) as the input, except that some subtrees are replaced,
|
||||
* according to the results of the mapping function.
|
||||
*
|
||||
* Mappings are memoized. Thus, if the nested structure contains the same
|
||||
* object in multiple positions, the output will contain the same mapped object
|
||||
* in those positions. Cycles are not supported, however.
|
||||
*
|
||||
* @param input: The object to which to apply the mapping function.
|
||||
* @param mapFn: A function that expects a single node of the object tree, and
|
||||
* returns a `DeepMapAsyncResult`. The `DeepMapAsyncResult` either provides
|
||||
* a `Promise` for a replacement value for that node (i.e., replacing the
|
||||
* subtree), or indicates that the node should be processed recursively. Note
|
||||
* that the decision whether or not to recurse must be made immediately; only
|
||||
* the mapped value may be promised.
|
||||
*/
|
||||
export async function deepMapAndAwaitAll(input, mapFn) {
|
||||
const seen = new Map();
|
||||
// First do a normal deepMap, collecting Promises in 'seen' as a side effect.
|
||||
deepMapInternal(input, mapFn, seen);
|
||||
// Replace the Promises in 'seen' in place.
|
||||
// Note TypeScript provides no async map iteration, and regular map iteration
|
||||
// is broken too, so sadly we have to do Array.from() to make it work.
|
||||
// (There's no advantage to Promise.all(), and that would be tricky anyway.)
|
||||
for (const key of Array.from(seen.keys())) {
|
||||
const value = seen.get(key);
|
||||
if (tf.util.isPromise(value)) {
|
||||
const mappedValue = await value;
|
||||
seen.set(key, mappedValue);
|
||||
}
|
||||
}
|
||||
// Normal deepMap again, this time filling in the resolved values.
|
||||
// It's unfortunate that we have to do two passes.
|
||||
// TODO(soergel): test performance and think harder about a fast solution.
|
||||
const result = deepMapInternal(input, mapFn, seen);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Determine whether the argument is iterable.
|
||||
*
|
||||
* @returns true if the argument is an array or any non-Tensor object.
|
||||
*/
|
||||
// tslint:disable-next-line:no-any
|
||||
export function isIterable(obj) {
|
||||
return obj != null && (!ArrayBuffer.isView(obj)) &&
|
||||
(Array.isArray(obj) ||
|
||||
(typeof obj === 'object' && !(obj instanceof tf.Tensor)));
|
||||
}
|
||||
/**
|
||||
* Determine whether the argument can be converted to Tensor.
|
||||
*
|
||||
* Tensors, primitives, arrays, and TypedArrays all qualify; anything else does
|
||||
* not.
|
||||
*
|
||||
* @returns true if the argument can be converted to Tensor.
|
||||
*/
|
||||
// tslint:disable-next-line:no-any
|
||||
export function canTensorify(obj) {
|
||||
return obj == null || isPrimitive(obj) || Array.isArray(obj) ||
|
||||
(typeof obj === 'object' && (obj instanceof tf.Tensor)) ||
|
||||
tf.util.isTypedArray(obj);
|
||||
}
|
||||
/**
|
||||
* Returns true if the given `value` is a primitive type. Otherwise returns
|
||||
* false. This is equivalant to node util.isPrimitive
|
||||
*/
|
||||
function isPrimitive(value) {
|
||||
return (value === null ||
|
||||
(typeof value !== 'object' && typeof value !== 'function'));
|
||||
}
|
||||
//# sourceMappingURL=deep_map.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"deep_map.js","sourceRoot":"","sources":["../../src/util/deep_map.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the LicensLine truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"deep_map_test.js","sourceRoot":"","sources":["../../src/util/deep_map_test.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-32
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { RingBuffer } from './ring_buffer';
|
||||
export declare class GrowingRingBuffer<T> extends RingBuffer<T> {
|
||||
private static INITIAL_CAPACITY;
|
||||
/**
|
||||
* Constructs a `GrowingRingBuffer`.
|
||||
*/
|
||||
constructor();
|
||||
isFull(): boolean;
|
||||
push(value: T): void;
|
||||
unshift(value: T): void;
|
||||
/**
|
||||
* Doubles the capacity of the buffer.
|
||||
*/
|
||||
private expand;
|
||||
}
|
||||
Generated
Vendored
-61
@@ -1,61 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
import { RingBuffer } from './ring_buffer';
|
||||
export class GrowingRingBuffer extends RingBuffer {
|
||||
/**
|
||||
* Constructs a `GrowingRingBuffer`.
|
||||
*/
|
||||
constructor() {
|
||||
super(GrowingRingBuffer.INITIAL_CAPACITY);
|
||||
}
|
||||
isFull() {
|
||||
return false;
|
||||
}
|
||||
push(value) {
|
||||
if (super.isFull()) {
|
||||
this.expand();
|
||||
}
|
||||
super.push(value);
|
||||
}
|
||||
unshift(value) {
|
||||
if (super.isFull()) {
|
||||
this.expand();
|
||||
}
|
||||
super.unshift(value);
|
||||
}
|
||||
/**
|
||||
* Doubles the capacity of the buffer.
|
||||
*/
|
||||
expand() {
|
||||
const newCapacity = this.capacity * 2;
|
||||
const newData = new Array(newCapacity);
|
||||
const len = this.length();
|
||||
// Rotate the buffer to start at index 0 again, since we can't just
|
||||
// allocate more space at the end.
|
||||
for (let i = 0; i < len; i++) {
|
||||
newData[i] = this.get(this.wrap(this.begin + i));
|
||||
}
|
||||
this.data = newData;
|
||||
this.capacity = newCapacity;
|
||||
this.doubledCapacity = 2 * this.capacity;
|
||||
this.begin = 0;
|
||||
this.end = len;
|
||||
}
|
||||
}
|
||||
GrowingRingBuffer.INITIAL_CAPACITY = 32;
|
||||
//# sourceMappingURL=growing_ring_buffer.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"growing_ring_buffer.js","sourceRoot":"","sources":["../../src/util/growing_ring_buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC,MAAM,OAAO,iBAAqB,SAAQ,UAAa;IAGrD;;OAEG;IACH;QACE,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,KAAQ;QACX,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE;YAClB,IAAI,CAAC,MAAM,EAAE,CAAC;SACf;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,CAAC,KAAQ;QACd,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE;YAClB,IAAI,CAAC,MAAM,EAAE,CAAC;SACf;QACD,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,MAAM;QACZ,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,KAAK,CAAI,WAAW,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAE1B,mEAAmE;QACnE,kCAAkC;QAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;YAC5B,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;SAClD;QAED,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QACpB,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;;AA9Cc,kCAAgB,GAAG,EAAE,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {RingBuffer} from './ring_buffer';\n\nexport class GrowingRingBuffer<T> extends RingBuffer<T> {\n private static INITIAL_CAPACITY = 32;\n\n /**\n * Constructs a `GrowingRingBuffer`.\n */\n constructor() {\n super(GrowingRingBuffer.INITIAL_CAPACITY);\n }\n\n isFull() {\n return false;\n }\n\n push(value: T) {\n if (super.isFull()) {\n this.expand();\n }\n super.push(value);\n }\n\n unshift(value: T) {\n if (super.isFull()) {\n this.expand();\n }\n super.unshift(value);\n }\n\n /**\n * Doubles the capacity of the buffer.\n */\n private expand() {\n const newCapacity = this.capacity * 2;\n const newData = new Array<T>(newCapacity);\n const len = this.length();\n\n // Rotate the buffer to start at index 0 again, since we can't just\n // allocate more space at the end.\n for (let i = 0; i < len; i++) {\n newData[i] = this.get(this.wrap(this.begin + i));\n }\n\n this.data = newData;\n this.capacity = newCapacity;\n this.doubledCapacity = 2 * this.capacity;\n this.begin = 0;\n this.end = len;\n }\n}\n"]}
|
||||
Generated
Vendored
-84
@@ -1,84 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
/**
|
||||
* A ring buffer, providing O(1) FIFO, LIFO, and related operations.
|
||||
*/
|
||||
export declare class RingBuffer<T> {
|
||||
capacity: number;
|
||||
protected begin: number;
|
||||
protected end: number;
|
||||
protected doubledCapacity: number;
|
||||
protected data: T[];
|
||||
/**
|
||||
* Constructs a `RingBuffer`.
|
||||
* @param capacity The number of items that the buffer can accomodate.
|
||||
*/
|
||||
constructor(capacity: number);
|
||||
/**
|
||||
* Map any index into the range 0 <= index < 2*capacity.
|
||||
*/
|
||||
protected wrap(index: number): number;
|
||||
protected get(index: number): T;
|
||||
protected set(index: number, value: T): void;
|
||||
/**
|
||||
* Returns the current number of items in the buffer.
|
||||
*/
|
||||
length(): number;
|
||||
/**
|
||||
* Reports whether the buffer is full.
|
||||
* @returns true if the number of items in the buffer equals its capacity, and
|
||||
* false otherwise.
|
||||
*/
|
||||
isFull(): boolean;
|
||||
/**
|
||||
* Reports whether the buffer is empty.
|
||||
* @returns true if the number of items in the buffer equals zero, and
|
||||
* false otherwise.
|
||||
*/
|
||||
isEmpty(): boolean;
|
||||
/**
|
||||
* Adds an item to the end of the buffer.
|
||||
*/
|
||||
push(value: T): void;
|
||||
/**
|
||||
* Adds many items to the end of the buffer, in order.
|
||||
*/
|
||||
pushAll(values: T[]): void;
|
||||
/**
|
||||
* Removes and returns the last item in the buffer.
|
||||
*/
|
||||
pop(): T;
|
||||
/**
|
||||
* Adds an item to the beginning of the buffer.
|
||||
*/
|
||||
unshift(value: T): void;
|
||||
/**
|
||||
* Removes and returns the first item in the buffer.
|
||||
*/
|
||||
shift(): T;
|
||||
/**
|
||||
* Removes and returns a specific item in the buffer, and moves the last item
|
||||
* to the vacated slot. This is useful for implementing a shuffling stream.
|
||||
* Note that this operation necessarily scrambles the original order.
|
||||
*
|
||||
* @param relativeIndex: the index of the item to remove, relative to the
|
||||
* first item in the buffer (e.g., hiding the ring nature of the underlying
|
||||
* storage).
|
||||
*/
|
||||
shuffleExcise(relativeIndex: number): T;
|
||||
}
|
||||
Generated
Vendored
-161
@@ -1,161 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
/**
|
||||
* A ring buffer, providing O(1) FIFO, LIFO, and related operations.
|
||||
*/
|
||||
export class RingBuffer {
|
||||
/**
|
||||
* Constructs a `RingBuffer`.
|
||||
* @param capacity The number of items that the buffer can accomodate.
|
||||
*/
|
||||
constructor(capacity) {
|
||||
this.capacity = capacity;
|
||||
// Note we store the indices in the range 0 <= index < 2*capacity.
|
||||
// This allows us to distinguish the full from the empty case.
|
||||
// See https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/
|
||||
this.begin = 0; // inclusive
|
||||
this.end = 0; // exclusive
|
||||
if (capacity == null) {
|
||||
throw new RangeError('Can\'t create a ring buffer of unknown capacity.');
|
||||
}
|
||||
if (capacity < 1) {
|
||||
throw new RangeError('Can\'t create ring buffer of capacity < 1.');
|
||||
}
|
||||
this.data = new Array(capacity);
|
||||
this.doubledCapacity = 2 * capacity;
|
||||
}
|
||||
/**
|
||||
* Map any index into the range 0 <= index < 2*capacity.
|
||||
*/
|
||||
wrap(index) {
|
||||
// don't trust % on negative numbers
|
||||
while (index < 0) {
|
||||
index += this.doubledCapacity;
|
||||
}
|
||||
return index % this.doubledCapacity;
|
||||
}
|
||||
get(index) {
|
||||
if (index < 0) {
|
||||
throw new RangeError('Can\'t get item at a negative index.');
|
||||
}
|
||||
return this.data[index % this.capacity];
|
||||
}
|
||||
set(index, value) {
|
||||
if (index < 0) {
|
||||
throw new RangeError('Can\'t set item at a negative index.');
|
||||
}
|
||||
this.data[index % this.capacity] = value;
|
||||
}
|
||||
/**
|
||||
* Returns the current number of items in the buffer.
|
||||
*/
|
||||
length() {
|
||||
let length = this.end - this.begin;
|
||||
if (length < 0) {
|
||||
length = this.doubledCapacity + length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
/**
|
||||
* Reports whether the buffer is full.
|
||||
* @returns true if the number of items in the buffer equals its capacity, and
|
||||
* false otherwise.
|
||||
*/
|
||||
isFull() {
|
||||
return this.length() === this.capacity;
|
||||
}
|
||||
/**
|
||||
* Reports whether the buffer is empty.
|
||||
* @returns true if the number of items in the buffer equals zero, and
|
||||
* false otherwise.
|
||||
*/
|
||||
isEmpty() {
|
||||
return this.length() === 0;
|
||||
}
|
||||
/**
|
||||
* Adds an item to the end of the buffer.
|
||||
*/
|
||||
push(value) {
|
||||
if (this.isFull()) {
|
||||
throw new RangeError('Ring buffer is full.');
|
||||
}
|
||||
this.set(this.end, value);
|
||||
this.end = this.wrap(this.end + 1);
|
||||
}
|
||||
/**
|
||||
* Adds many items to the end of the buffer, in order.
|
||||
*/
|
||||
pushAll(values) {
|
||||
for (const value of values) {
|
||||
this.push(value);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Removes and returns the last item in the buffer.
|
||||
*/
|
||||
pop() {
|
||||
if (this.isEmpty()) {
|
||||
throw new RangeError('Ring buffer is empty.');
|
||||
}
|
||||
this.end = this.wrap(this.end - 1);
|
||||
const result = this.get(this.end);
|
||||
this.set(this.end, undefined);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Adds an item to the beginning of the buffer.
|
||||
*/
|
||||
unshift(value) {
|
||||
if (this.isFull()) {
|
||||
throw new RangeError('Ring buffer is full.');
|
||||
}
|
||||
this.begin = this.wrap(this.begin - 1);
|
||||
this.set(this.begin, value);
|
||||
}
|
||||
/**
|
||||
* Removes and returns the first item in the buffer.
|
||||
*/
|
||||
shift() {
|
||||
if (this.isEmpty()) {
|
||||
throw new RangeError('Ring buffer is empty.');
|
||||
}
|
||||
const result = this.get(this.begin);
|
||||
this.set(this.begin, undefined);
|
||||
this.begin = this.wrap(this.begin + 1);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Removes and returns a specific item in the buffer, and moves the last item
|
||||
* to the vacated slot. This is useful for implementing a shuffling stream.
|
||||
* Note that this operation necessarily scrambles the original order.
|
||||
*
|
||||
* @param relativeIndex: the index of the item to remove, relative to the
|
||||
* first item in the buffer (e.g., hiding the ring nature of the underlying
|
||||
* storage).
|
||||
*/
|
||||
shuffleExcise(relativeIndex) {
|
||||
if (this.isEmpty()) {
|
||||
throw new RangeError('Ring buffer is empty.');
|
||||
}
|
||||
const index = this.wrap(this.begin + relativeIndex);
|
||||
const result = this.get(index);
|
||||
this.set(index, this.pop());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=ring_buffer.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"ring_buffer.js","sourceRoot":"","sources":["../../src/util/ring_buffer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\n/**\n * A ring buffer, providing O(1) FIFO, LIFO, and related operations.\n */\nexport class RingBuffer<T> {\n // Note we store the indices in the range 0 <= index < 2*capacity.\n // This allows us to distinguish the full from the empty case.\n // See https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/\n protected begin = 0; // inclusive\n protected end = 0; // exclusive\n protected doubledCapacity: number;\n\n protected data: T[];\n\n /**\n * Constructs a `RingBuffer`.\n * @param capacity The number of items that the buffer can accomodate.\n */\n constructor(public capacity: number) {\n if (capacity == null) {\n throw new RangeError('Can\\'t create a ring buffer of unknown capacity.');\n }\n if (capacity < 1) {\n throw new RangeError('Can\\'t create ring buffer of capacity < 1.');\n }\n this.data = new Array<T>(capacity);\n this.doubledCapacity = 2 * capacity;\n }\n\n /**\n * Map any index into the range 0 <= index < 2*capacity.\n */\n protected wrap(index:Line truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"ring_buffer_test.js","sourceRoot":"","sources":["../../src/util/ring_buffer_test.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
export declare function isLocalPath(source: any): boolean;
|
||||
Generated
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
// Skip tslint any type check cause this method is aiming to check type of
|
||||
// input.
|
||||
// tslint:disable-next-line:no-any
|
||||
export function isLocalPath(source) {
|
||||
return (typeof source === 'string') && source.substr(0, 7) === 'file://';
|
||||
}
|
||||
//# sourceMappingURL=source_util.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"source_util.js","sourceRoot":"","sources":["../../src/util/source_util.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,0EAA0E;AAC1E,SAAS;AACT,kCAAkC;AAClC,MAAM,UAAU,WAAW,CAAC,MAAW;IACrC,OAAO,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;AAC3E,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\n// Skip tslint any type check cause this method is aiming to check type of\n// input.\n// tslint:disable-next-line:no-any\nexport function isLocalPath(source: any): boolean {\n return (typeof source === 'string') && source.substr(0, 7) === 'file://';\n}\n"]}
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"source_util_test.js","sourceRoot":"","sources":["../../src/util/source_util_test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,GAAG,EAAC,MAAM,uBAAuB,CAAC;AAC1C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,MAAM,aAAa,GAAG,iBAAiB,CAAC;AACxC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAEtE,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\nimport {env} from '@tensorflow/tfjs-core';\nimport {isLocalPath} from './source_util';\n\nconst nonPathString = 'iamnotlocalpath';\nconst testData = env().get('IS_BROWSER') ? new Blob([nonPathString]) :\n Buffer.from(nonPathString);\n\ndescribe('source_util', () => {\n it('returns true if it is local path', () => {\n const result = isLocalPath('file://testfile');\n expect(result).toBeTruthy();\n });\n\n it('returns false if it is not local path', () => {\n const result = isLocalPath(nonPathString);\n expect(result).toBeFalsy();\n });\n\n it('returns false if it is not string type', () => {\n const result = isLocalPath(testData);\n expect(result).toBeFalsy();\n });\n});\n"]}
|
||||
Generated
Vendored
-51
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
export declare function setupFakeVideoStream(): void;
|
||||
export declare function replaceHTMLVideoElementSource(videoElement: HTMLVideoElement): Promise<void>;
|
||||
export declare function describeAllEnvs(testName: string, tests: () => void): void;
|
||||
export declare function describeBrowserEnvs(testName: string, tests: () => void): void;
|
||||
export declare function describeNodeEnvs(testName: string, tests: () => void): void;
|
||||
/**
|
||||
* Testing Utilities for browser audeo stream.
|
||||
*/
|
||||
export declare function setupFakeAudeoStream(): void;
|
||||
export declare class FakeAudioContext {
|
||||
readonly sampleRate = 44100;
|
||||
static createInstance(): FakeAudioContext;
|
||||
createMediaStreamSource(): FakeMediaStreamAudioSourceNode;
|
||||
createAnalyser(): FakeAnalyser;
|
||||
close(): void;
|
||||
}
|
||||
export declare class FakeAudioMediaStream {
|
||||
constructor();
|
||||
getTracks(): Array<{}>;
|
||||
}
|
||||
declare class FakeMediaStreamAudioSourceNode {
|
||||
constructor();
|
||||
connect(node: {}): void;
|
||||
}
|
||||
declare class FakeAnalyser {
|
||||
fftSize: number;
|
||||
smoothingTimeConstant: number;
|
||||
private x;
|
||||
constructor();
|
||||
getFloatFrequencyData(data: Float32Array): void;
|
||||
getFloatTimeDomainData(data: Float32Array): void;
|
||||
disconnect(): void;
|
||||
}
|
||||
export {};
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"test_utils.js","sourceRoot":"","sources":["../../src/util/test_utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\n\n// tslint:disable-next-line: no-imports-from-dist\nimport {ALL_ENVS, BROWSER_ENVS, describeWithFlags, NODE_ENVS, registerTestEnv} from '@tensorflow/tfjs-core/dist/jasmine_util';\n\n// Provide fake video stream\nexport function setupFakeVideoStream() {\n const width = 100;\n const height = 200;\n const canvasElement = document.createElement('canvas');\n const ctx = canvasElement.getContext('2d');\n ctx.fillStyle = 'rgb(1,2,3)';\n ctx.fillRect(0, 0, width, height);\n // tslint:disable-next-line:no-any\n const stream = (canvasElement as any).captureStream(60);\n navigator.mediaDevices.getUserMedia = async () => {\n return stream;\n };\n}\n\nexport async function replaceHTMLVideoElementSource(\n videoElement: HTMLVideoElement) {\n const source = document.createElement('source');\n // tslint:disable:max-line-length\n source.src =\n 'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAAu1tZGF0AAACrQYF//+p3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE1NSByMjkwMSA3ZDBmZjIyIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RLine truncated
|
||||
Generated
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
/** @license See the LICENSE file. */
|
||||
// This code is auto-generated, do not modify this file!
|
||||
const version = '3.6.0';
|
||||
export { version };
|
||||
//# sourceMappingURL=version.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,wDAAwD;AACxD,MAAM,OAAO,GAAG,OAAO,CAAC;AACxB,OAAO,EAAC,OAAO,EAAC,CAAC","sourcesContent":["/** @license See the LICENSE file. */\n\n// This code is auto-generated, do not modify this file!\nconst version = '3.6.0';\nexport {version};\n"]}
|
||||
Generated
Vendored
-705
@@ -1,705 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import * as tf from '@tensorflow/tfjs-core';
|
||||
import {TensorContainer, TensorLike} from '@tensorflow/tfjs-core';
|
||||
import * as seedrandom from 'seedrandom';
|
||||
|
||||
import {iteratorFromConcatenated, iteratorFromFunction, iteratorFromItems, iteratorFromZipped, LazyIterator, ZipMismatchMode} from './iterators/lazy_iterator';
|
||||
import {Container} from './types';
|
||||
import {canTensorify, deepMapAndAwaitAll, DeepMapResult, isIterable} from './util/deep_map';
|
||||
|
||||
/**
|
||||
* A nested structure of Datasets, used as the input to zip().
|
||||
*/
|
||||
export type DatasetContainer = Container<Dataset<TensorContainer>>;
|
||||
|
||||
// TODO(soergel): consider vectorized operations within the pipeline.
|
||||
|
||||
/**
|
||||
* Represents a potentially large list of independent data elements (typically
|
||||
* 'samples' or 'examples').
|
||||
*
|
||||
* A 'data example' may be a primitive, an array, a map from string keys to
|
||||
* values, or any nested structure of these.
|
||||
*
|
||||
* A `Dataset` represents an ordered collection of elements, together with a
|
||||
* chain of transformations to be performed on those elements. Each
|
||||
* transformation is a method of `Dataset` that returns another `Dataset`, so
|
||||
* these may be chained, e.g.
|
||||
* `const processedDataset = rawDataset.filter(...).map(...).batch(...)`.
|
||||
*
|
||||
* Data loading and transformation is done in a lazy, streaming fashion. The
|
||||
* dataset may be iterated over multiple times; each iteration starts the data
|
||||
* loading anew and recapitulates the transformations.
|
||||
*
|
||||
* A `Dataset` is typically processed as a stream of unbatched examples --i.e.,
|
||||
* its transformations are applied one example at a time. Batching produces a
|
||||
* new `Dataset` where each element is a batch. Batching should usually come
|
||||
* last in a pipeline, because data transformations are easier to express on a
|
||||
* per-example basis than on a per-batch basis.
|
||||
*
|
||||
* The following code examples are calling `await dataset.forEachAsync(...)` to
|
||||
* iterate once over the entire dataset in order to print out the data.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes', namespace: 'data'}
|
||||
*/
|
||||
export abstract class Dataset<T extends tf.TensorContainer> {
|
||||
/*
|
||||
* Provide a new stream of elements. Note this will also start new streams
|
||||
* from any underlying `Dataset`s.
|
||||
*
|
||||
* CAUTION: Any Tensors contained within the elements returned from
|
||||
* this stream *must* be manually disposed to avoid a GPU memory leak.
|
||||
* The tf.tidy() approach cannot be used in an asynchronous context.
|
||||
*/
|
||||
abstract async iterator(): Promise<LazyIterator<T>>;
|
||||
|
||||
readonly size: number = null;
|
||||
|
||||
// TODO(soergel): Make Datasets report whether repeated iterator() calls
|
||||
// produce the same result (e.g., reading from a file) or different results
|
||||
// (e.g., from the webcam). Currently we don't make this distinction but it
|
||||
// could be important for the user to know.
|
||||
// abstract isDeterministic(): boolean;
|
||||
|
||||
/**
|
||||
* Groups elements into batches.
|
||||
*
|
||||
* It is assumed that each of the incoming dataset elements has the same
|
||||
* structure-- i.e. the same set of keys at each location in an object
|
||||
* hierarchy. For each key, the resulting `Dataset` provides a batched
|
||||
* element collecting all of the incoming values for that key.
|
||||
*
|
||||
* * Incoming primitives are grouped into a 1-D Tensor.
|
||||
* * Incoming Tensors are grouped into a new Tensor where the 0'th axis is
|
||||
* the batch dimension.
|
||||
* * Incoming arrays are converted to Tensor and then batched.
|
||||
* * A nested array is interpreted as an n-D Tensor, so the batched result
|
||||
* has n+1 dimensions.
|
||||
* * An array that cannot be converted to Tensor produces an error.
|
||||
*
|
||||
* If an array should not be batched as a unit, it should first be converted
|
||||
* to an object with integer keys.
|
||||
*
|
||||
* Here are a few examples:
|
||||
*
|
||||
* Batch a dataset of numbers:
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3, 4, 5, 6, 7, 8]).batch(4);
|
||||
* await a.forEachAsync(e => e.print());
|
||||
* ```
|
||||
*
|
||||
* Batch a dataset of arrays:
|
||||
* ```js
|
||||
* const b = tf.data.array([[1], [2], [3], [4], [5], [6], [7], [8]]).batch(4);
|
||||
* await b.forEachAsync(e => e.print());
|
||||
* ```
|
||||
*
|
||||
* Batch a dataset of objects:
|
||||
* ```js
|
||||
* const c = tf.data.array([{a: 1, b: 11}, {a: 2, b: 12}, {a: 3, b: 13},
|
||||
* {a: 4, b: 14}, {a: 5, b: 15}, {a: 6, b: 16}, {a: 7, b: 17},
|
||||
* {a: 8, b: 18}]).batch(4);
|
||||
* await c.forEachAsync(e => {
|
||||
* console.log('{');
|
||||
* for(var key in e) {
|
||||
* console.log(key+':');
|
||||
* e[key].print();
|
||||
* }
|
||||
* console.log('}');
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param batchSize The number of elements desired per batch.
|
||||
* @param smallLastBatch Whether to emit the final batch when it has fewer
|
||||
* than batchSize elements. Default true.
|
||||
* @returns A `Dataset`, from which a stream of batches can be obtained.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
batch(batchSize: number, smallLastBatch = true): Dataset<tf.TensorContainer> {
|
||||
const base = this;
|
||||
tf.util.assert(
|
||||
batchSize > 0, () => `batchSize needs to be positive, but it is
|
||||
${batchSize}`);
|
||||
let size;
|
||||
if (this.size === Infinity || this.size == null) {
|
||||
// If the size of this dataset is infinity or null, the new size keeps the
|
||||
// same.
|
||||
size = this.size;
|
||||
} else if (smallLastBatch) {
|
||||
// If the size of this dataset is known and include small last batch, the
|
||||
// new size is full batch count plus last batch.
|
||||
size = Math.ceil(this.size / batchSize);
|
||||
} else {
|
||||
// If the size of this dataset is known and not include small last batch,
|
||||
// the new size is full batch count.
|
||||
size = Math.floor(this.size / batchSize);
|
||||
}
|
||||
return datasetFromIteratorFn(async () => {
|
||||
return (await base.iterator())
|
||||
.columnMajorBatch(batchSize, smallLastBatch, deepBatchConcat);
|
||||
}, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates this `Dataset` with another.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3]);
|
||||
* const b = tf.data.array([4, 5, 6]);
|
||||
* const c = a.concatenate(b);
|
||||
* await c.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param dataset A `Dataset` to be concatenated onto this one.
|
||||
* @returns A `Dataset`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
concatenate(dataset: Dataset<T>): Dataset<T> {
|
||||
const base = this;
|
||||
let size;
|
||||
if (this.size === Infinity || dataset.size === Infinity) {
|
||||
// If the size of any of these two dataset is infinity, new size is
|
||||
// infinity.
|
||||
size = Infinity;
|
||||
} else if (this.size != null && dataset.size != null) {
|
||||
// If the size of both datasets are known and not infinity, new size is
|
||||
// sum the size of these two datasets.
|
||||
size = this.size + dataset.size;
|
||||
} else {
|
||||
// If neither of these two datasets has infinite size and any of these two
|
||||
// datasets' size is null, the new size is null.
|
||||
size = null;
|
||||
}
|
||||
return datasetFromIteratorFn(
|
||||
async () =>
|
||||
(await base.iterator()).concatenate(await dataset.iterator()),
|
||||
size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters this dataset according to `predicate`.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
* .filter(x => x%2 === 0);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param predicate A function mapping a dataset element to a boolean or a
|
||||
* `Promise` for one.
|
||||
*
|
||||
* @returns A `Dataset` of elements for which the predicate was true.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
filter(predicate: (value: T) => boolean): Dataset<T> {
|
||||
const base = this;
|
||||
let size;
|
||||
if (this.size === Infinity) {
|
||||
// If the size of this dataset is infinity, new size is infinity
|
||||
size = Infinity;
|
||||
} else {
|
||||
// If this dataset has limited elements, new size is null because it might
|
||||
// exhausted randomly.
|
||||
size = null;
|
||||
}
|
||||
return datasetFromIteratorFn(async () => {
|
||||
return (await base.iterator()).filter(x => tf.tidy(() => predicate(x)));
|
||||
}, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a function to every element of the dataset.
|
||||
*
|
||||
* After the function is applied to a dataset element, any Tensors contained
|
||||
* within that element are disposed.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3]);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param f A function to apply to each dataset element.
|
||||
* @returns A `Promise` that resolves after all elements have been processed.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
async forEachAsync(f: (input: T) => void): Promise<void> {
|
||||
return (await this.iterator()).forEachAsync(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this dataset through a 1-to-1 transform.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3]).map(x => x*x);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param transform A function mapping a dataset element to a transformed
|
||||
* dataset element.
|
||||
*
|
||||
* @returns A `Dataset` of transformed elements.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
map<O extends tf.TensorContainer>(transform: (value: T) => O): Dataset<O> {
|
||||
const base = this;
|
||||
return datasetFromIteratorFn(async () => {
|
||||
return (await base.iterator()).map(x => tf.tidy(() => transform(x)));
|
||||
}, this.size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this dataset through an async 1-to-1 transform.
|
||||
*
|
||||
* ```js
|
||||
* const a =
|
||||
* tf.data.array([1, 2, 3]).mapAsync(x => new Promise(function(resolve){
|
||||
* setTimeout(() => {
|
||||
* resolve(x * x);
|
||||
* }, Math.random()*1000 + 500);
|
||||
* }));
|
||||
* console.log(await a.toArray());
|
||||
* ```
|
||||
*
|
||||
* @param transform A function mapping a dataset element to a `Promise` for a
|
||||
* transformed dataset element. This transform is responsible for disposing
|
||||
* any intermediate `Tensor`s, i.e. by wrapping its computation in
|
||||
* `tf.tidy()`; that cannot be automated here (as it is in the synchronous
|
||||
* `map()` case).
|
||||
*
|
||||
* @returns A `Dataset` of transformed elements.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
mapAsync<O extends tf.TensorContainer>(transform: (value: T) => Promise<O>):
|
||||
Dataset<O> {
|
||||
const base = this;
|
||||
return datasetFromIteratorFn(async () => {
|
||||
return (await base.iterator()).mapAsync(transform);
|
||||
}, this.size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `Dataset` that prefetches elements from this dataset.
|
||||
*
|
||||
* @param bufferSize: An integer specifying the number of elements to be
|
||||
* prefetched.
|
||||
* @returns A `Dataset`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
prefetch(bufferSize: number): Dataset<T> {
|
||||
if (bufferSize == null) {
|
||||
throw new RangeError(
|
||||
'`Dataset.prefetch()` requires bufferSize to be specified.');
|
||||
}
|
||||
|
||||
const base = this;
|
||||
return datasetFromIteratorFn(
|
||||
async () => (await base.iterator()).prefetch(bufferSize), this.size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats this dataset `count` times.
|
||||
*
|
||||
* NOTE: If this dataset is a function of global state (e.g. a random number
|
||||
* generator), then different repetitions may produce different elements.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3]).repeat(3);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param count: (Optional) An integer, representing the number of times
|
||||
* the dataset should be repeated. The default behavior (if `count` is
|
||||
* `undefined` or negative) is for the dataset be repeated indefinitely.
|
||||
* @returns A `Dataset`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
repeat(count?: number): Dataset<T> {
|
||||
const base = this;
|
||||
let size;
|
||||
if (this.size != null && count > 0) {
|
||||
// If this dataset has size and count is positive, new size is current
|
||||
// size multiply count. This also covers the case that current size is
|
||||
// infinity.
|
||||
size = this.size * count;
|
||||
} else if (count === 0) {
|
||||
// If count is 0, new size is 0.
|
||||
size = 0;
|
||||
} else if (this.size != null && (count === undefined || count < 0)) {
|
||||
// If this dataset has size and count is undefined or negative, the
|
||||
// dataset will be repeated indefinitely and new size is infinity.
|
||||
size = Infinity;
|
||||
} else {
|
||||
// If the size of this dataset is null, the new dataset's size is null.
|
||||
size = null;
|
||||
}
|
||||
return datasetFromIteratorFn(async () => {
|
||||
const iteratorIterator = iteratorFromFunction(
|
||||
async () => ({value: await base.iterator(), done: false}));
|
||||
return iteratorFromConcatenated(iteratorIterator.take(count));
|
||||
}, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `Dataset` that skips `count` initial elements from this dataset.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3, 4, 5, 6]).skip(3);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param count: The number of elements of this dataset that should be skipped
|
||||
* to form the new dataset. If `count` is greater than the size of this
|
||||
* dataset, the new dataset will contain no elements. If `count`
|
||||
* is `undefined` or negative, skips the entire dataset.
|
||||
*
|
||||
* @returns A `Dataset`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
skip(count: number): Dataset<T> {
|
||||
const base = this;
|
||||
let size;
|
||||
if (this.size != null && count >= 0 && this.size >= count) {
|
||||
// If the size of this dataset is greater than count, the new dataset's
|
||||
// size is current size minus skipped size.This also covers the case that
|
||||
// current size is infinity.
|
||||
size = this.size - count;
|
||||
} else if (
|
||||
this.size != null &&
|
||||
(this.size < count || count === undefined || count < 0)) {
|
||||
// If the size of this dataset is smaller than count, or count is
|
||||
// undefined or negative, skips the entire dataset and the new size is 0.
|
||||
size = 0;
|
||||
} else {
|
||||
// If the size of this dataset is null, the new dataset's size is null.
|
||||
size = null;
|
||||
}
|
||||
return datasetFromIteratorFn(
|
||||
async () => (await base.iterator()).skip(count), size);
|
||||
}
|
||||
|
||||
// TODO(soergel): deep sharded shuffle, where supported
|
||||
|
||||
static readonly MAX_BUFFER_SIZE = 10000;
|
||||
|
||||
/**
|
||||
* Pseudorandomly shuffles the elements of this dataset. This is done in a
|
||||
* streaming manner, by sampling from a given number of prefetched elements.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3, 4, 5, 6]).shuffle(3);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param bufferSize: An integer specifying the number of elements from this
|
||||
* dataset from which the new dataset will sample.
|
||||
* @param seed: (Optional) An integer specifying the random seed that will
|
||||
* be used to create the distribution.
|
||||
* @param reshuffleEachIteration: (Optional) A boolean, which if true
|
||||
* indicates that the dataset should be pseudorandomly reshuffled each time
|
||||
* it is iterated over. If false, elements will be returned in the same
|
||||
* shuffled order on each iteration. (Defaults to `true`.)
|
||||
* @returns A `Dataset`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
shuffle(bufferSize: number, seed?: string, reshuffleEachIteration = true):
|
||||
Dataset<T> {
|
||||
if (bufferSize == null || bufferSize < 0) {
|
||||
if (this.size == null) {
|
||||
throw new RangeError(
|
||||
'`Dataset.shuffle()` requires bufferSize to be specified.');
|
||||
} else {
|
||||
throw new RangeError(
|
||||
'`Dataset.shuffle()` requires bufferSize to be specified. ' +
|
||||
'If your data fits in main memory (for regular JS objects), ' +
|
||||
'and/or GPU memory (for `tf.Tensor`s), consider setting ' +
|
||||
`bufferSize to the dataset size (${this.size} elements)`);
|
||||
}
|
||||
}
|
||||
const base = this;
|
||||
const random = seedrandom.alea(seed || tf.util.now().toString());
|
||||
return datasetFromIteratorFn(async () => {
|
||||
let seed2 = random.int32();
|
||||
if (reshuffleEachIteration) {
|
||||
seed2 += random.int32();
|
||||
}
|
||||
return (await base.iterator()).shuffle(bufferSize, seed2.toString());
|
||||
}, this.size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `Dataset` with at most `count` initial elements from this
|
||||
* dataset.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3, 4, 5, 6]).take(3);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param count: The number of elements of this dataset that should be taken
|
||||
* to form the new dataset. If `count` is `undefined` or negative, or if
|
||||
* `count` is greater than the size of this dataset, the new dataset will
|
||||
* contain all elements of this dataset.
|
||||
* @returns A `Dataset`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
take(count: number): Dataset<T> {
|
||||
const base = this;
|
||||
let size;
|
||||
if (this.size != null && this.size > count) {
|
||||
// If the size of this dataset is greater than count, the new dataset's
|
||||
// size is count.
|
||||
size = count;
|
||||
} else if (this.size != null && this.size <= count) {
|
||||
// If the size of this dataset is equal or smaller than count, the new
|
||||
// dataset's size is the size of this dataset.
|
||||
size = this.size;
|
||||
} else {
|
||||
// If the size of this dataset is null, the new dataset's size is null.
|
||||
size = null;
|
||||
}
|
||||
return datasetFromIteratorFn(
|
||||
async () => (await base.iterator()).take(count), size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all elements of this dataset into an array.
|
||||
*
|
||||
* Obviously this will succeed only for small datasets that fit in memory.
|
||||
* Useful for testing and generally should be avoided if possible.
|
||||
*
|
||||
* ```js
|
||||
* const a = tf.data.array([1, 2, 3, 4, 5, 6]);
|
||||
* console.log(await a.toArray());
|
||||
* ```
|
||||
*
|
||||
* @returns A Promise for an array of elements, which will resolve
|
||||
* when a new stream has been obtained and fully consumed.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
async toArray() {
|
||||
if (this.size === Infinity) {
|
||||
throw new Error('Can not convert infinite data stream to array.');
|
||||
}
|
||||
return (await this.iterator()).toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all elements of this dataset into an array with prefetching 100
|
||||
* elements. This is useful for testing, because the prefetch changes the
|
||||
* order in which the Promises are resolved along the processing pipeline.
|
||||
* This may help expose bugs where results are dependent on the order of
|
||||
* Promise resolution rather than on the logical order of the stream (i.e.,
|
||||
* due to hidden mutable state).
|
||||
*
|
||||
* @returns A Promise for an array of elements, which will resolve
|
||||
* when a new stream has been obtained and fully consumed.
|
||||
*/
|
||||
async toArrayForTest() {
|
||||
if (this.size === Infinity) {
|
||||
throw new Error('Can not convert infinite data stream to array.');
|
||||
}
|
||||
return (await this.iterator()).toArrayForTest();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `Dataset` defined by a provided iterator() function.
|
||||
*
|
||||
* ```js
|
||||
* let i = -1;
|
||||
* const func = () =>
|
||||
* ++i < 5 ? {value: i, done: false} : {value: null, done: true};
|
||||
* const iter = tf.data.iteratorFromFunction(func);
|
||||
* const ds = tf.data.datasetFromIteratorFn(iter);
|
||||
* await ds.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*/
|
||||
export function datasetFromIteratorFn<T extends tf.TensorContainer>(
|
||||
iteratorFn: () => Promise<LazyIterator<T>>,
|
||||
size: number = null): Dataset<T> {
|
||||
return new class extends Dataset<T> {
|
||||
size = size;
|
||||
|
||||
/*
|
||||
* Provide a new stream of elements. Note this will also start new streams
|
||||
* from any underlying `Dataset`s.
|
||||
*/
|
||||
async iterator(): Promise<LazyIterator<T>> {
|
||||
return iteratorFn();
|
||||
}
|
||||
}
|
||||
();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `Dataset` from an array of elements.
|
||||
*
|
||||
* Create a Dataset from an array of objects:
|
||||
* ```js
|
||||
* const a = tf.data.array([{'item': 1}, {'item': 2}, {'item': 3}]);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* Create a Dataset from an array of numbers:
|
||||
* ```js
|
||||
* const a = tf.data.array([4, 5, 6]);
|
||||
* await a.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
* @param items An array of elements that will be parsed as items in a dataset.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Creation', namespace: 'data'}
|
||||
*/
|
||||
export function array<T extends tf.TensorContainer>(items: T[]): Dataset<T> {
|
||||
return datasetFromIteratorFn(
|
||||
async () => iteratorFromItems(items), items.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `Dataset` by zipping together an array, dict, or nested
|
||||
* structure of `Dataset`s (and perhaps additional constants).
|
||||
* The underlying datasets must provide elements in a consistent order such that
|
||||
* they correspond.
|
||||
*
|
||||
* The number of elements in the resulting dataset is the same as the size of
|
||||
* the smallest dataset in datasets.
|
||||
*
|
||||
* The nested structure of the `datasets` argument determines the
|
||||
* structure of elements in the resulting iterator.
|
||||
*
|
||||
* Note this means that, given an array of two datasets that produce dict
|
||||
* elements, the result is a dataset that produces elements that are arrays
|
||||
* of two dicts:
|
||||
*
|
||||
* Zip an array of datasets:
|
||||
* ```js
|
||||
* console.log('Zip two datasets of objects:');
|
||||
* const ds1 = tf.data.array([{a: 1}, {a: 2}, {a: 3}]);
|
||||
* const ds2 = tf.data.array([{b: 4}, {b: 5}, {b: 6}]);
|
||||
* const ds3 = tf.data.zip([ds1, ds2]);
|
||||
* await ds3.forEachAsync(e => console.log(JSON.stringify(e)));
|
||||
*
|
||||
* // If the goal is to merge the dicts in order to produce elements like
|
||||
* // {a: ..., b: ...}, this requires a second step such as:
|
||||
* console.log('Merge the objects:');
|
||||
* const ds4 = ds3.map(x => {return {a: x[0].a, b: x[1].b}});
|
||||
* await ds4.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* Zip a dict of datasets:
|
||||
* ```js
|
||||
* const a = tf.data.array([{a: 1}, {a: 2}, {a: 3}]);
|
||||
* const b = tf.data.array([{b: 4}, {b: 5}, {b: 6}]);
|
||||
* const c = tf.data.zip({c: a, d: b});
|
||||
* await c.forEachAsync(e => console.log(JSON.stringify(e)));
|
||||
* ```
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Operations', namespace: 'data'}
|
||||
*/
|
||||
export function zip<O extends tf.TensorContainer>(datasets: DatasetContainer):
|
||||
Dataset<O> {
|
||||
// manually type-check the argument for JS users
|
||||
if (!isIterable(datasets)) {
|
||||
throw new Error('The argument to zip() must be an object or array.');
|
||||
}
|
||||
let size;
|
||||
if (Array.isArray(datasets)) {
|
||||
for (let i = 0; i < datasets.length; i++) {
|
||||
size = size == null ? (datasets[i] as Dataset<O>).size :
|
||||
Math.min(size, (datasets[i] as Dataset<O>).size);
|
||||
}
|
||||
} else if (datasets instanceof Object) {
|
||||
for (const ds in datasets) {
|
||||
size = size == null ? (datasets[ds] as Dataset<O>).size :
|
||||
Math.min(size, (datasets[ds] as Dataset<O>).size);
|
||||
}
|
||||
}
|
||||
return datasetFromIteratorFn<O>(async () => {
|
||||
const streams = await deepMapAndAwaitAll(datasets, d => {
|
||||
if (d instanceof Dataset) {
|
||||
return {value: d.iterator(), recurse: false};
|
||||
} else if (isIterable(d)) {
|
||||
return {value: null, recurse: true};
|
||||
} else {
|
||||
throw new Error(
|
||||
'Leaves of the structure passed to zip() must be Datasets, ' +
|
||||
'not primitives.');
|
||||
}
|
||||
});
|
||||
return iteratorFromZipped<O>(streams, ZipMismatchMode.SHORTEST);
|
||||
}, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* A zip function for use with deepZip, passed via the columnMajorBatch call.
|
||||
*
|
||||
* Accepts an array of identically-structured nested elements and either batches
|
||||
* them (if they are primitives, numeric arrays, or Tensors) or requests
|
||||
* recursion (if not).
|
||||
*/
|
||||
// tslint:disable-next-line:no-any
|
||||
function deepBatchConcat(rows: any[]): DeepMapResult {
|
||||
if (rows === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// use the first item to decide whether to recurse or batch here.
|
||||
const exampleRow = rows[0];
|
||||
|
||||
if (canTensorify(exampleRow)) {
|
||||
// rows is an array of primitives, Tensors, or arrays. Batch them.
|
||||
const value = batchConcat(rows);
|
||||
return {value, recurse: false};
|
||||
}
|
||||
|
||||
// the example row is an object, so recurse into it.
|
||||
return {value: null, recurse: true};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles a list of same-shaped numbers, number arrays, or Tensors
|
||||
* into a single new Tensor where axis 0 is the batch dimension.
|
||||
*/
|
||||
function batchConcat<T extends(TensorLike | tf.Tensor)>(arrays: T[]):
|
||||
tf.Tensor {
|
||||
if (arrays.length === 0) {
|
||||
// We can't return an empty Tensor because we don't know the element shape.
|
||||
throw new Error('Can\'t make a batch of zero elements.');
|
||||
}
|
||||
|
||||
if (arrays[0] instanceof tf.Tensor) {
|
||||
// Input is an array of Tensors
|
||||
return tf.stack(arrays as tf.Tensor[]);
|
||||
} else {
|
||||
// Input is a possibly-nested array of numbers.
|
||||
return tf.tensor(arrays as TensorLike);
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-396
@@ -1,396 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {TensorContainer, util} from '@tensorflow/tfjs-core';
|
||||
import {Dataset} from '../dataset';
|
||||
import {DataSource} from '../datasource';
|
||||
import {LazyIterator} from '../iterators/lazy_iterator';
|
||||
import {ColumnConfig, CSVConfig} from '../types';
|
||||
import {TextLineDataset} from './text_line_dataset';
|
||||
|
||||
const CODE_QUOTE = '"';
|
||||
const STATE_OUT = Symbol('out');
|
||||
const STATE_FIELD = Symbol('field');
|
||||
const STATE_QUOTE = Symbol('quote');
|
||||
const STATE_QUOTE_AFTER_QUOTE = Symbol('quoteafterquote');
|
||||
const STATE_WITHIN_QUOTE_IN_QUOTE = Symbol('quoteinquote');
|
||||
|
||||
/**
|
||||
* Represents a potentially large collection of delimited text records.
|
||||
*
|
||||
* The produced `TensorContainer`s each contain one key-value pair for
|
||||
* every column of the table. When a field is empty in the incoming data, the
|
||||
* resulting value is `undefined`, or throw error if it is required. Values
|
||||
* that can be parsed as numbers are emitted as type `number`, other values
|
||||
* are parsed as `string`.
|
||||
*
|
||||
* The results are not batched.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes', namespace: 'data'}
|
||||
*/
|
||||
export class CSVDataset extends Dataset<TensorContainer> {
|
||||
base: TextLineDataset;
|
||||
private hasHeader = true;
|
||||
private fullColumnNames: string[] = null;
|
||||
private columnNamesValidated = false;
|
||||
private columnConfigs: {[key: string]: ColumnConfig} = null;
|
||||
private configuredColumnsOnly = false;
|
||||
private delimiter = ',';
|
||||
private delimWhitespace = false;
|
||||
|
||||
/**
|
||||
* Returns column names of the csv dataset. If `configuredColumnsOnly` is
|
||||
* true, return column names in `columnConfigs`. If `configuredColumnsOnly` is
|
||||
* false and `columnNames` is provided, `columnNames`. If
|
||||
* `configuredColumnsOnly` is false and `columnNames` is not provided, return
|
||||
* all column names parsed from the csv file. For example usage please go to
|
||||
* `tf.data.csv`.
|
||||
*
|
||||
* @doc {heading: 'Data', subheading: 'Classes'}
|
||||
*/
|
||||
async columnNames() {
|
||||
if (!this.columnNamesValidated) {
|
||||
await this.setColumnNames();
|
||||
}
|
||||
return this.configuredColumnsOnly ? Object.keys(this.columnConfigs) :
|
||||
this.fullColumnNames;
|
||||
}
|
||||
|
||||
/* 1) If `columnNames` is provided as string[], use this string[] as output
|
||||
* keys in corresponding order. The length must match the number of inferred
|
||||
* columns if `hasHeader` is true .
|
||||
* 2) If `columnNames` is not provided, parse header line as `columnNames` if
|
||||
* hasHeader is true. If `hasHeader` is false, throw an error.
|
||||
* 3) If `columnConfigs` is provided, all the keys in `columnConfigs` must
|
||||
* exist in parsed `columnNames`.
|
||||
*/
|
||||
private async setColumnNames() {
|
||||
const columnNamesFromFile = await this.maybeReadHeaderLine();
|
||||
if (!this.fullColumnNames && !columnNamesFromFile) {
|
||||
// Throw an error if columnNames is not provided and no header line.
|
||||
throw new Error(
|
||||
'Column names must be provided if there is no header line.');
|
||||
} else if (this.fullColumnNames && columnNamesFromFile) {
|
||||
// Check provided columnNames match header line.
|
||||
util.assert(
|
||||
columnNamesFromFile.length === this.fullColumnNames.length,
|
||||
() => 'The length of provided columnNames (' +
|
||||
this.fullColumnNames.length.toString() +
|
||||
') does not match the length of the header line read from ' +
|
||||
'file (' + columnNamesFromFile.length.toString() + ').');
|
||||
}
|
||||
if (!this.fullColumnNames) {
|
||||
this.fullColumnNames = columnNamesFromFile;
|
||||
}
|
||||
// Check if there are duplicate column names.
|
||||
const counts: {[key: string]: number} = this.fullColumnNames.reduce(
|
||||
(countAcc: {[key: string]: number}, name) => {
|
||||
countAcc[name] = (countAcc[name] + 1) || 1;
|
||||
return countAcc;
|
||||
},
|
||||
{});
|
||||
const duplicateNames =
|
||||
Object.keys(counts).filter((name) => (counts[name] > 1));
|
||||
util.assert(
|
||||
duplicateNames.length === 0,
|
||||
() => 'Duplicate column names found: ' + duplicateNames.toString());
|
||||
// Check if keys in columnConfigs match columnNames.
|
||||
if (this.columnConfigs) {
|
||||
for (const key of Object.keys(this.columnConfigs)) {
|
||||
const index = this.fullColumnNames.indexOf(key);
|
||||
if (index === -1) {
|
||||
throw new Error(
|
||||
'The key "' + key +
|
||||
'" provided in columnConfigs does not match any of the column ' +
|
||||
'names (' + this.fullColumnNames.toString() + ').');
|
||||
}
|
||||
}
|
||||
}
|
||||
this.columnNamesValidated = true;
|
||||
}
|
||||
|
||||
private async maybeReadHeaderLine() {
|
||||
if (this.hasHeader) {
|
||||
const iter = await this.base.iterator();
|
||||
const firstElement = await iter.next();
|
||||
if (firstElement.done) {
|
||||
throw new Error('No data was found for CSV parsing.');
|
||||
}
|
||||
const firstLine: string = firstElement.value;
|
||||
const headers = this.parseRow(firstLine, false);
|
||||
return headers;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `CSVDataset`.
|
||||
*
|
||||
* @param input A `DataSource` providing a chunked, UTF8-encoded byte stream.
|
||||
* @param csvConfig (Optional) A CSVConfig object that contains configurations
|
||||
* of reading and decoding from CSV file(s).
|
||||
*
|
||||
* hasHeader: (Optional) A boolean value that indicates whether the first
|
||||
* row of provided CSV file is a header line with column names, and should
|
||||
* not be included in the data. Defaults to `true`.
|
||||
*
|
||||
* columnNames: (Optional) A list of strings that corresponds to
|
||||
* the CSV column names, in order. If provided, it ignores the column
|
||||
* names inferred from the header row. If not provided, infers the column
|
||||
* names from the first row of the records. If hasHeader is false and
|
||||
* columnNames is not provided, this method throws an error.
|
||||
*
|
||||
* columnConfigs: (Optional) A dictionary whose key is column names, value
|
||||
* is an object stating if this column is required, column's data type,
|
||||
* default value, and if this column is label. If provided, keys must
|
||||
* correspond to names provided in columnNames or inferred from the file
|
||||
* header lines. If isLabel is true any column, returns an array of two
|
||||
* items: the first item is a dict of features key/value pairs, the second
|
||||
* item is a dict of labels key/value pairs. If no feature is marked as
|
||||
* label, returns a dict of features only.
|
||||
*
|
||||
* configuredColumnsOnly (Optional) If true, only columns provided in
|
||||
* columnConfigs will be parsed and provided during iteration.
|
||||
*
|
||||
* delimiter (Optional) The string used to parse each line of the input
|
||||
* file. Defaults to `,`.
|
||||
*/
|
||||
constructor(protected readonly input: DataSource, csvConfig?: CSVConfig) {
|
||||
super();
|
||||
this.base = new TextLineDataset(input);
|
||||
if (!csvConfig) {
|
||||
csvConfig = {};
|
||||
}
|
||||
this.hasHeader = csvConfig.hasHeader === false ? false : true;
|
||||
this.fullColumnNames = csvConfig.columnNames;
|
||||
this.columnConfigs = csvConfig.columnConfigs;
|
||||
this.configuredColumnsOnly = csvConfig.configuredColumnsOnly;
|
||||
if (csvConfig.delimWhitespace) {
|
||||
util.assert(
|
||||
csvConfig.delimiter == null,
|
||||
() =>
|
||||
'Delimiter should not be provided when delimWhitespace is true.');
|
||||
this.delimWhitespace = true;
|
||||
this.delimiter = ' ';
|
||||
} else {
|
||||
this.delimiter = csvConfig.delimiter ? csvConfig.delimiter : ',';
|
||||
}
|
||||
}
|
||||
|
||||
async iterator(): Promise<LazyIterator<TensorContainer>> {
|
||||
if (!this.columnNamesValidated) {
|
||||
await this.setColumnNames();
|
||||
}
|
||||
let lines = await this.base.iterator();
|
||||
if (this.hasHeader) {
|
||||
// We previously read the first line to get the columnNames.
|
||||
// Now that we're providing data, skip it.
|
||||
lines = lines.skip(1);
|
||||
}
|
||||
return lines.map(x => this.makeDataElement(x));
|
||||
}
|
||||
|
||||
makeDataElement(line: string): TensorContainer {
|
||||
const values = this.parseRow(line);
|
||||
const features: {[key: string]: TensorContainer} = {};
|
||||
const labels: {[key: string]: TensorContainer} = {};
|
||||
|
||||
for (let i = 0; i < this.fullColumnNames.length; i++) {
|
||||
const key = this.fullColumnNames[i];
|
||||
const config = this.columnConfigs ? this.columnConfigs[key] : null;
|
||||
if (this.configuredColumnsOnly && !config) {
|
||||
// This column is not selected.
|
||||
continue;
|
||||
} else {
|
||||
const value = values[i];
|
||||
let parsedValue = null;
|
||||
if (value === '') {
|
||||
// If default value is provided, use it. If default value is not
|
||||
// provided, set as undefined.
|
||||
if (config && config.default !== undefined) {
|
||||
parsedValue = config.default;
|
||||
} else if (config && (config.required || config.isLabel)) {
|
||||
throw new Error(
|
||||
`Required column ${key} is empty in this line: ${line}`);
|
||||
} else {
|
||||
parsedValue = undefined;
|
||||
}
|
||||
} else {
|
||||
// A value is present, so parse it based on type
|
||||
const valueAsNum = Number(value);
|
||||
if (isNaN(valueAsNum)) {
|
||||
// The value is a string and this column is declared as boolean
|
||||
// in config, parse it as boolean.
|
||||
if (config && config.dtype === 'bool') {
|
||||
parsedValue = this.getBoolean(value);
|
||||
} else {
|
||||
// Set value as string
|
||||
parsedValue = value;
|
||||
}
|
||||
} else if (!config || !config.dtype) {
|
||||
// If this value is a number and no type config is provided, return
|
||||
// it as number.
|
||||
parsedValue = valueAsNum;
|
||||
} else {
|
||||
// If this value is a number and data type is provided, parse it
|
||||
// according to provided data type.
|
||||
switch (config.dtype) {
|
||||
case 'float32':
|
||||
parsedValue = valueAsNum;
|
||||
break;
|
||||
case 'int32':
|
||||
parsedValue = Math.floor(valueAsNum);
|
||||
break;
|
||||
case 'bool':
|
||||
parsedValue = this.getBoolean(value);
|
||||
break;
|
||||
default:
|
||||
parsedValue = valueAsNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if this column is label.
|
||||
(config && config.isLabel) ? labels[key] = parsedValue :
|
||||
features[key] = parsedValue;
|
||||
}
|
||||
}
|
||||
// If label exists, return an object of features and labels as {xs:features,
|
||||
// ys:labels}, otherwise return features only.
|
||||
if (Object.keys(labels).length === 0) {
|
||||
return features;
|
||||
|
||||
} else {
|
||||
return {xs: features, ys: labels};
|
||||
}
|
||||
}
|
||||
|
||||
private getBoolean(value: string): number {
|
||||
if (value === '1' || value.toLowerCase() === 'true') {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// adapted from https://beta.observablehq.com/@mbostock/streaming-csv
|
||||
private parseRow(line: string, validateElementCount = true): string[] {
|
||||
const result: string[] = [];
|
||||
let readOffset = 0;
|
||||
const readLength = line.length;
|
||||
let currentState = STATE_OUT;
|
||||
// Goes through the line to parse quote.
|
||||
for (let i = 0; i < readLength; i++) {
|
||||
switch (currentState) {
|
||||
// Before enter a new field
|
||||
case STATE_OUT:
|
||||
switch (line.charAt(i)) {
|
||||
// Enter a quoted field
|
||||
case CODE_QUOTE:
|
||||
readOffset = i + 1;
|
||||
currentState = STATE_QUOTE;
|
||||
break;
|
||||
// Read an empty field
|
||||
case this.delimiter:
|
||||
readOffset = i + 1;
|
||||
// If delimiter is white space and configured to collapse
|
||||
// multiple white spaces, ignore this white space.
|
||||
if (this.delimiter === ' ' && this.delimWhitespace) {
|
||||
break;
|
||||
}
|
||||
result.push('');
|
||||
currentState = STATE_OUT;
|
||||
break;
|
||||
// Enter an unquoted field
|
||||
default:
|
||||
currentState = STATE_FIELD;
|
||||
readOffset = i;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// In an unquoted field
|
||||
case STATE_FIELD:
|
||||
switch (line.charAt(i)) {
|
||||
// Exit an unquoted field, add it to result
|
||||
case this.delimiter:
|
||||
result.push(line.substring(readOffset, i));
|
||||
currentState = STATE_OUT;
|
||||
readOffset = i + 1;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
break;
|
||||
// In a quoted field
|
||||
case STATE_QUOTE:
|
||||
switch (line.charAt(i)) {
|
||||
// Read a quote after a quote
|
||||
case CODE_QUOTE:
|
||||
currentState = STATE_QUOTE_AFTER_QUOTE;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
break;
|
||||
// This state means it's right after a second quote in a field
|
||||
case STATE_QUOTE_AFTER_QUOTE:
|
||||
switch (line.charAt(i)) {
|
||||
// Finished a quoted field
|
||||
case this.delimiter:
|
||||
result.push(line.substring(readOffset, i - 1));
|
||||
currentState = STATE_OUT;
|
||||
readOffset = i + 1;
|
||||
break;
|
||||
// Finished a quoted part in a quoted field
|
||||
case CODE_QUOTE:
|
||||
currentState = STATE_QUOTE;
|
||||
break;
|
||||
// In a quoted part in a quoted field
|
||||
default:
|
||||
currentState = STATE_WITHIN_QUOTE_IN_QUOTE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case STATE_WITHIN_QUOTE_IN_QUOTE:
|
||||
switch (line.charAt(i)) {
|
||||
// Exit a quoted part in a quoted field
|
||||
case CODE_QUOTE:
|
||||
currentState = STATE_QUOTE;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
// Adds last item based on if it is quoted.
|
||||
if (currentState === STATE_QUOTE_AFTER_QUOTE) {
|
||||
result.push(line.substring(readOffset, readLength - 1));
|
||||
} else {
|
||||
result.push(line.substring(readOffset));
|
||||
}
|
||||
// Check if each row has the same number of elements as column names.
|
||||
if (validateElementCount && result.length !== this.fullColumnNames.length) {
|
||||
throw new Error(`Invalid row in csv file. Should have ${
|
||||
this.fullColumnNames.length} elements in a row, but got ${result}`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(soergel): add more basic datasets for parity with tf.data
|
||||
// tf.data.FixedLengthRecordDataset()
|
||||
// tf.data.TFRecordDataset()
|
||||
Generated
Vendored
-50
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {Dataset} from '../dataset';
|
||||
import {DataSource} from '../datasource';
|
||||
import {LazyIterator} from '../iterators/lazy_iterator';
|
||||
|
||||
/**
|
||||
* Represents a potentially large collection of text lines.
|
||||
*
|
||||
* The results are not batched.
|
||||
*/
|
||||
export class TextLineDataset extends Dataset<string> {
|
||||
/**
|
||||
* Create a `TextLineDataset`.
|
||||
*
|
||||
* @param input A `DataSource` providing a chunked, UTF8-encoded byte stream.
|
||||
*/
|
||||
constructor(protected readonly input: DataSource) {
|
||||
super();
|
||||
}
|
||||
|
||||
async iterator(): Promise<LazyIterator<string>> {
|
||||
const inputIterator = await this.input.iterator();
|
||||
const utf8Iterator = inputIterator.decodeUTF8();
|
||||
const lineIterator = utf8Iterator.split('\n').map(line => {
|
||||
// Windows/DOS format text file has extra line breaker at the end of line.
|
||||
if (line.endsWith('\r')) {
|
||||
line = line.slice(0, -1);
|
||||
}
|
||||
return line;
|
||||
});
|
||||
return lineIterator;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-42
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {ByteChunkIterator} from './iterators/byte_chunk_iterator';
|
||||
|
||||
/**
|
||||
* Represents a data source readable as a stream of binary data chunks.
|
||||
*
|
||||
* Because `Dataset`s can be read repeatedly (via `Dataset.iterator()`), this
|
||||
* provides a means to repeatedly create streams from the underlying data
|
||||
* sources.
|
||||
*/
|
||||
export abstract class DataSource {
|
||||
/**
|
||||
* Obtain a new stream of binary data chunks.
|
||||
*
|
||||
* Starts the new stream from the beginning of the data source, even if other
|
||||
* streams have been obtained previously.
|
||||
*/
|
||||
abstract async iterator(): Promise<ByteChunkIterator>;
|
||||
|
||||
// TODO(soergel): consider chainable Dataset construction here
|
||||
}
|
||||
|
||||
// TODO(soergel): consider convenience factory functions here
|
||||
// in combination with chainable source->dataset above, e.g.:
|
||||
// tf.data.url(...).asCsvDataset().shuffle().batch()
|
||||
Generated
Vendored
-25
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
export {array, Dataset, zip} from './dataset';
|
||||
export {CSVDataset} from './datasets/csv_dataset';
|
||||
export {TextLineDataset} from './datasets/text_line_dataset';
|
||||
export {csv, func, generator, microphone, webcam} from './readers';
|
||||
export {FileDataSource} from './sources/file_data_source';
|
||||
export {URLDataSource} from './sources/url_data_source';
|
||||
export {ColumnConfig, MicrophoneConfig, WebcamConfig} from './types';
|
||||
export {version as version_data} from './version';
|
||||
Generated
Vendored
-126
@@ -1,126 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {env} from '@tensorflow/tfjs-core';
|
||||
import {LazyIterator, OneToManyIterator} from './lazy_iterator';
|
||||
import {StringIterator} from './string_iterator';
|
||||
|
||||
export abstract class ByteChunkIterator extends LazyIterator<Uint8Array> {
|
||||
/**
|
||||
* Decode a stream of UTF8-encoded byte arrays to a stream of strings.
|
||||
*
|
||||
* The byte arrays producetd from the ByteChunkIterator on which this is
|
||||
* called will be interpreted as concatenated. No assumptions are made about
|
||||
* the boundaries of the incoming chunks, so a multi-byte UTF8 encoding of a
|
||||
* character may span the boundary between chunks. This naturally happens,
|
||||
* for instance, when reading fixed-size byte arrays from a file.
|
||||
*/
|
||||
decodeUTF8(): StringIterator {
|
||||
return new Utf8Iterator(this);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// The following private classes serve to implement the chainable methods
|
||||
// on ByteChunkIterator. Unfortunately they can't be placed in separate files,
|
||||
// due to resulting trouble with circular imports.
|
||||
// ============================================================================
|
||||
|
||||
// We wanted multiple inheritance, e.g.
|
||||
// class Utf8Iterator extends QueueIterator<string>, StringIterator
|
||||
// but the TypeScript mixin approach is a bit hacky, so we take this adapter
|
||||
// approach instead.
|
||||
|
||||
class Utf8Iterator extends StringIterator {
|
||||
private impl: Utf8IteratorImpl;
|
||||
|
||||
constructor(protected upstream: LazyIterator<Uint8Array>) {
|
||||
super();
|
||||
this.impl = new Utf8IteratorImpl(upstream);
|
||||
}
|
||||
|
||||
summary() {
|
||||
return this.impl.summary();
|
||||
}
|
||||
|
||||
async next() {
|
||||
return this.impl.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a stream of UTF8-encoded byte arrays to a stream of strings.
|
||||
*
|
||||
* This is tricky because the incoming byte array boundaries may disrupt a
|
||||
* multi-byte UTF8 character. Thus any incomplete character data at the end of
|
||||
* a chunk must be carried over and prepended to the next chunk before
|
||||
* decoding. Luckily with native decoder, TextDecoder in browser and
|
||||
* string_decoder in node, byte array boundaries are handled automatically.
|
||||
*
|
||||
* In the context of an input pipeline for machine learning, UTF8 decoding is
|
||||
* needed to parse text files containing training examples or prediction
|
||||
* requests (e.g., formatted as CSV or JSON). We cannot use the built-in
|
||||
* decoding provided by FileReader.readAsText() because here we are in a
|
||||
* streaming context, which FileReader does not support.
|
||||
*
|
||||
* @param upstream A `LazyIterator` of `Uint8Arrays` containing UTF8-encoded
|
||||
* text, which should be interpreted as concatenated. No assumptions are
|
||||
* made about the boundaries of the incoming chunks, so a multi-byte UTF8
|
||||
* encoding of a character may span the boundary between chunks. This
|
||||
* naturally happens, for instance, when reading fixed-size byte arrays from a
|
||||
* file.
|
||||
*/
|
||||
class Utf8IteratorImpl extends OneToManyIterator<string> {
|
||||
// `decoder` as `any` here to dynamically assign value based on the
|
||||
// environment.
|
||||
// tslint:disable-next-line:no-any
|
||||
decoder: any;
|
||||
|
||||
constructor(protected readonly upstream: LazyIterator<Uint8Array>) {
|
||||
super();
|
||||
if (env().get('IS_BROWSER')) {
|
||||
this.decoder = new TextDecoder('utf-8');
|
||||
} else {
|
||||
// tslint:disable-next-line:no-require-imports
|
||||
const {StringDecoder} = require('string_decoder');
|
||||
this.decoder = new StringDecoder('utf8');
|
||||
}
|
||||
}
|
||||
summary() {
|
||||
return `${this.upstream.summary()} -> Utf8`;
|
||||
}
|
||||
|
||||
async pump(): Promise<boolean> {
|
||||
const chunkResult = await this.upstream.next();
|
||||
let chunk;
|
||||
if (chunkResult.done) {
|
||||
return false;
|
||||
} else {
|
||||
chunk = chunkResult.value;
|
||||
}
|
||||
|
||||
let text: string;
|
||||
if (env().get('IS_BROWSER')) {
|
||||
text = this.decoder.decode(chunk, {stream: true});
|
||||
} else {
|
||||
text = this.decoder.write(Buffer.from(chunk.buffer));
|
||||
}
|
||||
this.outputQueue.push(text);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-110
@@ -1,110 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
// inspired by https://github.com/maxogden/filereader-stream
|
||||
import {env, util} from '@tensorflow/tfjs-core';
|
||||
import {FileElement} from '../types';
|
||||
import {ByteChunkIterator} from './byte_chunk_iterator';
|
||||
|
||||
export interface FileChunkIteratorOptions {
|
||||
/** The byte offset at which to begin reading the File or Blob. Default 0. */
|
||||
offset?: number;
|
||||
/** The number of bytes to read at a time. Default 1MB. */
|
||||
chunkSize?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a stream of chunks from a File, Blob, or Uint8Array.
|
||||
* @param file The source File, Blob or Uint8Array.
|
||||
* @param options Optional settings controlling file reading.
|
||||
* @returns a lazy Iterator of Uint8Arrays containing sequential chunks of the
|
||||
* input File, Blob or Uint8Array.
|
||||
*/
|
||||
export class FileChunkIterator extends ByteChunkIterator {
|
||||
offset: number;
|
||||
chunkSize: number;
|
||||
|
||||
constructor(
|
||||
protected file: FileElement,
|
||||
protected options: FileChunkIteratorOptions = {}) {
|
||||
super();
|
||||
util.assert(
|
||||
(file instanceof Uint8Array) ||
|
||||
(env().get('IS_BROWSER') ?
|
||||
(file instanceof File || file instanceof Blob) :
|
||||
false),
|
||||
() => 'FileChunkIterator only supports File, Blob and Uint8Array ' +
|
||||
'right now.');
|
||||
this.offset = options.offset || 0;
|
||||
// default 1MB chunk has tolerable perf on large files
|
||||
this.chunkSize = options.chunkSize || 1024 * 1024;
|
||||
}
|
||||
|
||||
summary() {
|
||||
return `FileChunks ${this.file}`;
|
||||
}
|
||||
|
||||
async next(): Promise<IteratorResult<Uint8Array>> {
|
||||
if (this.offset >= ((this.file instanceof Uint8Array) ?
|
||||
this.file.byteLength :
|
||||
this.file.size)) {
|
||||
return {value: null, done: true};
|
||||
}
|
||||
const chunk = new Promise<Uint8Array>((resolve, reject) => {
|
||||
const end = this.offset + this.chunkSize;
|
||||
if (this.file instanceof Uint8Array) {
|
||||
// Note if end > this.uint8Array.byteLength, we just get a small last
|
||||
// chunk.
|
||||
resolve(new Uint8Array(this.file.slice(this.offset, end)));
|
||||
} else {
|
||||
// This branch assumes that this.file type is File or Blob, which
|
||||
// means it is in the browser environment.
|
||||
|
||||
// TODO(soergel): is this a performance issue?
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = (event) => {
|
||||
let data: string|ArrayBuffer|Uint8Array = fileReader.result;
|
||||
// Not sure we can trust the return type of
|
||||
// FileReader.readAsArrayBuffer See e.g.
|
||||
// https://github.com/node-file-api/FileReader/issues/2
|
||||
if (data instanceof ArrayBuffer) {
|
||||
data = new Uint8Array(data);
|
||||
}
|
||||
if (!(data instanceof Uint8Array)) {
|
||||
return reject(new TypeError('FileReader returned unknown type.'));
|
||||
}
|
||||
resolve(data);
|
||||
};
|
||||
fileReader.onabort = (event) => {
|
||||
return reject(new Error('Aborted'));
|
||||
};
|
||||
fileReader.onerror = (event) => {
|
||||
return reject(new Error(event.type));
|
||||
};
|
||||
// TODO(soergel): better handle onabort, onerror
|
||||
// Note if end > this.file.size, we just get a small last chunk.
|
||||
const slice = this.file.slice(this.offset, end);
|
||||
// We can't use readAsText here (even if we know the file is text)
|
||||
// because the slice boundary may fall within a multi-byte character.
|
||||
fileReader.readAsArrayBuffer(slice);
|
||||
}
|
||||
this.offset = end;
|
||||
});
|
||||
return {value: (await chunk), done: false};
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-1190
File diff suppressed because it is too large.
Load diff
Generated
Vendored
-234
@@ -1,234 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {env, Tensor, tensor, Tensor2D, Tensor3D, TensorContainer, util} from '@tensorflow/tfjs-core';
|
||||
import {MicrophoneConfig} from '../types';
|
||||
import {LazyIterator} from './lazy_iterator';
|
||||
|
||||
/**
|
||||
* Provide a stream of tensors from microphone audio stream. The tensors are
|
||||
* representing audio data as frequency-domain spectrogram generated with
|
||||
* browser's native FFT. Tensors representing time-domain waveform is available
|
||||
* based on configuration. Only works in browser environment.
|
||||
*/
|
||||
export class MicrophoneIterator extends LazyIterator<TensorContainer> {
|
||||
private isClosed = false;
|
||||
private stream: MediaStream;
|
||||
private readonly fftSize: number;
|
||||
private readonly columnTruncateLength: number;
|
||||
private freqData: Float32Array;
|
||||
private timeData: Float32Array;
|
||||
private readonly numFrames: number;
|
||||
private analyser: AnalyserNode;
|
||||
private audioContext: AudioContext;
|
||||
private sampleRateHz: number;
|
||||
private readonly audioTrackConstraints: MediaTrackConstraints;
|
||||
private readonly smoothingTimeConstant: number;
|
||||
private readonly includeSpectrogram: boolean;
|
||||
private readonly includeWaveform: boolean;
|
||||
|
||||
private constructor(protected readonly microphoneConfig: MicrophoneConfig) {
|
||||
super();
|
||||
this.fftSize = microphoneConfig.fftSize || 1024;
|
||||
const fftSizeLog2 = Math.log2(this.fftSize);
|
||||
if (this.fftSize < 0 || fftSizeLog2 < 4 || fftSizeLog2 > 14 ||
|
||||
!Number.isInteger(fftSizeLog2)) {
|
||||
throw new Error(
|
||||
`Invalid fftSize: it must be a power of 2 between ` +
|
||||
`2 to 4 and 2 to 14, but got ${this.fftSize}`);
|
||||
}
|
||||
|
||||
this.numFrames = microphoneConfig.numFramesPerSpectrogram || 43;
|
||||
this.sampleRateHz = microphoneConfig.sampleRateHz;
|
||||
this.columnTruncateLength =
|
||||
microphoneConfig.columnTruncateLength || this.fftSize;
|
||||
this.audioTrackConstraints = microphoneConfig.audioTrackConstraints;
|
||||
this.smoothingTimeConstant = microphoneConfig.smoothingTimeConstant || 0;
|
||||
|
||||
this.includeSpectrogram =
|
||||
microphoneConfig.includeSpectrogram === false ? false : true;
|
||||
this.includeWaveform =
|
||||
microphoneConfig.includeWaveform === true ? true : false;
|
||||
if (!this.includeSpectrogram && !this.includeWaveform) {
|
||||
throw new Error(
|
||||
'Both includeSpectrogram and includeWaveform are false. ' +
|
||||
'At least one type of data should be returned.');
|
||||
}
|
||||
}
|
||||
|
||||
summary() {
|
||||
return `microphone`;
|
||||
}
|
||||
|
||||
// Construct a MicrophoneIterator and start the audio stream.
|
||||
static async create(microphoneConfig: MicrophoneConfig = {}) {
|
||||
if (env().get('IS_NODE')) {
|
||||
throw new Error(
|
||||
'microphone API is only supported in browser environment.');
|
||||
}
|
||||
|
||||
const microphoneIterator = new MicrophoneIterator(microphoneConfig);
|
||||
|
||||
// Call async function start() to initialize the audio stream.
|
||||
await microphoneIterator.start();
|
||||
|
||||
return microphoneIterator;
|
||||
}
|
||||
|
||||
// Start the audio stream and FFT.
|
||||
async start(): Promise<void> {
|
||||
try {
|
||||
this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: this.audioTrackConstraints == null ? true :
|
||||
this.audioTrackConstraints,
|
||||
video: false
|
||||
});
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Error thrown while initializing video stream: ${e.message}`);
|
||||
}
|
||||
|
||||
if (!this.stream) {
|
||||
throw new Error('Could not obtain audio from microphone.');
|
||||
}
|
||||
|
||||
const ctxConstructor =
|
||||
// tslint:disable-next-line:no-any
|
||||
(window as any).AudioContext || (window as any).webkitAudioContext;
|
||||
this.audioContext = new ctxConstructor();
|
||||
|
||||
if (!this.sampleRateHz) {
|
||||
// If sample rate is not provided, use the available sample rate on
|
||||
// device.
|
||||
this.sampleRateHz = this.audioContext.sampleRate;
|
||||
} else if (this.audioContext.sampleRate !== this.sampleRateHz) {
|
||||
throw new Error(
|
||||
`Mismatch in sampling rate: ` +
|
||||
`Expected: ${this.sampleRateHz}; ` +
|
||||
`Actual: ${this.audioContext.sampleRate}`);
|
||||
}
|
||||
|
||||
const streamSource = this.audioContext.createMediaStreamSource(this.stream);
|
||||
this.analyser = this.audioContext.createAnalyser();
|
||||
this.analyser.fftSize = this.fftSize * 2;
|
||||
this.analyser.smoothingTimeConstant = this.smoothingTimeConstant;
|
||||
streamSource.connect(this.analyser);
|
||||
this.freqData = new Float32Array(this.fftSize);
|
||||
this.timeData = new Float32Array(this.fftSize);
|
||||
return;
|
||||
}
|
||||
|
||||
async next(): Promise<IteratorResult<TensorContainer>> {
|
||||
if (this.isClosed) {
|
||||
return {value: null, done: true};
|
||||
}
|
||||
|
||||
let spectrogramTensor: Tensor;
|
||||
let waveformTensor: Tensor;
|
||||
|
||||
const audioDataQueue = await this.getAudioData();
|
||||
if (this.includeSpectrogram) {
|
||||
const freqData = this.flattenQueue(audioDataQueue.freqDataQueue);
|
||||
spectrogramTensor = this.getTensorFromAudioDataArray(
|
||||
freqData, [this.numFrames, this.columnTruncateLength, 1]);
|
||||
}
|
||||
if (this.includeWaveform) {
|
||||
const timeData = this.flattenQueue(audioDataQueue.timeDataQueue);
|
||||
waveformTensor = this.getTensorFromAudioDataArray(
|
||||
timeData, [this.numFrames * this.fftSize, 1]);
|
||||
}
|
||||
|
||||
return {
|
||||
value: {'spectrogram': spectrogramTensor, 'waveform': waveformTensor},
|
||||
done: false
|
||||
};
|
||||
}
|
||||
|
||||
// Capture one result from the audio stream, and extract the value from
|
||||
// iterator.next() result.
|
||||
async capture(): Promise<{spectrogram: Tensor3D, waveform: Tensor2D}> {
|
||||
return (await this.next()).value as
|
||||
{spectrogram: Tensor3D, waveform: Tensor2D};
|
||||
}
|
||||
|
||||
private async getAudioData():
|
||||
Promise<{freqDataQueue: Float32Array[], timeDataQueue: Float32Array[]}> {
|
||||
const freqDataQueue: Float32Array[] = [];
|
||||
const timeDataQueue: Float32Array[] = [];
|
||||
let currentFrames = 0;
|
||||
return new Promise(resolve => {
|
||||
const intervalID = setInterval(() => {
|
||||
if (this.includeSpectrogram) {
|
||||
this.analyser.getFloatFrequencyData(this.freqData);
|
||||
// If the audio stream is initializing, return empty queue.
|
||||
if (this.freqData[0] === -Infinity) {
|
||||
resolve({freqDataQueue, timeDataQueue});
|
||||
}
|
||||
freqDataQueue.push(this.freqData.slice(0, this.columnTruncateLength));
|
||||
}
|
||||
if (this.includeWaveform) {
|
||||
this.analyser.getFloatTimeDomainData(this.timeData);
|
||||
timeDataQueue.push(this.timeData.slice());
|
||||
}
|
||||
|
||||
// Clean interval and return when all frames have been collected
|
||||
if (++currentFrames === this.numFrames) {
|
||||
clearInterval(intervalID);
|
||||
resolve({freqDataQueue, timeDataQueue});
|
||||
}
|
||||
}, this.fftSize / this.sampleRateHz * 1e3);
|
||||
});
|
||||
}
|
||||
|
||||
// Stop the audio stream and pause the iterator.
|
||||
stop(): void {
|
||||
if (!this.isClosed) {
|
||||
this.isClosed = true;
|
||||
this.analyser.disconnect();
|
||||
this.audioContext.close();
|
||||
if (this.stream != null && this.stream.getTracks().length > 0) {
|
||||
this.stream.getTracks()[0].stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override toArray() function to prevent collecting.
|
||||
toArray(): Promise<Tensor[]> {
|
||||
throw new Error('Can not convert infinite audio stream to array.');
|
||||
}
|
||||
|
||||
// Return audio sampling rate in Hz
|
||||
getSampleRate(): number {
|
||||
return this.sampleRateHz;
|
||||
}
|
||||
|
||||
private flattenQueue(queue: Float32Array[]): Float32Array {
|
||||
const frameSize = queue[0].length;
|
||||
const freqData = new Float32Array(queue.length * frameSize);
|
||||
queue.forEach((data, i) => freqData.set(data, i * frameSize));
|
||||
return freqData;
|
||||
}
|
||||
|
||||
private getTensorFromAudioDataArray(freqData: Float32Array, shape: number[]):
|
||||
Tensor {
|
||||
const vals = new Float32Array(util.sizeFromShape(shape));
|
||||
// If the data is less than the output shape, the rest is padded with zeros.
|
||||
vals.set(freqData, vals.length - freqData.length);
|
||||
return tensor(vals, shape);
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-112
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {LazyIterator, OneToManyIterator} from './lazy_iterator';
|
||||
|
||||
export abstract class StringIterator extends LazyIterator<string> {
|
||||
/**
|
||||
* Splits a string stream on a given separator.
|
||||
*
|
||||
* It is assumed that the incoming chunk boundaries have no semantic meaning,
|
||||
* so conceptually the incoming stream is treated simply as the concatenation
|
||||
* of its elements.
|
||||
*
|
||||
* The outgoing stream provides chunks corresponding to the results of the
|
||||
* standard string split() operation (even if such a chunk spanned incoming
|
||||
* chunks). The separators are not included.
|
||||
*
|
||||
* A typical usage is to split a text file (represented as a stream with
|
||||
* arbitrary chunk boundaries) into lines.
|
||||
*
|
||||
* @param upstream A readable stream of strings that can be treated as
|
||||
* concatenated.
|
||||
* @param separator A character to split on.
|
||||
*/
|
||||
split(separator: string): StringIterator {
|
||||
return new SplitIterator(this, separator);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// The following private classes serve to implement the chainable methods
|
||||
// on StringIterator. Unfortunately they can't be placed in separate files, due
|
||||
// to resulting trouble with circular imports.
|
||||
// ============================================================================
|
||||
|
||||
// We wanted multiple inheritance, e.g.
|
||||
// class SplitIterator extends QueueIterator<string>, StringIterator
|
||||
// but the TypeScript mixin approach is a bit hacky, so we take this adapter
|
||||
// approach instead.
|
||||
|
||||
class SplitIterator extends StringIterator {
|
||||
private impl: SplitIteratorImpl;
|
||||
|
||||
constructor(protected upstream: LazyIterator<string>, separator: string) {
|
||||
super();
|
||||
this.impl = new SplitIteratorImpl(upstream, separator);
|
||||
}
|
||||
|
||||
summary() {
|
||||
return this.impl.summary();
|
||||
}
|
||||
|
||||
async next() {
|
||||
return this.impl.next();
|
||||
}
|
||||
}
|
||||
|
||||
class SplitIteratorImpl extends OneToManyIterator<string> {
|
||||
// A partial string at the end of an upstream chunk
|
||||
carryover = '';
|
||||
|
||||
constructor(
|
||||
protected upstream: LazyIterator<string>, protected separator: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
summary() {
|
||||
return `${this.upstream.summary()} -> Split('${this.separator}')`;
|
||||
}
|
||||
|
||||
async pump(): Promise<boolean> {
|
||||
const chunkResult = await this.upstream.next();
|
||||
if (chunkResult.done) {
|
||||
if (this.carryover === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pretend that the pump succeeded in order to emit the small last batch.
|
||||
// The next pump() call will actually fail.
|
||||
this.outputQueue.push(this.carryover);
|
||||
this.carryover = '';
|
||||
return true;
|
||||
}
|
||||
const lines = chunkResult.value.split(this.separator);
|
||||
// Note the behavior: " ab ".split(' ') === ['', 'ab', '']
|
||||
// Thus the carryover may be '' if the separator falls on a chunk
|
||||
// boundary; this produces the correct result.
|
||||
|
||||
lines[0] = this.carryover + lines[0];
|
||||
for (const line of lines.slice(0, -1)) {
|
||||
this.outputQueue.push(line);
|
||||
}
|
||||
this.carryover = lines[lines.length - 1];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-62
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {util} from '@tensorflow/tfjs-core';
|
||||
import {FileChunkIterator, FileChunkIteratorOptions} from './file_chunk_iterator';
|
||||
|
||||
/**
|
||||
* Provide a stream of chunks from a URL.
|
||||
*
|
||||
* Note this class first downloads the entire file into memory before providing
|
||||
* the first element from the stream. This is because the Fetch API does not
|
||||
* yet reliably provide a reader stream for the response body.
|
||||
*/
|
||||
export async function urlChunkIterator(
|
||||
url: RequestInfo, options: FileChunkIteratorOptions = {}) {
|
||||
let urlString;
|
||||
let requestInit;
|
||||
if ((typeof url) === 'string') {
|
||||
urlString = url as string;
|
||||
} else {
|
||||
urlString = (url as Request).url;
|
||||
requestInit = getRequestInitFromRequest(url as Request);
|
||||
}
|
||||
const response = await util.fetch(urlString, requestInit);
|
||||
if (response.ok) {
|
||||
const uint8Array = new Uint8Array(await response.arrayBuffer());
|
||||
return new FileChunkIterator(uint8Array, options);
|
||||
} else {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate RequestInit from Request to match tf.util.fetch signature.
|
||||
const getRequestInitFromRequest = (request: Request) => {
|
||||
const init = {
|
||||
method: request.method,
|
||||
headers: request.headers,
|
||||
body: request.body,
|
||||
mode: request.mode,
|
||||
credentials: request.credentials,
|
||||
cache: request.cache,
|
||||
redirect: request.redirect,
|
||||
referrer: request.referrer,
|
||||
integrity: request.integrity,
|
||||
};
|
||||
return init;
|
||||
};
|
||||
Generated
Vendored
-223
@@ -1,223 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {browser, cast, env, expandDims, image, reshape, tensor1d, Tensor1D, tensor2d, Tensor2D, Tensor3D, Tensor4D, tidy, util} from '@tensorflow/tfjs-core';
|
||||
import {WebcamConfig} from '../types';
|
||||
import {LazyIterator} from './lazy_iterator';
|
||||
|
||||
/**
|
||||
* Provide a stream of image tensors from webcam video stream. Only works in
|
||||
* browser environment.
|
||||
*/
|
||||
export class WebcamIterator extends LazyIterator<Tensor3D> {
|
||||
private isClosed = true;
|
||||
private stream: MediaStream;
|
||||
private resize = false;
|
||||
private cropSize: [number, number];
|
||||
private cropBox: Tensor2D;
|
||||
private cropBoxInd: Tensor1D;
|
||||
|
||||
private constructor(
|
||||
protected readonly webcamVideoElement: HTMLVideoElement,
|
||||
protected readonly webcamConfig: WebcamConfig) {
|
||||
super();
|
||||
if (this.needToResize()) {
|
||||
this.resize = true;
|
||||
this.cropSize =
|
||||
[this.webcamConfig.resizeHeight, this.webcamConfig.resizeWidth];
|
||||
this.cropBoxInd = tensor1d([0], 'int32');
|
||||
if (this.webcamConfig.centerCrop) {
|
||||
// Calculate the box based on resizing shape.
|
||||
const widthCroppingRatio =
|
||||
this.webcamConfig.resizeWidth * 1.0 / this.webcamVideoElement.width;
|
||||
const heightCroppingRatio = this.webcamConfig.resizeHeight * 1.0 /
|
||||
this.webcamVideoElement.height;
|
||||
const widthCropStart = (1 - widthCroppingRatio) / 2;
|
||||
const heightCropStart = (1 - heightCroppingRatio) / 2;
|
||||
const widthCropEnd = widthCropStart + widthCroppingRatio;
|
||||
const heightCropEnd = heightCroppingRatio + heightCropStart;
|
||||
this.cropBox = tensor2d(
|
||||
[heightCropStart, widthCropStart, heightCropEnd, widthCropEnd],
|
||||
[1, 4]);
|
||||
} else {
|
||||
this.cropBox = tensor2d([0, 0, 1, 1], [1, 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
summary() {
|
||||
return `webcam`;
|
||||
}
|
||||
|
||||
// Construct a WebcamIterator and start it's video stream.
|
||||
static async create(
|
||||
webcamVideoElement?: HTMLVideoElement, webcamConfig: WebcamConfig = {}) {
|
||||
if (env().get('IS_NODE')) {
|
||||
throw new Error(
|
||||
'tf.data.webcam is only supported in browser environment.');
|
||||
}
|
||||
|
||||
if (!webcamVideoElement) {
|
||||
// If webcam video element is not provided, create a hidden video element
|
||||
// with provided width and height.
|
||||
webcamVideoElement = document.createElement('video');
|
||||
if (!webcamConfig.resizeWidth || !webcamConfig.resizeHeight) {
|
||||
throw new Error(
|
||||
'Please provide webcam video element, or resizeWidth and ' +
|
||||
'resizeHeight to create a hidden video element.');
|
||||
}
|
||||
webcamVideoElement.width = webcamConfig.resizeWidth;
|
||||
webcamVideoElement.height = webcamConfig.resizeHeight;
|
||||
}
|
||||
const webcamIterator = new WebcamIterator(webcamVideoElement, webcamConfig);
|
||||
|
||||
// Call async function to initialize the video stream.
|
||||
await webcamIterator.start();
|
||||
|
||||
return webcamIterator;
|
||||
}
|
||||
|
||||
// Async function to start video stream.
|
||||
async start(): Promise<void> {
|
||||
if (this.webcamConfig.facingMode) {
|
||||
util.assert(
|
||||
(this.webcamConfig.facingMode === 'user') ||
|
||||
(this.webcamConfig.facingMode === 'environment'),
|
||||
() =>
|
||||
`Invalid webcam facing mode: ${this.webcamConfig.facingMode}. ` +
|
||||
`Please provide 'user' or 'environment'`);
|
||||
}
|
||||
|
||||
try {
|
||||
this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: {
|
||||
deviceId: this.webcamConfig.deviceId,
|
||||
facingMode: this.webcamConfig.facingMode ?
|
||||
this.webcamConfig.facingMode :
|
||||
'user',
|
||||
width: this.webcamVideoElement.width,
|
||||
height: this.webcamVideoElement.height
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// Modify the error message but leave the stack trace intact
|
||||
e.message = `Error thrown while initializing video stream: ${e.message}`;
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (!this.stream) {
|
||||
throw new Error('Could not obtain video from webcam.');
|
||||
}
|
||||
|
||||
// Older browsers may not have srcObject
|
||||
try {
|
||||
this.webcamVideoElement.srcObject = this.stream;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
this.webcamVideoElement.src = window.URL.createObjectURL(this.stream);
|
||||
}
|
||||
// Start the webcam video stream
|
||||
this.webcamVideoElement.play();
|
||||
|
||||
this.isClosed = false;
|
||||
|
||||
return new Promise<void>(resolve => {
|
||||
// Add event listener to make sure the webcam has been fully initialized.
|
||||
this.webcamVideoElement.onloadedmetadata = () => {
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async next(): Promise<IteratorResult<Tensor3D>> {
|
||||
if (this.isClosed) {
|
||||
return {value: null, done: true};
|
||||
}
|
||||
|
||||
let img;
|
||||
try {
|
||||
img = browser.fromPixels(this.webcamVideoElement);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Error thrown converting video to pixels: ${JSON.stringify(e)}`);
|
||||
}
|
||||
if (this.resize) {
|
||||
try {
|
||||
return {value: this.cropAndResizeFrame(img), done: false};
|
||||
} catch (e) {
|
||||
throw new Error(`Error thrown cropping the video: ${e.message}`);
|
||||
} finally {
|
||||
img.dispose();
|
||||
}
|
||||
} else {
|
||||
return {value: img, done: false};
|
||||
}
|
||||
}
|
||||
|
||||
private needToResize() {
|
||||
// If resizeWidth and resizeHeight are provided, and different from the
|
||||
// width and height of original HTMLVideoElement, then resizing and cropping
|
||||
// is required.
|
||||
if (this.webcamConfig.resizeWidth && this.webcamConfig.resizeHeight &&
|
||||
(this.webcamVideoElement.width !== this.webcamConfig.resizeWidth ||
|
||||
this.webcamVideoElement.height !== this.webcamConfig.resizeHeight)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cropping and resizing each frame based on config
|
||||
cropAndResizeFrame(img: Tensor3D): Tensor3D {
|
||||
return tidy(() => {
|
||||
const expandedImage: Tensor4D = expandDims(cast(img, 'float32'), (0));
|
||||
let resizedImage;
|
||||
resizedImage = image.cropAndResize(
|
||||
expandedImage, this.cropBox, this.cropBoxInd, this.cropSize,
|
||||
'bilinear');
|
||||
// Extract image from batch cropping.
|
||||
const shape = resizedImage.shape;
|
||||
return reshape(resizedImage, shape.slice(1) as [number, number, number]);
|
||||
});
|
||||
}
|
||||
|
||||
// Capture one frame from the video stream, and extract the value from
|
||||
// iterator.next() result.
|
||||
async capture(): Promise<Tensor3D> {
|
||||
return (await this.next()).value;
|
||||
}
|
||||
|
||||
// Stop the video stream and pause webcam iterator.
|
||||
stop(): void {
|
||||
const tracks = this.stream.getTracks();
|
||||
|
||||
tracks.forEach(track => track.stop());
|
||||
|
||||
try {
|
||||
this.webcamVideoElement.srcObject = null;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
this.webcamVideoElement.src = null;
|
||||
}
|
||||
this.isClosed = true;
|
||||
}
|
||||
|
||||
// Override toArray() function to prevent collecting.
|
||||
toArray(): Promise<Tensor3D[]> {
|
||||
throw new Error('Can not convert infinite video stream to array.');
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-282
@@ -1,282 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {TensorContainer} from '@tensorflow/tfjs-core';
|
||||
import {Dataset, datasetFromIteratorFn} from './dataset';
|
||||
import {CSVDataset} from './datasets/csv_dataset';
|
||||
import {iteratorFromFunction} from './iterators/lazy_iterator';
|
||||
import {MicrophoneIterator} from './iterators/microphone_iterator';
|
||||
import {WebcamIterator} from './iterators/webcam_iterator';
|
||||
import {URLDataSource} from './sources/url_data_source';
|
||||
import {CSVConfig, MicrophoneConfig, WebcamConfig} from './types';
|
||||
|
||||
/**
|
||||
* Create a `CSVDataset` by reading and decoding CSV file(s) from provided URL
|
||||
* or local path if it's in Node environment.
|
||||
*
|
||||
* Note: If isLabel in columnConfigs is `true` for at least one column, the
|
||||
* element in returned `CSVDataset` will be an object of
|
||||
* `{xs:features, ys:labels}`: xs is a dict of features key/value pairs, ys
|
||||
* is a dict of labels key/value pairs. If no column is marked as label,
|
||||
* returns a dict of features only.
|
||||
*
|
||||
* ```js
|
||||
* const csvUrl =
|
||||
* 'https://storage.googleapis.com/tfjs-examples/multivariate-linear-regression/data/boston-housing-train.csv';
|
||||
*
|
||||
* async function run() {
|
||||
* // We want to predict the column "medv", which represents a median value of
|
||||
* // a home (in $1000s), so we mark it as a label.
|
||||
* const csvDataset = tf.data.csv(
|
||||
* csvUrl, {
|
||||
* columnConfigs: {
|
||||
* medv: {
|
||||
* isLabel: true
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // Number of features is the number of column names minus one for the label
|
||||
* // column.
|
||||
* const numOfFeatures = (await csvDataset.columnNames()).length - 1;
|
||||
*
|
||||
* // Prepare the Dataset for training.
|
||||
* const flattenedDataset =
|
||||
* csvDataset
|
||||
* .map(({xs, ys}) =>
|
||||
* {
|
||||
* // Convert xs(features) and ys(labels) from object form (keyed by
|
||||
* // column name) to array form.
|
||||
* return {xs:Object.values(xs), ys:Object.values(ys)};
|
||||
* })
|
||||
* .batch(10);
|
||||
*
|
||||
* // Define the model.
|
||||
* const model = tf.sequential();
|
||||
* model.add(tf.layers.dense({
|
||||
* inputShape: [numOfFeatures],
|
||||
* units: 1
|
||||
* }));
|
||||
* model.compile({
|
||||
* optimizer: tf.train.sgd(0.000001),
|
||||
* loss: 'meanSquaredError'
|
||||
* });
|
||||
*
|
||||
* // Fit the model using the prepared Dataset
|
||||
* return model.fitDataset(flattenedDataset, {
|
||||
* epochs: 10,
|
||||
* callbacks: {
|
||||
* onEpochEnd: async (epoch, logs) => {
|
||||
* console.log(epoch + ':' + logs.loss);
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* await run();
|
||||
* ```
|
||||
*
|
||||
* @param source URL or local path to get CSV file. If it's a local path, it
|
||||
* must have prefix `file://` and it only works in node environment.
|
||||
* @param csvConfig (Optional) A CSVConfig object that contains configurations
|
||||
* of reading and decoding from CSV file(s).
|
||||
*
|
||||
* @doc {
|
||||
* heading: 'Data',
|
||||
* subheading: 'Creation',
|
||||
* namespace: 'data',
|
||||
* configParamIndices: [1]
|
||||
* }
|
||||
*/
|
||||
export function csv(
|
||||
source: RequestInfo, csvConfig: CSVConfig = {}): CSVDataset {
|
||||
return new CSVDataset(new URLDataSource(source), csvConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `Dataset` that produces each element by calling a provided function.
|
||||
*
|
||||
* Note that repeated iterations over this `Dataset` may produce different
|
||||
* results, because the function will be called anew for each element of each
|
||||
* iteration.
|
||||
*
|
||||
* Also, beware that the sequence of calls to this function may be out of order
|
||||
* in time with respect to the logical order of the Dataset. This is due to the
|
||||
* asynchronous lazy nature of stream processing, and depends on downstream
|
||||
* transformations (e.g. .shuffle()). If the provided function is pure, this is
|
||||
* no problem, but if it is a closure over a mutable state (e.g., a traversal
|
||||
* pointer), then the order of the produced elements may be scrambled.
|
||||
*
|
||||
* ```js
|
||||
* let i = -1;
|
||||
* const func = () =>
|
||||
* ++i < 5 ? {value: i, done: false} : {value: null, done: true};
|
||||
* const ds = tf.data.func(func);
|
||||
* await ds.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param f A function that produces one data element on each call.
|
||||
*/
|
||||
export function func<T extends TensorContainer>(
|
||||
f: () => IteratorResult<T>| Promise<IteratorResult<T>>): Dataset<T> {
|
||||
const iter = iteratorFromFunction(f);
|
||||
return datasetFromIteratorFn(async () => iter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `Dataset` that produces each element from provided JavaScript
|
||||
* generator, which is a function*
|
||||
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generator_functions),
|
||||
* or a function that returns an
|
||||
* iterator
|
||||
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generator_functions).
|
||||
*
|
||||
* The returned iterator should have `.next()` function that returns element in
|
||||
* format of `{value: TensorContainer, done:boolean}`.
|
||||
*
|
||||
* Example of creating a dataset from an iterator factory:
|
||||
* ```js
|
||||
* function makeIterator() {
|
||||
* const numElements = 10;
|
||||
* let index = 0;
|
||||
*
|
||||
* const iterator = {
|
||||
* next: () => {
|
||||
* let result;
|
||||
* if (index < numElements) {
|
||||
* result = {value: index, done: false};
|
||||
* index++;
|
||||
* return result;
|
||||
* }
|
||||
* return {value: index, done: true};
|
||||
* }
|
||||
* };
|
||||
* return iterator;
|
||||
* }
|
||||
* const ds = tf.data.generator(makeIterator);
|
||||
* await ds.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* Example of creating a dataset from a generator:
|
||||
* ```js
|
||||
* function* dataGenerator() {
|
||||
* const numElements = 10;
|
||||
* let index = 0;
|
||||
* while (index < numElements) {
|
||||
* const x = index;
|
||||
* index++;
|
||||
* yield x;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* const ds = tf.data.generator(dataGenerator);
|
||||
* await ds.forEachAsync(e => console.log(e));
|
||||
* ```
|
||||
*
|
||||
* @param generator A Javascript generator function that returns a JavaScript
|
||||
* iterator.
|
||||
*
|
||||
* @doc {
|
||||
* heading: 'Data',
|
||||
* subheading: 'Creation',
|
||||
* namespace: 'data',
|
||||
* configParamIndices: [1]
|
||||
* }
|
||||
*/
|
||||
export function generator<T extends TensorContainer>(
|
||||
generator: () => Iterator<T>| Promise<Iterator<T>>): Dataset<T> {
|
||||
return datasetFromIteratorFn(async () => {
|
||||
const gen = await generator();
|
||||
return iteratorFromFunction(() => gen.next());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an iterator that generate `Tensor`s from webcam video stream. This API
|
||||
* only works in Browser environment when the device has webcam.
|
||||
*
|
||||
* Note: this code snippet only works when the device has a webcam. It will
|
||||
* request permission to open the webcam when running.
|
||||
* ```js
|
||||
* const videoElement = document.createElement('video');
|
||||
* videoElement.width = 100;
|
||||
* videoElement.height = 100;
|
||||
* const cam = await tf.data.webcam(videoElement);
|
||||
* const img = await cam.capture();
|
||||
* img.print();
|
||||
* cam.stop();
|
||||
* ```
|
||||
*
|
||||
* @param webcamVideoElement A `HTMLVideoElement` used to play video from
|
||||
* webcam. If this element is not provided, a hidden `HTMLVideoElement` will
|
||||
* be created. In that case, `resizeWidth` and `resizeHeight` must be
|
||||
* provided to set the generated tensor shape.
|
||||
* @param webcamConfig A `WebcamConfig` object that contains configurations of
|
||||
* reading and manipulating data from webcam video stream.
|
||||
*
|
||||
* @doc {
|
||||
* heading: 'Data',
|
||||
* subheading: 'Creation',
|
||||
* namespace: 'data',
|
||||
* ignoreCI: true
|
||||
* }
|
||||
*/
|
||||
export async function webcam(
|
||||
webcamVideoElement?: HTMLVideoElement,
|
||||
webcamConfig?: WebcamConfig): Promise<WebcamIterator> {
|
||||
return WebcamIterator.create(webcamVideoElement, webcamConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an iterator that generate frequency-domain spectrogram `Tensor`s from
|
||||
* microphone audio stream with browser's native FFT. This API only works in
|
||||
* browser environment when the device has microphone.
|
||||
*
|
||||
* Note: this code snippet only works when the device has a microphone. It will
|
||||
* request permission to open the microphone when running.
|
||||
* ```js
|
||||
* const mic = await tf.data.microphone({
|
||||
* fftSize: 1024,
|
||||
* columnTruncateLength: 232,
|
||||
* numFramesPerSpectrogram: 43,
|
||||
* sampleRateHz:44100,
|
||||
* includeSpectrogram: true,
|
||||
* includeWaveform: true
|
||||
* });
|
||||
* const audioData = await mic.capture();
|
||||
* const spectrogramTensor = audioData.spectrogram;
|
||||
* spectrogramTensor.print();
|
||||
* const waveformTensor = audioData.waveform;
|
||||
* waveformTensor.print();
|
||||
* mic.stop();
|
||||
* ```
|
||||
*
|
||||
* @param microphoneConfig A `MicrophoneConfig` object that contains
|
||||
* configurations of reading audio data from microphone.
|
||||
*
|
||||
* @doc {
|
||||
* heading: 'Data',
|
||||
* subheading: 'Creation',
|
||||
* namespace: 'data',
|
||||
* ignoreCI: true
|
||||
* }
|
||||
*/
|
||||
export async function microphone(microphoneConfig?: MicrophoneConfig):
|
||||
Promise<MicrophoneIterator> {
|
||||
return MicrophoneIterator.create(microphoneConfig);
|
||||
}
|
||||
Generated
Vendored
-55
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {env} from '@tensorflow/tfjs-core';
|
||||
import {DataSource} from '../datasource';
|
||||
import {ByteChunkIterator} from '../iterators/byte_chunk_iterator';
|
||||
import {FileChunkIterator, FileChunkIteratorOptions} from '../iterators/file_chunk_iterator';
|
||||
import {FileElement} from '../types';
|
||||
import {isLocalPath} from '../util/source_util';
|
||||
|
||||
/**
|
||||
* Represents a file, blob, or Uint8Array readable as a stream of binary data
|
||||
* chunks.
|
||||
*/
|
||||
export class FileDataSource extends DataSource {
|
||||
/**
|
||||
* Create a `FileDataSource`.
|
||||
*
|
||||
* @param input Local file path, or `File`/`Blob`/`Uint8Array` object to
|
||||
* read. Local file only works in node environment.
|
||||
* @param options Options passed to the underlying `FileChunkIterator`s,
|
||||
* such as {chunksize: 1024}.
|
||||
*/
|
||||
constructor(
|
||||
protected input: FileElement|string,
|
||||
protected readonly options: FileChunkIteratorOptions = {}) {
|
||||
super();
|
||||
}
|
||||
|
||||
async iterator(): Promise<ByteChunkIterator> {
|
||||
if (isLocalPath(this.input) && env().get('IS_NODE')) {
|
||||
// tslint:disable-next-line:no-require-imports
|
||||
const fs = require('fs');
|
||||
this.input = fs.readFileSync((this.input as string).substr(7));
|
||||
}
|
||||
// TODO(kangyizhang): Add LocalFileChunkIterator to split local streaming
|
||||
// with file in browser.
|
||||
return new FileChunkIterator(this.input as FileElement, this.options);
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-55
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {DataSource} from '../datasource';
|
||||
import {ByteChunkIterator} from '../iterators/byte_chunk_iterator';
|
||||
import {FileChunkIteratorOptions} from '../iterators/file_chunk_iterator';
|
||||
import {urlChunkIterator} from '../iterators/url_chunk_iterator';
|
||||
import {isLocalPath} from '../util/source_util';
|
||||
import {FileDataSource} from './file_data_source';
|
||||
|
||||
/*
|
||||
* Represents a URL readable as a stream of binary data chunks.
|
||||
*/
|
||||
export class URLDataSource extends DataSource {
|
||||
/**
|
||||
* Create a `URLDataSource`.
|
||||
*
|
||||
* @param url A source URL string, or a `Request` object.
|
||||
* @param options Options passed to the underlying `FileChunkIterator`s,
|
||||
* such as {chunksize: 1024}.
|
||||
*/
|
||||
constructor(
|
||||
protected readonly url: RequestInfo,
|
||||
protected readonly fileOptions: FileChunkIteratorOptions = {}) {
|
||||
super();
|
||||
}
|
||||
|
||||
// TODO(soergel): provide appropriate caching options. Currently this
|
||||
// will download the URL anew for each call to iterator(). Since we have
|
||||
// to treat the downloaded file as a blob/buffer anyway, we may as well retain
|
||||
// it-- but that raises GC issues. Also we may want a persistent disk cache.
|
||||
async iterator(): Promise<ByteChunkIterator> {
|
||||
if (isLocalPath(this.url)) {
|
||||
return (new FileDataSource(this.url as string, this.fileOptions))
|
||||
.iterator();
|
||||
} else {
|
||||
return urlChunkIterator(this.url, this.fileOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-212
@@ -1,212 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import * as tf from '@tensorflow/tfjs-core';
|
||||
import {div, max, min, sub} from '@tensorflow/tfjs-core';
|
||||
|
||||
import {Dataset} from './dataset';
|
||||
|
||||
// TODO(kangyizhang): eliminate the need for ElementArray and TabularRecord, by
|
||||
// computing stats on nested structures via deepMap/deepZip.
|
||||
|
||||
/**
|
||||
* The value associated with a given key for a single element.
|
||||
*
|
||||
* Such a value may not have a batch dimension. A value may be a scalar or an
|
||||
* n-dimensional array.
|
||||
*/
|
||||
export type ElementArray = number|number[]|tf.Tensor|string;
|
||||
|
||||
/**
|
||||
* A map from string keys (aka column names) to values for a single element.
|
||||
*/
|
||||
export type TabularRecord = {
|
||||
[key: string]: ElementArray
|
||||
};
|
||||
|
||||
// TODO(kangyizhang): Flesh out collected statistics.
|
||||
// For numeric columns we should provide mean, stddev, histogram, etc.
|
||||
// For string columns we should provide a vocabulary (at least, top-k), maybe a
|
||||
// length histogram, etc.
|
||||
// Collecting only numeric min and max is just the bare minimum for now.
|
||||
|
||||
/** An interface representing numeric statistics of a column. */
|
||||
export interface NumericColumnStatistics {
|
||||
min: number;
|
||||
max: number;
|
||||
mean: number;
|
||||
variance: number;
|
||||
stddev: number;
|
||||
length: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface representing column level NumericColumnStatistics for a
|
||||
* Dataset.
|
||||
*/
|
||||
export interface DatasetStatistics {
|
||||
[key: string]: NumericColumnStatistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a function that scales numeric values into the [0, 1] interval.
|
||||
*
|
||||
* @param min the lower bound of the inputs, which should be mapped to 0.
|
||||
* @param max the upper bound of the inputs, which should be mapped to 1,
|
||||
* @return A function that maps an input ElementArray to a scaled ElementArray.
|
||||
*/
|
||||
export function scaleTo01(min: number, max: number): (value: ElementArray) =>
|
||||
ElementArray {
|
||||
const range = max - min;
|
||||
const minTensor: tf.Tensor = tf.scalar(min);
|
||||
const rangeTensor: tf.Tensor = tf.scalar(range);
|
||||
return (value: ElementArray): ElementArray => {
|
||||
if (typeof (value) === 'string') {
|
||||
throw new Error('Can\'t scale a string.');
|
||||
} else {
|
||||
if (value instanceof tf.Tensor) {
|
||||
const result = div(sub(value, minTensor), rangeTensor);
|
||||
return result;
|
||||
} else if (value instanceof Array) {
|
||||
return value.map(v => (v - min) / range);
|
||||
} else {
|
||||
return (value - min) / range;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a function that calculates column level statistics, i.e. min, max,
|
||||
* variance, stddev.
|
||||
*
|
||||
* @param dataset The Dataset object whose statistics will be calculated.
|
||||
* @param sampleSize (Optional) If set, statistics will only be calculated
|
||||
* against a subset of the whole data.
|
||||
* @param shuffleWindowSize (Optional) If set, shuffle provided dataset before
|
||||
* calculating statistics.
|
||||
* @return A DatasetStatistics object that contains NumericColumnStatistics of
|
||||
* each column.
|
||||
*/
|
||||
export async function computeDatasetStatistics(
|
||||
dataset: Dataset<TabularRecord>, sampleSize?: number,
|
||||
shuffleWindowSize?: number): Promise<DatasetStatistics> {
|
||||
let sampleDataset = dataset;
|
||||
// TODO(soergel): allow for deep shuffle where possible.
|
||||
if (shuffleWindowSize != null) {
|
||||
sampleDataset = sampleDataset.shuffle(shuffleWindowSize);
|
||||
}
|
||||
if (sampleSize != null) {
|
||||
sampleDataset = sampleDataset.take(sampleSize);
|
||||
}
|
||||
|
||||
// TODO(soergel): prepare the column objects based on a schema.
|
||||
const result: DatasetStatistics = {};
|
||||
|
||||
await sampleDataset.forEachAsync(e => {
|
||||
for (const key of Object.keys(e)) {
|
||||
const value = e[key];
|
||||
if (typeof (value) === 'string') {
|
||||
// No statistics for string element.
|
||||
} else {
|
||||
let previousMean = 0;
|
||||
let previousLength = 0;
|
||||
let previousVariance = 0;
|
||||
let columnStats: NumericColumnStatistics = result[key];
|
||||
if (columnStats == null) {
|
||||
columnStats = {
|
||||
min: Number.POSITIVE_INFINITY,
|
||||
max: Number.NEGATIVE_INFINITY,
|
||||
mean: 0,
|
||||
variance: 0,
|
||||
stddev: 0,
|
||||
length: 0
|
||||
};
|
||||
result[key] = columnStats;
|
||||
} else {
|
||||
previousMean = columnStats.mean;
|
||||
previousLength = columnStats.length;
|
||||
previousVariance = columnStats.variance;
|
||||
}
|
||||
let recordMin: number;
|
||||
let recordMax: number;
|
||||
|
||||
// Calculate accumulated mean and variance following tf.Transform
|
||||
// implementation
|
||||
let valueLength = 0;
|
||||
let valueMean = 0;
|
||||
let valueVariance = 0;
|
||||
let combinedLength = 0;
|
||||
let combinedMean = 0;
|
||||
let combinedVariance = 0;
|
||||
|
||||
if (value instanceof tf.Tensor) {
|
||||
recordMin = min(value).dataSync()[0];
|
||||
recordMax = max(value).dataSync()[0];
|
||||
const valueMoment = tf.moments(value);
|
||||
valueMean = valueMoment.mean.dataSync()[0];
|
||||
valueVariance = valueMoment.variance.dataSync()[0];
|
||||
valueLength = value.size;
|
||||
|
||||
} else if (value instanceof Array) {
|
||||
recordMin = value.reduce((a, b) => Math.min(a, b));
|
||||
recordMax = value.reduce((a, b) => Math.max(a, b));
|
||||
const valueMoment = tf.moments(value);
|
||||
valueMean = valueMoment.mean.dataSync()[0];
|
||||
valueVariance = valueMoment.variance.dataSync()[0];
|
||||
valueLength = value.length;
|
||||
|
||||
} else if (!isNaN(value) && isFinite(value)) {
|
||||
recordMin = value;
|
||||
recordMax = value;
|
||||
valueMean = value;
|
||||
valueVariance = 0;
|
||||
valueLength = 1;
|
||||
|
||||
} else {
|
||||
columnStats = null;
|
||||
continue;
|
||||
}
|
||||
combinedLength = previousLength + valueLength;
|
||||
combinedMean = previousMean +
|
||||
(valueLength / combinedLength) * (valueMean - previousMean);
|
||||
combinedVariance = previousVariance +
|
||||
(valueLength / combinedLength) *
|
||||
(valueVariance +
|
||||
((valueMean - combinedMean) * (valueMean - previousMean)) -
|
||||
previousVariance);
|
||||
|
||||
columnStats.min = Math.min(columnStats.min, recordMin);
|
||||
columnStats.max = Math.max(columnStats.max, recordMax);
|
||||
columnStats.length = combinedLength;
|
||||
columnStats.mean = combinedMean;
|
||||
columnStats.variance = combinedVariance;
|
||||
columnStats.stddev = Math.sqrt(combinedVariance);
|
||||
}
|
||||
}
|
||||
});
|
||||
// Variance and stddev should be NaN for the case of a single element.
|
||||
for (const key in result) {
|
||||
const stat: NumericColumnStatistics = result[key];
|
||||
if (stat.length === 1) {
|
||||
stat.variance = NaN;
|
||||
stat.stddev = NaN;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Generated
Vendored
-219
@@ -1,219 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {DataType, TensorContainer} from '@tensorflow/tfjs-core';
|
||||
|
||||
// Maybe this should be called 'NestedContainer'-- that's just a bit unwieldy.
|
||||
export type Container<T> = ContainerObject<T>|ContainerArray<T>;
|
||||
|
||||
export type ContainerOrT<T> = Container<T>|T;
|
||||
|
||||
export interface ContainerObject<T> {
|
||||
[x: string]: ContainerOrT<T>;
|
||||
}
|
||||
export interface ContainerArray<T> extends Array<ContainerOrT<T>> {}
|
||||
|
||||
/**
|
||||
* Types supported by FileChunkIterator in both Browser and Node Environment.
|
||||
*/
|
||||
export type FileElement = File|Blob|Uint8Array;
|
||||
|
||||
/**
|
||||
* A dictionary containing column level configurations when reading and decoding
|
||||
* CSV file(s) from csv source.
|
||||
* Has the following fields:
|
||||
* - `required` If value in this column is required. If set to `true`, throw an
|
||||
* error when it finds an empty value.
|
||||
*
|
||||
* - `dtype` Data type of this column. Could be int32, float32, bool, or string.
|
||||
*
|
||||
* - `default` Default value of this column.
|
||||
*
|
||||
* - `isLabel` Whether this column is label instead of features. If isLabel is
|
||||
* `true` for at least one column, the .csv() API will return an array of two
|
||||
* items: the first item is a dict of features key/value pairs, the second item
|
||||
* is a dict of labels key/value pairs. If no column is marked as label returns
|
||||
* a dict of features only.
|
||||
*/
|
||||
export interface ColumnConfig {
|
||||
required?: boolean;
|
||||
dtype?: DataType;
|
||||
default?: TensorContainer;
|
||||
isLabel?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for configuring dataset when reading and decoding from CSV file(s).
|
||||
*/
|
||||
export interface CSVConfig {
|
||||
/**
|
||||
* A boolean value that indicates whether the first row of provided CSV file
|
||||
* is a header line with column names, and should not be included in the data.
|
||||
*/
|
||||
hasHeader?: boolean;
|
||||
|
||||
/**
|
||||
* A list of strings that corresponds to the CSV column names, in order. If
|
||||
* provided, it ignores the column names inferred from the header row. If not
|
||||
* provided, infers the column names from the first row of the records. If
|
||||
* `hasHeader` is false and `columnNames` is not provided, this method will
|
||||
* throw an error.
|
||||
*/
|
||||
columnNames?: string[];
|
||||
|
||||
/**
|
||||
* A dictionary whose key is column names, value is an object stating if this
|
||||
* column is required, column's data type, default value, and if this column
|
||||
* is label. If provided, keys must correspond to names provided in
|
||||
* `columnNames` or inferred from the file header lines. If any column is
|
||||
* marked as label, the .csv() API will return an array of two items: the
|
||||
* first item is a dict of features key/value pairs, the second item is a dict
|
||||
* of labels key/value pairs. If no column is marked as label returns a dict
|
||||
* of features only.
|
||||
*
|
||||
* Has the following fields:
|
||||
* - `required` If value in this column is required. If set to `true`, throw
|
||||
* an error when it finds an empty value.
|
||||
*
|
||||
* - `dtype` Data type of this column. Could be int32, float32, bool, or
|
||||
* string.
|
||||
*
|
||||
* - `default` Default value of this column.
|
||||
*
|
||||
* - `isLabel` Whether this column is label instead of features. If isLabel is
|
||||
* `true` for at least one column, the element in returned `CSVDataset` will
|
||||
* be an object of {xs: features, ys: labels}: xs is a dict of features
|
||||
* key/value pairs, ys is a dict of labels key/value pairs. If no column is
|
||||
* marked as label, returns a dict of features only.
|
||||
*/
|
||||
columnConfigs?: {[key: string]: ColumnConfig};
|
||||
|
||||
/**
|
||||
* If true, only columns provided in `columnConfigs` will be parsed and
|
||||
* provided during iteration.
|
||||
*/
|
||||
configuredColumnsOnly?: boolean;
|
||||
|
||||
/**
|
||||
* The string used to parse each line of the input file.
|
||||
*/
|
||||
delimiter?: string;
|
||||
|
||||
/**
|
||||
* If true, delimiter field should be null. Parsing delimiter is whitespace
|
||||
* and treat continuous multiple whitespace as one delimiter.
|
||||
*/
|
||||
delimWhitespace?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface configuring data from webcam video stream.
|
||||
*/
|
||||
export interface WebcamConfig {
|
||||
/**
|
||||
* A string specifying which camera to use on device. If the value is
|
||||
* 'user', it will use front camera. If the value is 'environment', it will
|
||||
* use rear camera.
|
||||
*/
|
||||
facingMode?: 'user'|'environment';
|
||||
|
||||
/**
|
||||
* A string used to request a specific camera. The deviceId can be obtained by
|
||||
* calling `mediaDevices.enumerateDevices()`.
|
||||
*/
|
||||
deviceId?: string;
|
||||
|
||||
/**
|
||||
* Specifies the width of the output tensor. The actual width of the
|
||||
* HTMLVideoElement (if provided) can be different and the final image will be
|
||||
* resized to match resizeWidth.
|
||||
*/
|
||||
resizeWidth?: number;
|
||||
|
||||
/**
|
||||
* Specifies the height of the output tensor. The actual height of the
|
||||
* HTMLVideoElement (if provided) can be different and the final image will be
|
||||
* resized to match resizeHeight.
|
||||
*/
|
||||
resizeHeight?: number;
|
||||
|
||||
/**
|
||||
* A boolean value that indicates whether to crop the video frame from center.
|
||||
* If true, `resizeWidth` and `resizeHeight` must be specified; then an image
|
||||
* of size `[resizeWidth, resizeHeight]` is taken from the center of the frame
|
||||
* without scaling. If false, the entire image is returned (perhaps scaled to
|
||||
* fit in `[resizeWidth, resizeHeight]`, if those are provided).
|
||||
*/
|
||||
centerCrop?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface configuring data from microphone audio stream.
|
||||
*/
|
||||
export interface MicrophoneConfig {
|
||||
// A number representing Audio sampling rate in Hz. either 44,100 or 48,000.
|
||||
// If provided sample rate is not available on the device, it will throw an
|
||||
// error. Optional, defaults to the sample rate available on device.
|
||||
sampleRateHz?: 44100|48000;
|
||||
|
||||
// The FFT length of each spectrogram column. A higher value will result in
|
||||
// more details in the frequency domain but fewer details in the time domain.
|
||||
// Must be a power of 2 between 2 to 4 and 2 to 14, so one of: 16, 32, 64,
|
||||
// 128, 256, 512, 1024, 2048, 4096, 8192, and 16384. It will throw an error if
|
||||
// it is an invalid number.Defaults to 1024.
|
||||
fftSize?: number;
|
||||
|
||||
// Truncate each spectrogram column at how many frequency points. Each audio
|
||||
// frame contains fftSize, for example, 1024 samples which covers voice
|
||||
// frequency from 0 to 22,500 Hz. However, the frequency content relevant to
|
||||
// human speech is generally in the frequency range from 0 to 5000 Hz. So each
|
||||
// audio frame only need 232 columns to cover the frequency range of human
|
||||
// voice. This will be part of the output spectrogram tensor shape. Optional,
|
||||
// defaults to null which means no truncation.
|
||||
columnTruncateLength?: number;
|
||||
|
||||
// Number of audio frames per spectrogram. The time duration of one
|
||||
// spectrogram equals to numFramesPerSpectrogram*fftSize/sampleRateHz second.
|
||||
// For example: the device sampling rate is 44,100 Hz, and fftSize is 1024,
|
||||
// then each frame duration between two sampling is 0.023 second. If the
|
||||
// purpose is for an audio model to recognize speech command that last 1
|
||||
// second, each spectrogram should contain 1/0.023, which is 43 frames. This
|
||||
// will be part of the output spectrogram tensor shape. Optional, defaults to
|
||||
// 43 so that each audio data last 1 second.
|
||||
numFramesPerSpectrogram?: number;
|
||||
|
||||
// A dictionary specifying the requirements of audio to request, such as
|
||||
// deviceID, echoCancellation, etc. Optional.
|
||||
audioTrackConstraints?: MediaTrackConstraints;
|
||||
|
||||
// The averaging constant with the last analysis frame -- basically, it makes
|
||||
// the transition between values over time smoother. It is used by
|
||||
// AnalyserNode interface during FFT. Optional, has to be between 0 and 1,
|
||||
// defaults to 0.
|
||||
smoothingTimeConstant?: number;
|
||||
|
||||
// Whether to collect the frequency domain audio spectrogram in
|
||||
// MicrophoneIterator result. If both includeSpectrogram and includeWaveform
|
||||
// are false, it will throw an error. Defaults to true.
|
||||
includeSpectrogram?: boolean;
|
||||
|
||||
// Whether to collect the time domain audio waveform in MicrophoneIterator
|
||||
// result. If both includeSpectrogram and includeWaveform are false, it will
|
||||
// throw an error. Defaults to false.
|
||||
includeWaveform?: boolean;
|
||||
}
|
||||
Generated
Vendored
-35
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import * as tf from '@tensorflow/tfjs-core';
|
||||
import {deepMap, DeepMapResult, isIterable} from './deep_map';
|
||||
|
||||
export function deepClone<T>(container: T): T {
|
||||
return deepMap(container, cloneIfTensor);
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
function cloneIfTensor(item: any): DeepMapResult {
|
||||
if (item instanceof tf.Tensor) {
|
||||
return ({value: item.clone(), recurse: false});
|
||||
} else if (isIterable(item)) {
|
||||
return {value: null, recurse: true};
|
||||
} else {
|
||||
return {value: item, recurse: false};
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-277
@@ -1,277 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import * as tf from '@tensorflow/tfjs-core';
|
||||
|
||||
// tslint:disable:no-any
|
||||
|
||||
/**
|
||||
* A return value for a mapping function that can be applied via deepMap.
|
||||
*
|
||||
* If recurse is true, the value should be empty, and iteration will continue
|
||||
* into the object or array.
|
||||
*/
|
||||
export type DeepMapResult = {
|
||||
value: any,
|
||||
recurse: boolean
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply a mapping function to a nested structure in a recursive manner.
|
||||
*
|
||||
* The result of the mapping is an object with the same nested structure (i.e.,
|
||||
* of arrays and dicts) as the input, except that some subtrees are replaced,
|
||||
* according to the results of the mapping function.
|
||||
*
|
||||
* Mappings are memoized. Thus, if the nested structure contains the same
|
||||
* object in multiple positions, the output will contain the same mapped object
|
||||
* in those positions. Cycles are not supported, however.
|
||||
*
|
||||
* @param input: The object to which to apply the mapping function.
|
||||
* @param mapFn: A function that expects a single node of the object tree, and
|
||||
* returns a `DeepMapResult`. The `DeepMapResult` either provides a
|
||||
* replacement value for that node (i.e., replacing the subtree), or indicates
|
||||
* that the node should be processed recursively.
|
||||
*/
|
||||
export function deepMap(input: any, mapFn: (x: any) => DeepMapResult): any|
|
||||
any[] {
|
||||
return deepMapInternal(input, mapFn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param seen: A Map of known object mappings (i.e., memoized results of
|
||||
* `mapFn()`)
|
||||
* @param containedIn: An set containing objects on the reference path currently
|
||||
* being processed (used to detect cycles).
|
||||
*/
|
||||
function deepMapInternal(
|
||||
input: any, mapFn: (x: any) => DeepMapResult,
|
||||
seen: Map<any, any> = new Map(), containedIn: Set<{}> = new Set()): any|
|
||||
any[] {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
if (containedIn.has(input)) {
|
||||
throw new Error('Circular references are not supported.');
|
||||
}
|
||||
if (seen.has(input)) {
|
||||
return seen.get(input);
|
||||
}
|
||||
const result = mapFn(input);
|
||||
|
||||
if (result.recurse && result.value !== null) {
|
||||
throw new Error(
|
||||
'A deep map function may not return both a value and recurse=true.');
|
||||
}
|
||||
|
||||
if (!result.recurse) {
|
||||
seen.set(input, result.value);
|
||||
return result.value;
|
||||
} else if (isIterable(input)) {
|
||||
// tslint:disable-next-line:no-any
|
||||
const mappedIterable: any|any[] = Array.isArray(input) ? [] : {};
|
||||
containedIn.add(input);
|
||||
for (const k in input) {
|
||||
const child = input[k];
|
||||
const childResult = deepMapInternal(child, mapFn, seen, containedIn);
|
||||
mappedIterable[k] = childResult;
|
||||
}
|
||||
containedIn.delete(input);
|
||||
return mappedIterable;
|
||||
} else {
|
||||
throw new Error(`Can't recurse into non-iterable type: ${input}`);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(soergel, kangyizhang) Reconsider naming of deepZip() to avoid confusion
|
||||
// with zip()
|
||||
|
||||
/**
|
||||
* Zip nested structures together in a recursive manner.
|
||||
*
|
||||
* This has the effect of transposing or pivoting data, e.g. converting it from
|
||||
* a row-major representation to a column-major representation.
|
||||
*
|
||||
* For example, `deepZip([{a: 1, b: 2}, {a: 3, b: 4}])` returns
|
||||
* `{a: [1, 3], b: [2, 4]}`.
|
||||
*
|
||||
* The inputs should all have the same nested structure (i.e., of arrays and
|
||||
* dicts). The result is a single object with the same nested structure, where
|
||||
* the leaves are arrays collecting the values of the inputs at that location
|
||||
* (or, optionally, the result of a custom function applied to those arrays).
|
||||
*
|
||||
* @param inputs: An array of the objects to zip together.
|
||||
* @param zipFn: (optional) A function that expects an array of elements at a
|
||||
* single node of the object tree, and returns a `DeepMapResult`. The
|
||||
* `DeepMapResult` either provides a result value for that node (i.e.,
|
||||
* representing the subtree), or indicates that the node should be processed
|
||||
* recursively. The default zipFn recurses as far as possible and places
|
||||
* arrays at the leaves.
|
||||
*/
|
||||
export function deepZip(
|
||||
inputs: any[], zipFn: (xs: any[]) => DeepMapResult = zipToList): any|any[] {
|
||||
return deepZipInternal(inputs, zipFn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param containedIn: An set containing objects on the reference path currently
|
||||
* being processed (used to detect cycles).
|
||||
*/
|
||||
function deepZipInternal(
|
||||
inputs: any[], zipFn: (xs: any[]) => DeepMapResult,
|
||||
containedIn: Set<{}> = new Set()): any|any[] {
|
||||
// The recursion follows the structure of input 0; it's assumed that all the
|
||||
// other inputs have the same structure.
|
||||
const input = inputs[0];
|
||||
if (containedIn.has(input)) {
|
||||
throw new Error('Circular references are not supported.');
|
||||
}
|
||||
const result = zipFn(inputs);
|
||||
|
||||
if (result.recurse && result.value !== null) {
|
||||
throw new Error(
|
||||
'A deep zip function may not return both a value and recurse=true.');
|
||||
}
|
||||
|
||||
if (!result.recurse) {
|
||||
return result.value;
|
||||
} else if (isIterable(input)) {
|
||||
// tslint:disable-next-line:no-any
|
||||
const mappedIterable: any|any[] = Array.isArray(input) ? [] : {};
|
||||
containedIn.add(input);
|
||||
for (const k in input) {
|
||||
const children = inputs.map(x => x[k]);
|
||||
const childResult = deepZipInternal(children, zipFn, containedIn);
|
||||
mappedIterable[k] = childResult;
|
||||
}
|
||||
containedIn.delete(input);
|
||||
return mappedIterable;
|
||||
} else {
|
||||
throw new Error(`Can't recurse into non-iterable type: ${input}`);
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
export function zipToList(x: any[]): DeepMapResult {
|
||||
if (x === null) {
|
||||
return null;
|
||||
}
|
||||
// TODO(soergel): validate array type?
|
||||
|
||||
if (isIterable(x[0])) {
|
||||
return {value: null, recurse: true};
|
||||
} else {
|
||||
return {value: x, recurse: false};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A return value for an async map function for use with deepMapAndAwaitAll.
|
||||
*
|
||||
* If recurse is true, the value should be empty, and iteration will continue
|
||||
* into the object or array.
|
||||
*/
|
||||
export type DeepMapAsyncResult = {
|
||||
value: Promise<any>,
|
||||
recurse: boolean
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply an async mapping function to a nested structure in a recursive manner.
|
||||
*
|
||||
* This first creates a nested structure of Promises, and then awaits all of
|
||||
* those, resulting in a single Promise for a resolved nested structure.
|
||||
*
|
||||
* The result of the mapping is an object with the same nested structure (i.e.,
|
||||
* of arrays and dicts) as the input, except that some subtrees are replaced,
|
||||
* according to the results of the mapping function.
|
||||
*
|
||||
* Mappings are memoized. Thus, if the nested structure contains the same
|
||||
* object in multiple positions, the output will contain the same mapped object
|
||||
* in those positions. Cycles are not supported, however.
|
||||
*
|
||||
* @param input: The object to which to apply the mapping function.
|
||||
* @param mapFn: A function that expects a single node of the object tree, and
|
||||
* returns a `DeepMapAsyncResult`. The `DeepMapAsyncResult` either provides
|
||||
* a `Promise` for a replacement value for that node (i.e., replacing the
|
||||
* subtree), or indicates that the node should be processed recursively. Note
|
||||
* that the decision whether or not to recurse must be made immediately; only
|
||||
* the mapped value may be promised.
|
||||
*/
|
||||
export async function deepMapAndAwaitAll(
|
||||
input: any, mapFn: (x: any) => DeepMapAsyncResult): Promise<any|any[]> {
|
||||
const seen: Map<any, Promise<any>> = new Map();
|
||||
|
||||
// First do a normal deepMap, collecting Promises in 'seen' as a side effect.
|
||||
deepMapInternal(input, mapFn, seen);
|
||||
|
||||
// Replace the Promises in 'seen' in place.
|
||||
// Note TypeScript provides no async map iteration, and regular map iteration
|
||||
// is broken too, so sadly we have to do Array.from() to make it work.
|
||||
// (There's no advantage to Promise.all(), and that would be tricky anyway.)
|
||||
for (const key of Array.from(seen.keys())) {
|
||||
const value = seen.get(key);
|
||||
if (tf.util.isPromise(value)) {
|
||||
const mappedValue = await value;
|
||||
seen.set(key, mappedValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Normal deepMap again, this time filling in the resolved values.
|
||||
// It's unfortunate that we have to do two passes.
|
||||
// TODO(soergel): test performance and think harder about a fast solution.
|
||||
const result = deepMapInternal(input, mapFn, seen);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the argument is iterable.
|
||||
*
|
||||
* @returns true if the argument is an array or any non-Tensor object.
|
||||
*/
|
||||
// tslint:disable-next-line:no-any
|
||||
export function isIterable(obj: any): boolean {
|
||||
return obj != null && (!ArrayBuffer.isView(obj)) &&
|
||||
(Array.isArray(obj) ||
|
||||
(typeof obj === 'object' && !(obj instanceof tf.Tensor)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the argument can be converted to Tensor.
|
||||
*
|
||||
* Tensors, primitives, arrays, and TypedArrays all qualify; anything else does
|
||||
* not.
|
||||
*
|
||||
* @returns true if the argument can be converted to Tensor.
|
||||
*/
|
||||
// tslint:disable-next-line:no-any
|
||||
export function canTensorify(obj: any): boolean {
|
||||
return obj == null || isPrimitive(obj) || Array.isArray(obj) ||
|
||||
(typeof obj === 'object' && (obj instanceof tf.Tensor)) ||
|
||||
tf.util.isTypedArray(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given `value` is a primitive type. Otherwise returns
|
||||
* false. This is equivalant to node util.isPrimitive
|
||||
*/
|
||||
function isPrimitive(value: any): boolean {
|
||||
return (
|
||||
value === null ||
|
||||
(typeof value !== 'object' && typeof value !== 'function'));
|
||||
}
|
||||
Generated
Vendored
-69
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
import {RingBuffer} from './ring_buffer';
|
||||
|
||||
export class GrowingRingBuffer<T> extends RingBuffer<T> {
|
||||
private static INITIAL_CAPACITY = 32;
|
||||
|
||||
/**
|
||||
* Constructs a `GrowingRingBuffer`.
|
||||
*/
|
||||
constructor() {
|
||||
super(GrowingRingBuffer.INITIAL_CAPACITY);
|
||||
}
|
||||
|
||||
isFull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
push(value: T) {
|
||||
if (super.isFull()) {
|
||||
this.expand();
|
||||
}
|
||||
super.push(value);
|
||||
}
|
||||
|
||||
unshift(value: T) {
|
||||
if (super.isFull()) {
|
||||
this.expand();
|
||||
}
|
||||
super.unshift(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Doubles the capacity of the buffer.
|
||||
*/
|
||||
private expand() {
|
||||
const newCapacity = this.capacity * 2;
|
||||
const newData = new Array<T>(newCapacity);
|
||||
const len = this.length();
|
||||
|
||||
// Rotate the buffer to start at index 0 again, since we can't just
|
||||
// allocate more space at the end.
|
||||
for (let i = 0; i < len; i++) {
|
||||
newData[i] = this.get(this.wrap(this.begin + i));
|
||||
}
|
||||
|
||||
this.data = newData;
|
||||
this.capacity = newCapacity;
|
||||
this.doubledCapacity = 2 * this.capacity;
|
||||
this.begin = 0;
|
||||
this.end = len;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-176
@@ -1,176 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* A ring buffer, providing O(1) FIFO, LIFO, and related operations.
|
||||
*/
|
||||
export class RingBuffer<T> {
|
||||
// Note we store the indices in the range 0 <= index < 2*capacity.
|
||||
// This allows us to distinguish the full from the empty case.
|
||||
// See https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/
|
||||
protected begin = 0; // inclusive
|
||||
protected end = 0; // exclusive
|
||||
protected doubledCapacity: number;
|
||||
|
||||
protected data: T[];
|
||||
|
||||
/**
|
||||
* Constructs a `RingBuffer`.
|
||||
* @param capacity The number of items that the buffer can accomodate.
|
||||
*/
|
||||
constructor(public capacity: number) {
|
||||
if (capacity == null) {
|
||||
throw new RangeError('Can\'t create a ring buffer of unknown capacity.');
|
||||
}
|
||||
if (capacity < 1) {
|
||||
throw new RangeError('Can\'t create ring buffer of capacity < 1.');
|
||||
}
|
||||
this.data = new Array<T>(capacity);
|
||||
this.doubledCapacity = 2 * capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map any index into the range 0 <= index < 2*capacity.
|
||||
*/
|
||||
protected wrap(index: number) {
|
||||
// don't trust % on negative numbers
|
||||
while (index < 0) {
|
||||
index += this.doubledCapacity;
|
||||
}
|
||||
return index % this.doubledCapacity;
|
||||
}
|
||||
|
||||
protected get(index: number) {
|
||||
if (index < 0) {
|
||||
throw new RangeError('Can\'t get item at a negative index.');
|
||||
}
|
||||
return this.data[index % this.capacity];
|
||||
}
|
||||
|
||||
protected set(index: number, value: T) {
|
||||
if (index < 0) {
|
||||
throw new RangeError('Can\'t set item at a negative index.');
|
||||
}
|
||||
this.data[index % this.capacity] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current number of items in the buffer.
|
||||
*/
|
||||
length(): number {
|
||||
let length = this.end - this.begin;
|
||||
if (length < 0) {
|
||||
length = this.doubledCapacity + length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports whether the buffer is full.
|
||||
* @returns true if the number of items in the buffer equals its capacity, and
|
||||
* false otherwise.
|
||||
*/
|
||||
isFull() {
|
||||
return this.length() === this.capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports whether the buffer is empty.
|
||||
* @returns true if the number of items in the buffer equals zero, and
|
||||
* false otherwise.
|
||||
*/
|
||||
isEmpty() {
|
||||
return this.length() === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the end of the buffer.
|
||||
*/
|
||||
push(value: T) {
|
||||
if (this.isFull()) {
|
||||
throw new RangeError('Ring buffer is full.');
|
||||
}
|
||||
this.set(this.end, value);
|
||||
this.end = this.wrap(this.end + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds many items to the end of the buffer, in order.
|
||||
*/
|
||||
pushAll(values: T[]) {
|
||||
for (const value of values) {
|
||||
this.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and returns the last item in the buffer.
|
||||
*/
|
||||
pop(): T {
|
||||
if (this.isEmpty()) {
|
||||
throw new RangeError('Ring buffer is empty.');
|
||||
}
|
||||
this.end = this.wrap(this.end - 1);
|
||||
const result = this.get(this.end);
|
||||
this.set(this.end, undefined);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the beginning of the buffer.
|
||||
*/
|
||||
unshift(value: T) {
|
||||
if (this.isFull()) {
|
||||
throw new RangeError('Ring buffer is full.');
|
||||
}
|
||||
this.begin = this.wrap(this.begin - 1);
|
||||
this.set(this.begin, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and returns the first item in the buffer.
|
||||
*/
|
||||
shift(): T {
|
||||
if (this.isEmpty()) {
|
||||
throw new RangeError('Ring buffer is empty.');
|
||||
}
|
||||
const result = this.get(this.begin);
|
||||
this.set(this.begin, undefined);
|
||||
this.begin = this.wrap(this.begin + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and returns a specific item in the buffer, and moves the last item
|
||||
* to the vacated slot. This is useful for implementing a shuffling stream.
|
||||
* Note that this operation necessarily scrambles the original order.
|
||||
*
|
||||
* @param relativeIndex: the index of the item to remove, relative to the
|
||||
* first item in the buffer (e.g., hiding the ring nature of the underlying
|
||||
* storage).
|
||||
*/
|
||||
shuffleExcise(relativeIndex: number): T {
|
||||
if (this.isEmpty()) {
|
||||
throw new RangeError('Ring buffer is empty.');
|
||||
}
|
||||
const index = this.wrap(this.begin + relativeIndex);
|
||||
const result = this.get(index);
|
||||
this.set(index, this.pop());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
// Skip tslint any type check cause this method is aiming to check type of
|
||||
// input.
|
||||
// tslint:disable-next-line:no-any
|
||||
export function isLocalPath(source: any): boolean {
|
||||
return (typeof source === 'string') && source.substr(0, 7) === 'file://';
|
||||
}
|
||||
Generated
Vendored
-152
@@ -1,152 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
// tslint:disable-next-line: no-imports-from-dist
|
||||
import {ALL_ENVS, BROWSER_ENVS, describeWithFlags, NODE_ENVS, registerTestEnv} from '@tensorflow/tfjs-core/dist/jasmine_util';
|
||||
|
||||
// Provide fake video stream
|
||||
export function setupFakeVideoStream() {
|
||||
const width = 100;
|
||||
const height = 200;
|
||||
const canvasElement = document.createElement('canvas');
|
||||
const ctx = canvasElement.getContext('2d');
|
||||
ctx.fillStyle = 'rgb(1,2,3)';
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
// tslint:disable-next-line:no-any
|
||||
const stream = (canvasElement as any).captureStream(60);
|
||||
navigator.mediaDevices.getUserMedia = async () => {
|
||||
return stream;
|
||||
};
|
||||
}
|
||||
|
||||
export async function replaceHTMLVideoElementSource(
|
||||
videoElement: HTMLVideoElement) {
|
||||
const source = document.createElement('source');
|
||||
// tslint:disable:max-line-length
|
||||
source.src =
|
||||
'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAAu1tZGF0AAACrQYF//+p3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE1NSByMjkwMSA3ZDBmZjIyIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxOCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MSBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aHJlYWRzPTMgbG9va2FoZWFkX3RocmVhZHM9MSBzbGljZWRfdGhyZWFkcz0wIG5yPTAgZGVjaW1hdGU9MSBpbnRlcmxhY2VkPTAgYmx1cmF5X2NvbXBhdD0wIGNvbnN0cmFpbmVkX2ludHJhPTAgYmZyYW1lcz0zIGJfcHlyYW1pZD0yIGJfYWRhcHQ9MSBiX2JpYXM9MCBkaXJlY3Q9MSB3ZWlnaHRiPTEgb3Blbl9nb3A9MCB3ZWlnaHRwPTIga2V5aW50PTI1MCBrZXlpbnRfbWluPTEgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MCByYz1jcmYgbWJ0cmVlPTEgY3JmPTI4LjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IGlwX3JhdGlvPTEuNDAgYXE9MToxLjAwAIAAAAAwZYiEAD//8m+P5OXfBeLGOfKE3xkODvFZuBflHv/+VwJIta6cbpIo4ABLoKBaYTkTAAAC7m1vb3YAAABsbXZoZAAAAAAAAAAAAAAAAAAAA+gAAAPoAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIYdHJhawAAAFx0a2hkAAAAAwAAAAAAAAAAAAAAAQAAAAAAAAPoAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAACgAAAAWgAAAAAAJGVkdHMAAAAcZWxzdAAAAAAAAAABAAAD6AAAAAAAAQAAAAABkG1kaWEAAAAgbWRoZAAAAAAAAAAAAAAAAAAAQAAAAEAAVcQAAAAAAC1oZGxyAAAAAAAAAAB2aWRlAAAAAAAAAAAAAAAAVmlkZW9IYW5kbGVyAAAAATttaW5mAAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAD7c3RibAAAAJdzdHNkAAAAAAAAAAEAAACHYXZjMQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAACgAFoASAAAAEgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABj//wAAADFhdmNDAWQACv/hABhnZAAKrNlCjfkhAAADAAEAAAMAAg8SJZYBAAZo6+JLIsAAAAAYc3R0cwAAAAAAAAABAAAAAQAAQAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAFHN0c3oAAAAAAAAC5QAAAAEAAAAUc3RjbwAAAAAAAAABAAAAMAAAAGJ1ZHRhAAAAWm1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAALWlsc3QAAAAlqXRvbwAAAB1kYXRhAAAAAQAAAABMYXZmNTguMTIuMTAw';
|
||||
source.type = 'video/mp4';
|
||||
videoElement.srcObject = null;
|
||||
videoElement.appendChild(source);
|
||||
videoElement.play();
|
||||
|
||||
if (videoElement.readyState < 2) {
|
||||
await new Promise(resolve => {
|
||||
videoElement.addEventListener('loadeddata', () => resolve());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Register backends.
|
||||
registerTestEnv({name: 'cpu', backendName: 'cpu'});
|
||||
registerTestEnv({
|
||||
name: 'webgl2',
|
||||
backendName: 'webgl',
|
||||
flags: {
|
||||
'WEBGL_VERSION': 2,
|
||||
'WEBGL_CPU_FORWARD': false,
|
||||
'WEBGL_SIZE_UPLOAD_UNIFORM': 0
|
||||
}
|
||||
});
|
||||
|
||||
export function describeAllEnvs(testName: string, tests: () => void) {
|
||||
describeWithFlags(testName, ALL_ENVS, () => {
|
||||
tests();
|
||||
});
|
||||
}
|
||||
|
||||
export function describeBrowserEnvs(testName: string, tests: () => void) {
|
||||
describeWithFlags(testName, BROWSER_ENVS, () => {
|
||||
tests();
|
||||
});
|
||||
}
|
||||
|
||||
export function describeNodeEnvs(testName: string, tests: () => void) {
|
||||
describeWithFlags(testName, NODE_ENVS, () => {
|
||||
tests();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing Utilities for browser audeo stream.
|
||||
*/
|
||||
export function setupFakeAudeoStream() {
|
||||
navigator.mediaDevices.getUserMedia = async () => {
|
||||
const stream = new MediaStream();
|
||||
return stream;
|
||||
};
|
||||
// tslint:disable-next-line:no-any
|
||||
(window as any).AudioContext = FakeAudioContext.createInstance;
|
||||
}
|
||||
|
||||
export class FakeAudioContext {
|
||||
readonly sampleRate = 44100;
|
||||
|
||||
static createInstance() {
|
||||
return new FakeAudioContext();
|
||||
}
|
||||
|
||||
createMediaStreamSource() {
|
||||
return new FakeMediaStreamAudioSourceNode();
|
||||
}
|
||||
|
||||
createAnalyser() {
|
||||
return new FakeAnalyser();
|
||||
}
|
||||
|
||||
close(): void {}
|
||||
}
|
||||
|
||||
export class FakeAudioMediaStream {
|
||||
constructor() {}
|
||||
getTracks(): Array<{}> {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
class FakeMediaStreamAudioSourceNode {
|
||||
constructor() {}
|
||||
connect(node: {}): void {}
|
||||
}
|
||||
|
||||
class FakeAnalyser {
|
||||
fftSize: number;
|
||||
smoothingTimeConstant: number;
|
||||
private x: number;
|
||||
constructor() {
|
||||
this.x = 0;
|
||||
}
|
||||
|
||||
getFloatFrequencyData(data: Float32Array): void {
|
||||
const xs: number[] = [];
|
||||
for (let i = 0; i < this.fftSize / 2; ++i) {
|
||||
xs.push(this.x++);
|
||||
}
|
||||
data.set(new Float32Array(xs));
|
||||
}
|
||||
|
||||
getFloatTimeDomainData(data: Float32Array): void {
|
||||
const xs: number[] = [];
|
||||
for (let i = 0; i < this.fftSize / 2; ++i) {
|
||||
xs.push(-(this.x++));
|
||||
}
|
||||
data.set(new Float32Array(xs));
|
||||
}
|
||||
|
||||
disconnect(): void {}
|
||||
}
|
||||
Generated
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
/** @license See the LICENSE file. */
|
||||
|
||||
// This code is auto-generated, do not modify this file!
|
||||
const version = '3.6.0';
|
||||
export {version};
|
||||
Generated
Vendored
-249
@@ -1,249 +0,0 @@
|
||||
TensorFlow.js Layers is licensed under both the MIT and the Apache 2.0 licenses.
|
||||
|
||||
================================================================================
|
||||
COPYRIGHT
|
||||
|
||||
All contributions by François Chollet:
|
||||
Copyright (c) 2015 - 2018, François Chollet.
|
||||
All rights reserved.
|
||||
|
||||
All contributions by Google:
|
||||
Copyright (c) 2015 - 2018, Google LLC.
|
||||
All rights reserved.
|
||||
|
||||
All contributions by Microsoft:
|
||||
Copyright (c) 2017 - 2018, Microsoft, LLC
|
||||
All rights reserved.
|
||||
|
||||
All other contributions:
|
||||
Copyright (c) 2015 - 2018, the respective contributors.
|
||||
All rights reserved.
|
||||
|
||||
Each contributor holds copyright over their respective contributions.
|
||||
The project versioning (Git) records all such contribution source information.
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
================================================================================
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Generated
Vendored
-94
@@ -1,94 +0,0 @@
|
||||
# TensorFlow.js Layers: High-Level Machine Learning Model API
|
||||
|
||||
A part of the TensorFlow.js ecosystem, TensorFlow.js Layers is a high-level
|
||||
API built on [TensorFlow.js Core](/tfjs-core),
|
||||
enabling users to build, train and execute deep learning models in the browser.
|
||||
TensorFlow.js Layers is modeled after
|
||||
[Keras](https://keras.io/) and
|
||||
[tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) and can
|
||||
load models saved from those libraries.
|
||||
|
||||
## Importing
|
||||
|
||||
There are three ways to import TensorFlow.js Layers
|
||||
|
||||
1. You can access TensorFlow.js Layers through the union package
|
||||
between the TensorFlow.js Core and Layers:
|
||||
[@tensorflow/tfjs](https://www.npmjs.com/package/@tensorflow/tfjs)
|
||||
2. You can get [TensorFlow.js](https://github.com/tensorflow/tfjs) Layers as a module:
|
||||
[@tensorflow/tfjs-layers](https://www.npmjs.com/package/@tensorflow/tfjs-layers).
|
||||
Note that `tfjs-layers` has peer dependency on tfjs-core, so if you import
|
||||
`@tensorflow/tfjs-layers`, you also need to import
|
||||
`@tensorflow/tfjs-core`.
|
||||
3. As a standalone through [unpkg](https://unpkg.com/).
|
||||
|
||||
Option 1 is the most convenient, but leads to a larger bundle size (we will be
|
||||
adding more packages to it in the future). Use option 2 if you care about bundle
|
||||
size.
|
||||
|
||||
## Getting started
|
||||
|
||||
### Building, training and executing a model
|
||||
|
||||
The following example shows how to build a toy model with only one `dense` layer
|
||||
to perform linear regression.
|
||||
|
||||
```js
|
||||
import * as tf from '@tensorflow/tfjs';
|
||||
|
||||
// A sequential model is a container which you can add layers to.
|
||||
const model = tf.sequential();
|
||||
|
||||
// Add a dense layer with 1 output unit.
|
||||
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
|
||||
|
||||
// Specify the loss type and optimizer for training.
|
||||
model.compile({loss: 'meanSquaredError', optimizer: 'SGD'});
|
||||
|
||||
// Generate some synthetic data for training.
|
||||
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);
|
||||
const ys = tf.tensor2d([[1], [3], [5], [7]], [4, 1]);
|
||||
|
||||
// Train the model.
|
||||
await model.fit(xs, ys, {epochs: 500});
|
||||
|
||||
// Ater the training, perform inference.
|
||||
const output = model.predict(tf.tensor2d([[5]], [1, 1]));
|
||||
output.print();
|
||||
```
|
||||
|
||||
### Loading a pretrained Keras model
|
||||
|
||||
You can also load a model previously trained and saved from elsewhere (e.g.,
|
||||
from Python Keras) and use it for inference or transfer learning in the browser.
|
||||
|
||||
For example, in Python, save your Keras model using
|
||||
[tensorflowjs](https://pypi.org/project/tensorflowjs/),
|
||||
which can be installed using `pip install tensorflowjs`.
|
||||
|
||||
|
||||
```python
|
||||
import tensorflowjs as tfjs
|
||||
|
||||
# ... Create and train your Keras model.
|
||||
|
||||
# Save your Keras model in TensorFlow.js format.
|
||||
tfjs.converters.save_keras_model(model, '/path/to/tfjs_artifacts/')
|
||||
|
||||
# Then use your favorite web server to serve the directory at a URL, say
|
||||
# http://foo.bar/tfjs_artifacts/model.json
|
||||
```
|
||||
|
||||
To load the model with TensorFlow.js Layers:
|
||||
|
||||
```js
|
||||
import * as tf from '@tensorflow/tfjs';
|
||||
|
||||
const model = await tf.loadLayersModel('http://foo.bar/tfjs_artifacts/model.json');
|
||||
// Now the model is ready for inference, evaluation or re-training.
|
||||
```
|
||||
|
||||
## For more information
|
||||
|
||||
- [TensorFlow.js API documentation](https://js.tensorflow.org/api/latest/)
|
||||
- [TensorFlow.js Tutorials](https://js.tensorflow.org/tutorials/)
|
||||
Generated
Vendored
-184
@@ -1,184 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
* =============================================================================
|
||||
*/
|
||||
import { serialization, Tensor } from '@tensorflow/tfjs-core';
|
||||
import { ActivationIdentifier } from './keras_format/activation_config';
|
||||
/**
|
||||
* Base class for Activations.
|
||||
*
|
||||
* Special note: due to cross-language compatibility reasons, the
|
||||
* static readonly className field in this family of classes must be set to
|
||||
* the initialLowerCamelCase name of the activation.
|
||||
*/
|
||||
export declare abstract class Activation extends serialization.Serializable {
|
||||
abstract apply(tensor: Tensor, axis?: number): Tensor;
|
||||
getConfig(): serialization.ConfigDict;
|
||||
}
|
||||
/**
|
||||
* Exponential linear unit (ELU).
|
||||
* Reference: https://arxiv.org/abs/1511.07289
|
||||
*/
|
||||
export declare class Elu extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "elu";
|
||||
/**
|
||||
* Calculate the activation function.
|
||||
*
|
||||
* @param x: Input.
|
||||
* @param alpha: Scaling factor the negative section.
|
||||
* @return Output of the ELU activation.
|
||||
*/
|
||||
apply(x: Tensor, alpha?: number): Tensor;
|
||||
}
|
||||
/**
|
||||
* Scaled Exponential Linear Unit. (Klambauer et al., 2017).
|
||||
* Reference: Self-Normalizing Neural Networks, https://arxiv.org/abs/1706.02515
|
||||
* Notes:
|
||||
* - To be used together with the initialization "lecunNormal".
|
||||
* - To be used together with the dropout variant "AlphaDropout".
|
||||
*/
|
||||
export declare class Selu extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "selu";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
/**
|
||||
* Rectified linear unit
|
||||
*/
|
||||
export declare class Relu extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "relu";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
/**
|
||||
* Rectified linear unit activation maxing out at 6.0.
|
||||
*/
|
||||
export declare class Relu6 extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "relu6";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
export declare class Linear extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "linear";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
/**
|
||||
* Sigmoid activation function.
|
||||
*/
|
||||
export declare class Sigmoid extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "sigmoid";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
/**
|
||||
* Segment-wise linear approximation of sigmoid.
|
||||
*/
|
||||
export declare class HardSigmoid extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "hardSigmoid";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
/**
|
||||
* Softplus activation function.
|
||||
*/
|
||||
export declare class Softplus extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "softplus";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
/**
|
||||
* Softsign activation function.
|
||||
*/
|
||||
export declare class Softsign extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "softsign";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
/**
|
||||
* Hyperbolic tangent function.
|
||||
*/
|
||||
export declare class Tanh extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "tanh";
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
/**
|
||||
* Softmax activation function
|
||||
*/
|
||||
export declare class Softmax extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "softmax";
|
||||
/**
|
||||
* Calculate the activation function.
|
||||
*
|
||||
* @param x Tensor.
|
||||
* @param axis Integer, axis along which the softmax normalization is applied.
|
||||
* Invalid if < 2, as softmax across 1 (the batch dimension) is assumed to be
|
||||
* an error.
|
||||
*
|
||||
* @returns a Tensor of the same shape as x
|
||||
*
|
||||
* @throws ValueError: In case `dim(x) < 2`.
|
||||
*/
|
||||
apply(x: Tensor, axis?: number): Tensor;
|
||||
}
|
||||
/**
|
||||
* Log softmax activation function
|
||||
*/
|
||||
export declare class LogSoftmax extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "logSoftmax";
|
||||
/**
|
||||
* Calculate the activation function of log softmax:
|
||||
* log( exp(x_i) / sum(exp(x)) )
|
||||
*
|
||||
* @param x Tensor.
|
||||
* @param axis Integer, axis along which the softmax normalization is applied.
|
||||
* Invalid if < 2, as softmax across 1 (the batch dimension) is assumed to be
|
||||
* an error.
|
||||
*
|
||||
* @returns a Tensor of the same shape as x
|
||||
*
|
||||
* @throws ValueError: In case `dim(x) < 2`.
|
||||
*/
|
||||
apply(x: Tensor, axis?: number): Tensor;
|
||||
}
|
||||
/**
|
||||
* Swish activation function
|
||||
*/
|
||||
export declare class Swish extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "swish";
|
||||
/**
|
||||
* Calculate the activation function.
|
||||
*
|
||||
* @param x Tensor.
|
||||
* @param alpha Scaling factor for the sigmoid function.
|
||||
* @returns a Tensor of the same shape as x
|
||||
*/
|
||||
apply(x: Tensor, alpha?: number): Tensor;
|
||||
}
|
||||
/**
|
||||
* Mish activation function
|
||||
*/
|
||||
export declare class Mish extends Activation {
|
||||
/** @nocollapse */
|
||||
static readonly className = "mish";
|
||||
/**
|
||||
* Calculate the activation function.
|
||||
*
|
||||
* @param x Tensor.
|
||||
* @returns a Tensor of the same shape as x
|
||||
*/
|
||||
apply(x: Tensor): Tensor;
|
||||
}
|
||||
export declare function serializeActivation(activation: Activation): string;
|
||||
export declare function deserializeActivation(config: serialization.ConfigDict, customObjects?: serialization.ConfigDict): Activation;
|
||||
export declare function getActivation(identifier: ActivationIdentifier | serialization.ConfigDict | Activation): Activation;
|
||||
Generated
Vendored
-255
@@ -1,255 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
* =============================================================================
|
||||
*/
|
||||
// Layer activation functions
|
||||
import * as tfc from '@tensorflow/tfjs-core';
|
||||
import { serialization, tidy } from '@tensorflow/tfjs-core';
|
||||
import * as K from './backend/tfjs_backend';
|
||||
import { deserializeKerasObject } from './utils/generic_utils';
|
||||
/**
|
||||
* Base class for Activations.
|
||||
*
|
||||
* Special note: due to cross-language compatibility reasons, the
|
||||
* static readonly className field in this family of classes must be set to
|
||||
* the initialLowerCamelCase name of the activation.
|
||||
*/
|
||||
export class Activation extends serialization.Serializable {
|
||||
getConfig() {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Exponential linear unit (ELU).
|
||||
* Reference: https://arxiv.org/abs/1511.07289
|
||||
*/
|
||||
export class Elu extends Activation {
|
||||
/**
|
||||
* Calculate the activation function.
|
||||
*
|
||||
* @param x: Input.
|
||||
* @param alpha: Scaling factor the negative section.
|
||||
* @return Output of the ELU activation.
|
||||
*/
|
||||
apply(x, alpha = 1) {
|
||||
return K.elu(x, alpha);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Elu.className = 'elu';
|
||||
serialization.registerClass(Elu);
|
||||
/**
|
||||
* Scaled Exponential Linear Unit. (Klambauer et al., 2017).
|
||||
* Reference: Self-Normalizing Neural Networks, https://arxiv.org/abs/1706.02515
|
||||
* Notes:
|
||||
* - To be used together with the initialization "lecunNormal".
|
||||
* - To be used together with the dropout variant "AlphaDropout".
|
||||
*/
|
||||
export class Selu extends Activation {
|
||||
apply(x) {
|
||||
return tfc.selu(x);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Selu.className = 'selu';
|
||||
serialization.registerClass(Selu);
|
||||
/**
|
||||
* Rectified linear unit
|
||||
*/
|
||||
export class Relu extends Activation {
|
||||
apply(x) {
|
||||
return tfc.relu(x);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Relu.className = 'relu';
|
||||
serialization.registerClass(Relu);
|
||||
/**
|
||||
* Rectified linear unit activation maxing out at 6.0.
|
||||
*/
|
||||
export class Relu6 extends Activation {
|
||||
apply(x) {
|
||||
return tidy(() => tfc.minimum(6.0, tfc.relu(x)));
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Relu6.className = 'relu6';
|
||||
serialization.registerClass(Relu6);
|
||||
//* Linear activation (no-op) */
|
||||
export class Linear extends Activation {
|
||||
apply(x) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Linear.className = 'linear';
|
||||
serialization.registerClass(Linear);
|
||||
/**
|
||||
* Sigmoid activation function.
|
||||
*/
|
||||
export class Sigmoid extends Activation {
|
||||
apply(x) {
|
||||
return tfc.sigmoid(x);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Sigmoid.className = 'sigmoid';
|
||||
serialization.registerClass(Sigmoid);
|
||||
/**
|
||||
* Segment-wise linear approximation of sigmoid.
|
||||
*/
|
||||
export class HardSigmoid extends Activation {
|
||||
apply(x) {
|
||||
return K.hardSigmoid(x);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
HardSigmoid.className = 'hardSigmoid';
|
||||
serialization.registerClass(HardSigmoid);
|
||||
/**
|
||||
* Softplus activation function.
|
||||
*/
|
||||
export class Softplus extends Activation {
|
||||
apply(x) {
|
||||
return tfc.softplus(x);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Softplus.className = 'softplus';
|
||||
serialization.registerClass(Softplus);
|
||||
/**
|
||||
* Softsign activation function.
|
||||
*/
|
||||
export class Softsign extends Activation {
|
||||
apply(x) {
|
||||
return K.softsign(x);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Softsign.className = 'softsign';
|
||||
serialization.registerClass(Softsign);
|
||||
/**
|
||||
* Hyperbolic tangent function.
|
||||
*/
|
||||
export class Tanh extends Activation {
|
||||
apply(x) {
|
||||
return tfc.tanh(x);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Tanh.className = 'tanh';
|
||||
serialization.registerClass(Tanh);
|
||||
/**
|
||||
* Softmax activation function
|
||||
*/
|
||||
export class Softmax extends Activation {
|
||||
/**
|
||||
* Calculate the activation function.
|
||||
*
|
||||
* @param x Tensor.
|
||||
* @param axis Integer, axis along which the softmax normalization is applied.
|
||||
* Invalid if < 2, as softmax across 1 (the batch dimension) is assumed to be
|
||||
* an error.
|
||||
*
|
||||
* @returns a Tensor of the same shape as x
|
||||
*
|
||||
* @throws ValueError: In case `dim(x) < 2`.
|
||||
*/
|
||||
apply(x, axis = (-1)) {
|
||||
return tfc.softmax(x, axis);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Softmax.className = 'softmax';
|
||||
serialization.registerClass(Softmax);
|
||||
/**
|
||||
* Log softmax activation function
|
||||
*/
|
||||
export class LogSoftmax extends Activation {
|
||||
/**
|
||||
* Calculate the activation function of log softmax:
|
||||
* log( exp(x_i) / sum(exp(x)) )
|
||||
*
|
||||
* @param x Tensor.
|
||||
* @param axis Integer, axis along which the softmax normalization is applied.
|
||||
* Invalid if < 2, as softmax across 1 (the batch dimension) is assumed to be
|
||||
* an error.
|
||||
*
|
||||
* @returns a Tensor of the same shape as x
|
||||
*
|
||||
* @throws ValueError: In case `dim(x) < 2`.
|
||||
*/
|
||||
apply(x, axis = (-1)) {
|
||||
return tfc.logSoftmax(x, axis);
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
LogSoftmax.className = 'logSoftmax';
|
||||
serialization.registerClass(LogSoftmax);
|
||||
/**
|
||||
* Swish activation function
|
||||
*/
|
||||
export class Swish extends Activation {
|
||||
/**
|
||||
* Calculate the activation function.
|
||||
*
|
||||
* @param x Tensor.
|
||||
* @param alpha Scaling factor for the sigmoid function.
|
||||
* @returns a Tensor of the same shape as x
|
||||
*/
|
||||
apply(x, alpha = 1) {
|
||||
return tidy(() => tfc.sigmoid(x.mul(alpha)).mul(x));
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Swish.className = 'swish';
|
||||
serialization.registerClass(Swish);
|
||||
/**
|
||||
* Mish activation function
|
||||
*/
|
||||
export class Mish extends Activation {
|
||||
/**
|
||||
* Calculate the activation function.
|
||||
*
|
||||
* @param x Tensor.
|
||||
* @returns a Tensor of the same shape as x
|
||||
*/
|
||||
apply(x) {
|
||||
return tidy(() => tfc.mul(x, tfc.tanh(tfc.softplus(x))));
|
||||
}
|
||||
}
|
||||
/** @nocollapse */
|
||||
Mish.className = 'mish';
|
||||
serialization.registerClass(Mish);
|
||||
export function serializeActivation(activation) {
|
||||
return activation.getClassName();
|
||||
}
|
||||
export function deserializeActivation(config, customObjects = {}) {
|
||||
return deserializeKerasObject(config, serialization.SerializationMap.getMap().classNameMap, customObjects, 'activation');
|
||||
}
|
||||
export function getActivation(identifier) {
|
||||
if (identifier == null) {
|
||||
const config = {};
|
||||
config['className'] = 'linear';
|
||||
config['config'] = {};
|
||||
return deserializeActivation(config);
|
||||
}
|
||||
if (typeof identifier === 'string') {
|
||||
const config = {};
|
||||
config['className'] = identifier;
|
||||
config['config'] = {};
|
||||
return deserializeActivation(config);
|
||||
}
|
||||
else if (identifier instanceof Activation) {
|
||||
return identifier;
|
||||
}
|
||||
else {
|
||||
return deserializeActivation(identifier);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=activations.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"activations.js","sourceRoot":"","sources":["../src/activations.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\n// Layer activation functions\nimport * as tfc from '@tensorflow/tfjs-core';\nimport {serialization, Tensor, tidy} from '@tensorflow/tfjs-core';\nimport * as K from './backend/tfjs_backend';\nimport {ActivationIdentifier} from './keras_format/activation_config';\nimport Line truncated
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"activations_test.js","sourceRoot":"","sources":["../src/activations_test.ts"],"names":[],"mappings":"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 truncated
|
||||
Generated
Vendored
-23
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
* =============================================================================
|
||||
*/
|
||||
import { DataFormat } from '../keras_format/common';
|
||||
/**
|
||||
* Returns the value of the fuzz factor used in numeric expressions.
|
||||
*/
|
||||
export declare function epsilon(): number;
|
||||
/**
|
||||
* Sets the value of the fuzz factor used in numeric expressions.
|
||||
* @param e New value of epsilon.
|
||||
*/
|
||||
export declare function setEpsilon(e: number): void;
|
||||
/**
|
||||
* Returns the default image data format convention.
|
||||
*/
|
||||
export declare function imageDataFormat(): DataFormat;
|
||||
Loaded 100 of 999 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user