* Adds a layer instance on top of the layer stack. * * ```js * const model = tf.sequential(); * model.add(tf.layers.dense({units: 8, inputShape: [1]})); * model.add(tf.layers.dense({units: 4, activation: 'relu6'})); * model.add(tf.layers.dense({units: 1, activation: 'relu6'}));
(layer: Layer)
| 450 | * @doc {heading: 'Models', subheading: 'Classes'} |
| 451 | */ |
| 452 | add(layer: Layer): void { |
| 453 | const isLayerModelInstance = |
| 454 | layer instanceof Sequential || layer instanceof LayersModel; |
| 455 | let modelLayer: LayersModel; |
| 456 | if (isLayerModelInstance) { |
| 457 | modelLayer = layer as LayersModel; |
| 458 | if (modelLayer.outputs.length !== 1) { |
| 459 | throw new ValueError( |
| 460 | 'All layers in a Sequential model ' + |
| 461 | 'should have a single output tensor. ' + |
| 462 | 'For multi-output layers, ' + |
| 463 | 'use the functional API.'); |
| 464 | } |
| 465 | if (modelLayer.inputs.length !== 1) { |
| 466 | throw new ValueError( |
| 467 | 'All layers in a Sequential model ' + |
| 468 | 'should have a single input tensor. ' + |
| 469 | 'For multi-input layers, ' + |
| 470 | 'use the functional API.'); |
| 471 | } |
| 472 | } |
| 473 | |
| 474 | if (this.outputs.length === 0) { |
| 475 | // first layer in model: check that it is an input layer |
| 476 | if (layer.inboundNodes.length === 0) { |
| 477 | // create an input layer |
| 478 | if (layer.batchInputShape == null) { |
| 479 | throw new ValueError( |
| 480 | 'The first layer in a Sequential model must ' + |
| 481 | 'get an `inputShape` or `batchInputShape` argument.'); |
| 482 | } |
| 483 | // Instantiate the input layer. |
| 484 | const x = Input({ |
| 485 | batchShape: layer.batchInputShape, |
| 486 | dtype: layer.dtype, |
| 487 | name: layer.name + '_input' |
| 488 | }); |
| 489 | // This will build the current layer and create the node connecting |
| 490 | // the current layer to the input layer we just created. |
| 491 | layer.apply(x); |
| 492 | } |
| 493 | |
| 494 | if (isLayerModelInstance) { |
| 495 | this.outputs = modelLayer.outputs; |
| 496 | this.inputs = modelLayer.inputs; |
| 497 | } else { |
| 498 | if (layer.inboundNodes.length !== 1) { |
| 499 | throw new ValueError( |
| 500 | 'A layer added to a Sequential model must not already be ' + |
| 501 | `connected somewhere else. LayersModel received layer ${ |
| 502 | layer.name} ` + |
| 503 | `which has ${layer.inboundNodes.length} pre-existing inbound ` + |
| 504 | 'connections.'); |
| 505 | } |
| 506 | |
| 507 | if (layer.inboundNodes[0].outputTensors.length !== 1) { |
| 508 | throw new ValueError( |
| 509 | 'All layers in a Sequential model ' + |