* refactor toc * refactor toc * Change to pydata-sphinx-theme and update packages requirement list for ReadtheDocs * Remove customized css for old theme * Add index page to each top bar section and limit dropdown maximum to be 4 * Use js to change 'More' to 'Libraries' * Add custom.css to conf.py for further css changes * Add BigDL logo and search bar * refactor toc * refactor toc and add overview * refactor toc and add overview * refactor toc and add overview * refactor get started * add paper and video section * add videos * add grid columns in landing page * add document roadmap to index * reapply search bar and github icon commit * reorg orca and chronos sections * Test: weaken ads by js * update: change left attrbute * update: add comments * update: change opacity to 0.7 * Remove useless theme template override for old theme * Add sidebar releases component in the home page * Remove sidebar search and restore top nav search button * Add BigDL handouts * Add back to homepage button to pages except from the home page * Update releases contents & styles in left sidebar * Add version badge to the top bar * Test: weaken ads by js * update: add comments * remove landing page contents * rfix chronos install * refactor install * refactor chronos section titles * refactor nano index * change chronos landing * revise chronos landing page * add document navigator to nano landing page * revise install landing page * Improve css of versions in sidebar * Make handouts image pointing to a page in new tab * add win guide to install * add dliib installation * revise title bar * rename index files * add index page for user guide * add dllib and orca API * update user guide landing page * refactor side bar * Remove extra style configuration of card components & make different card usage consistent * Remove extra styles for Nano how-to guides * Remove extra styles for Chronos how-to guides * Remove dark mode for now * Update index page description * Add decision tree for choosing BigDL libraries in index page * add dllib models api, revise core layers formats * Change primary & info color in light mode * Restyle card components * Restructure Chronos landing page * Update card style * Update BigDL library selection decision tree * Fix failed Chronos tutorials filter * refactor PPML documents * refactor and add friesian documents * add friesian arch diagram * update landing pages and fill key features guide index page * Restyle link card component * Style video frames in PPML sections * Adjust Nano landing page * put api docs to the last in index for convinience * Make badge horizontal padding smaller & small changes * Change the second letter of all header titles to be small capitalizd * Small changes on Chronos index page * Revise decision tree to make it smaller * Update: try to change the position of ads. * Bugfix: deleted nonexist file config * Update: update ad JS/CSS/config * Update: change ad. * Update: delete my template and change files. * Update: change chronos installation table color. * Update: change table font color to --pst-color-primary-text * Remove old contents in landing page sidebar * Restyle badge for usage in card footer again * Add quicklinks template on landing page sidebar * add quick links * Add scala logo * move tf, pytorch out of the link * change orca key features cards * fix typo * fix a mistake in wording * Restyle badge for card footer * Update decision tree * Remove useless html templates * add more api docs and update tutorials in dllib * update chronos install using new style * merge changes in nano doc from master * fix quickstart links in sidebar quicklinks * Make tables responsive * Fix overflow in api doc * Fix list indents problems in [User guide] section * Further fixes to nested bullets contents in [User Guide] section * Fix strange title in Nano 5-min doc * Fix list indent problems in [DLlib] section * Fix misnumbered list problems and other small fixes for [Chronos] section * Fix list indent problems and other small fixes for [Friesian] section * Fix list indent problem and other small fixes for [PPML] section * Fix list indent problem for developer guide * Fix list indent problem for [Cluster Serving] section * fix dllib links * Fix wrong relative link in section landing page Co-authored-by: Yuwen Hu <yuwen.hu@intel.com> Co-authored-by: Juntao Luo <1072087358@qq.com>
		
			
				
	
	
		
			187 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Keras-Like API
 | 
						|
 | 
						|
## 1. Introduction
 | 
						|
[DLlib](dllib.md) provides __Keras-like API__ based on [__Keras 1.2.2__](https://faroit.github.io/keras-docs/1.2.2/) for distributed deep learning on Apache Spark. Users can easily use the Keras-like API to create a neural network model, and train, evaluate or tune it in a distributed fashion on Spark.
 | 
						|
 | 
						|
To define a model in Scala using the Keras-like API, one just needs to import the following packages:
 | 
						|
 | 
						|
```scala
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.layers._
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.models._
 | 
						|
import com.intel.analytics.bigdl.dllib.utils.Shape
 | 
						|
```
 | 
						|
 | 
						|
One of the highlighted features with regard to the new API is __shape inference__. Users only need to specify the input shape (a `Shape` object __excluding__ batch dimension, for example, `inputShape=Shape(3, 4)` for 3D input) for the first layer of a model and for the remaining layers, the input dimension will be automatically inferred.
 | 
						|
 | 
						|
---
 | 
						|
## 2. LeNet Example
 | 
						|
Here we use the Keras-like API to define a LeNet CNN model and train it on the MNIST dataset:
 | 
						|
 | 
						|
```scala
 | 
						|
import com.intel.analytics.bigdl.numeric.NumericFloat
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.layers._
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.models._
 | 
						|
import com.intel.analytics.bigdl.dllib.utils.Shape
 | 
						|
 | 
						|
val model = Sequential()
 | 
						|
model.add(Reshape(Array(1, 28, 28), inputShape = Shape(28, 28, 1)))
 | 
						|
model.add(Convolution2D(6, 5, 5, activation = "tanh").setName("conv1_5x5"))
 | 
						|
model.add(MaxPooling2D())
 | 
						|
model.add(Convolution2D(12, 5, 5, activation = "tanh").setName("conv2_5x5"))
 | 
						|
model.add(MaxPooling2D())
 | 
						|
model.add(Flatten())
 | 
						|
model.add(Dense(100, activation = "tanh").setName("fc1"))
 | 
						|
model.add(Dense(10, activation = "softmax").setName("fc2"))
 | 
						|
 | 
						|
model.getInputShape().toSingle().toArray // Array(-1, 28, 28, 1)
 | 
						|
model.getOutputShape().toSingle().toArray // Array(-1, 10)
 | 
						|
```
 | 
						|
---
 | 
						|
## 3. Shape
 | 
						|
Input and output shapes of a model in the Keras-like API are described by the `Shape` object in Scala, which can be classified into `SingleShape` and `MultiShape`.
 | 
						|
 | 
						|
`SingleShape` is just a list of Int indicating shape dimensions while `MultiShape` is essentially a list of `Shape`.
 | 
						|
 | 
						|
Example code to create a shape:
 | 
						|
```scala
 | 
						|
// create a SingleShape
 | 
						|
val shape1 = Shape(3, 4)
 | 
						|
// create a MultiShape consisting of two SingleShape
 | 
						|
val shape2 = Shape(List(Shape(1, 2, 3), Shape(4, 5, 6)))
 | 
						|
```
 | 
						|
You can use method `toSingle()` to cast a `Shape` to a `SingleShape`. Similarly, use `toMulti()` to cast a `Shape` to a `MultiShape`.
 | 
						|
 | 
						|
---
 | 
						|
## 4. Define a model
 | 
						|
You can define a model either using [Sequential API](#sequential-api) or [Functional API](#functional-api). Remember to specify the input shape for the first layer.
 | 
						|
 | 
						|
After creating a model, you can call the following __methods__:
 | 
						|
 | 
						|
```scala
 | 
						|
getInputShape()
 | 
						|
```
 | 
						|
```scala
 | 
						|
getOutputShape()
 | 
						|
```
 | 
						|
* Return the input or output shape of a model, which is a [`Shape`](#2-shape) object. For `SingleShape`, the first entry is `-1` representing the batch dimension. For a model with multiple inputs or outputs, it will return a `MultiShape`.
 | 
						|
 | 
						|
```scala
 | 
						|
setName(name)
 | 
						|
```
 | 
						|
* Set the name of the model.
 | 
						|
 | 
						|
---
 | 
						|
## 5. Sequential API
 | 
						|
The model is described as a linear stack of layers in the Sequential API. Layers can be added into the `Sequential` container one by one and the order of the layers in the model will be the same as the insertion order.
 | 
						|
 | 
						|
To create a sequential container:
 | 
						|
```scala
 | 
						|
Sequential()
 | 
						|
```
 | 
						|
 | 
						|
Example code to create a sequential model:
 | 
						|
```scala
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.layers.{Dense, Activation}
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.models.Sequential
 | 
						|
import com.intel.analytics.bigdl.dllib.utils.Shape
 | 
						|
 | 
						|
val model = Sequential[Float]()
 | 
						|
model.add(Dense[Float](32, inputShape = Shape(128)))
 | 
						|
model.add(Activation[Float]("relu"))
 | 
						|
```
 | 
						|
 | 
						|
---
 | 
						|
## 6. Functional API
 | 
						|
The model is described as a graph in the Functional API. It is more convenient than the Sequential API when defining some complex model (for example, a model with multiple outputs).
 | 
						|
 | 
						|
To create an input node:
 | 
						|
```scala
 | 
						|
Input(inputShape = null, name = null)
 | 
						|
```
 | 
						|
Parameters:
 | 
						|
 | 
						|
* `inputShape`: A [`Shape`](#shape) object indicating the shape of the input node, not including batch.
 | 
						|
* `name`: String to set the name of the input node. If not specified, its name will by default to be a generated string.
 | 
						|
 | 
						|
To create a graph container:
 | 
						|
```scala
 | 
						|
Model(input, output)
 | 
						|
```
 | 
						|
Parameters:
 | 
						|
 | 
						|
* `input`: An input node or an array of input nodes.
 | 
						|
* `output`: An output node or an array of output nodes.
 | 
						|
 | 
						|
To merge a list of input __nodes__ (__NOT__ layers), following some merge mode in the Functional API:
 | 
						|
```scala
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.layers.Merge.merge
 | 
						|
 | 
						|
merge(inputs, mode = "sum", concatAxis = -1) // This will return an output NODE.
 | 
						|
```
 | 
						|
 | 
						|
Parameters:
 | 
						|
 | 
						|
* `inputs`: A list of node instances. Must be more than one node.
 | 
						|
* `mode`: Merge mode. String, must be one of: 'sum', 'mul', 'concat', 'ave', 'cos', 'dot', 'max'. Default is 'sum'.
 | 
						|
* `concatAxis`: Int, axis to use when concatenating nodes. Only specify this when merge mode is 'concat'. Default is -1, meaning the last axis of the input.
 | 
						|
 | 
						|
Example code to create a graph model:
 | 
						|
```scala
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.layers.{Dense, Input}
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.layers.Merge.merge
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.models.Model
 | 
						|
import com.intel.analytics.bigdl.dllib.utils.Shape
 | 
						|
 | 
						|
// instantiate input nodes
 | 
						|
val input1 = Input[Float](inputShape = Shape(8))
 | 
						|
val input2 = Input[Float](inputShape = Shape(6))
 | 
						|
// call inputs() with an input node and get an output node
 | 
						|
val dense1 = Dense[Float](10).inputs(input1)
 | 
						|
val dense2 = Dense[Float](10).inputs(input2)
 | 
						|
// merge two nodes following some merge mode
 | 
						|
val output = merge(inputs = List(dense1, dense2), mode = "sum")
 | 
						|
// create a graph container
 | 
						|
val model = Model[Float](Array(input1, input2), output)
 | 
						|
```
 | 
						|
 | 
						|
## 7. Persistence
 | 
						|
This section describes how to save and load the Keras-like API.
 | 
						|
 | 
						|
### 7.1 save
 | 
						|
To save a Keras model, you call the method `saveModel(path)`.
 | 
						|
 | 
						|
**Scala:**
 | 
						|
```scala
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.layers.{Dense, Activation}
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.models.Sequential
 | 
						|
 | 
						|
val model = Sequential[Float]()
 | 
						|
model.add(Dense[Float](32, inputShape = Shape(128)))
 | 
						|
model.add(Activation[Float]("relu"))
 | 
						|
model.saveModel("/tmp/seq.model")
 | 
						|
```
 | 
						|
**Python:**
 | 
						|
```python
 | 
						|
import bigdl.dllib.keras.Sequential
 | 
						|
from bigdl.dllib.keras.layer import Dense
 | 
						|
 | 
						|
model = Sequential()
 | 
						|
model.add(Dense(input_shape=(32, )))
 | 
						|
model.saveModel("/tmp/seq.model")
 | 
						|
```
 | 
						|
 | 
						|
### 7.2 load
 | 
						|
To load a saved Keras model, you call the method `load_model(path)`.
 | 
						|
 | 
						|
**Scala:**
 | 
						|
```scala
 | 
						|
import com.intel.analytics.bigdl.dllib.keras.Models
 | 
						|
 | 
						|
val model = Models.loadModel[Float]("/tmp/seq.model")
 | 
						|
```
 | 
						|
 | 
						|
**Python:**
 | 
						|
```python
 | 
						|
from bigdl.dllib.keras.models
 | 
						|
model = load_model("/tmp/seq.model")
 | 
						|
```
 |