Skip to content

Commit

Permalink
support multi input models for nnframes (intel-analytics#1553)
Browse files Browse the repository at this point in the history
* support multi input for nnframes

* update ut

* add doc and unit test

* doc update

* scala style
  • Loading branch information
hhbyyh committed Aug 20, 2019
1 parent 0e4a243 commit 746be93
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,32 @@ object NNClassifier {
FeatureLabelPreprocessing(SeqToTensor(featureSize), ScalarToTensor()))
}


/**
* Construct a [[NNClassifier]] with multiple input sizes. The constructor is useful
* when the feature column and label column contains the following data types:
* Float, Double, Int, Array[Float], Array[Double], Array[Int] and MLlib Vector. The feature
* data are converted to Tensors with the specified sizes before sending to the model.
*
* This API is used for multi-input model, where user need to specify the tensor sizes for
* each of the model input.
*
* @param model module to be optimized
* @param criterion criterion method
* @param featureSize The sizes (Tensor dimensions) of the feature data.
*/
def apply[T: ClassTag](
model: Module[T],
criterion: Criterion[T],
featureSize : Array[Array[Int]]
)(implicit ev: TensorNumeric[T]): NNClassifier[T] = {
new NNClassifier(model, criterion)
.setSamplePreprocessing(FeatureLabelPreprocessing(
SeqToMultipleTensors(featureSize), ScalarToTensor()
)
)
}

/**
* Construct a [[NNClassifier]] with a feature Preprocessing.
*
Expand Down Expand Up @@ -216,6 +242,26 @@ object NNClassifierModel extends MLReadable[NNClassifierModel[_]] {
.setSamplePreprocessing(SeqToTensor(featureSize) -> TensorToSample())
}

/**
* Construct a [[NNClassifierModel]] with sizes of multiple model inputs. The constructor is
* useful when the feature column contains the following data types:
* Float, Double, Int, Array[Float], Array[Double], Array[Int] and MLlib Vector. The feature
* data are converted to Tensors with the specified sizes before sending to the model.
*
* This API is used for multi-input model, where user need to specify the tensor sizes for
* each of the model input.
*
* @param model model to be used, which should be a multi-input model.
* @param featureSize The sizes (Tensor dimensions) of the feature data.
*/
def apply[T: ClassTag](
model: Module[T],
featureSize : Array[Array[Int]]
)(implicit ev: TensorNumeric[T]): NNClassifierModel[T] = {
new NNClassifierModel(model)
.setSamplePreprocessing(SeqToMultipleTensors(featureSize) -> MultiTensorsToSample())
}

/**
* Construct a [[NNClassifierModel]] with a feature Preprocessing.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,35 @@ object NNEstimator {
)
}

/**
* Construct a [[NNEstimator]] with a feature size and label size. The constructor is useful
* when the feature column and label column contains the following data types:
* Float, Double, Int, Array[Float], Array[Double], Array[Int] and MLlib Vector. The feature and
* label data are converted to Tensors with the specified sizes before sending to the model.
*
* This API is used for multi-input model, where user need to specify the tensor sizes for
* each of the model input.
*
* @param model BigDL module to be optimized
* @param criterion BigDL criterion method
* @param featureSize The sizes (Tensor dimensions) of the feature data. e.g. an image may be with
* width * height = 28 * 28, featureSize = Array(28, 28).
* @param labelSize The size (Tensor dimensions) of the label data.
*/
def apply[T: ClassTag](
model: Module[T],
criterion: Criterion[T],
featureSize : Array[Array[Int]],
labelSize : Array[Int]
)(implicit ev: TensorNumeric[T]): NNEstimator[T] = {
new NNEstimator(model, criterion)
.setSamplePreprocessing(FeatureLabelPreprocessing(
SeqToMultipleTensors(featureSize),
SeqToTensor(labelSize)
)
)
}

/**
* Construct a [[NNEstimator]] with a feature Preprocessing and label Preprocessing.
*
Expand Down Expand Up @@ -702,6 +731,27 @@ object NNModel extends MLReadable[NNModel[_]] {
.setSamplePreprocessing(SeqToTensor(featureSize) -> TensorToSample())
}


/**
* Construct a [[NNModel]] with sizes of multiple model inputs. The constructor is useful
* when the feature column contains the following data types:
* Float, Double, Int, Array[Float], Array[Double], Array[Int] and MLlib Vector. The feature
* data are converted to Tensors with the specified sizes before sending to the model.
*
* This API is used for multi-input model, where user need to specify the tensor sizes for
* each of the model input.
*
* @param model model to be used, which should be a multi-input model.
* @param featureSize The sizes (Tensor dimensions) of the feature data.
*/
def apply[T: ClassTag](
model: Module[T],
featureSize : Array[Array[Int]]
)(implicit ev: TensorNumeric[T]): NNModel[T] = {
new NNModel(model)
.setSamplePreprocessing(SeqToMultipleTensors(featureSize) -> MultiTensorsToSample())
}

/**
* Construct a [[NNModel]] with a feature Preprocessing.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ class PythonNNFrames[T: ClassTag](implicit ev: TensorNumeric[T]) extends PythonZ
SeqToTensor(size.asScala.toArray)
}

def createSeqToMultipleTensors(size: JArrayList[JArrayList[Int]]): SeqToMultipleTensors[T] = {
SeqToMultipleTensors(size.asScala.map(x => x.asScala.toArray).toArray)
}

def createArrayToTensor(size: JArrayList[Int]): ArrayToTensor[T] = {
ArrayToTensor(size.asScala.toArray)
}
Expand All @@ -121,9 +125,9 @@ class PythonNNFrames[T: ClassTag](implicit ev: TensorNumeric[T]) extends PythonZ
def createFeatureLabelPreprocessing(
featureTransfomer: Preprocessing[Any, Tensor[T]],
labelTransformer: Preprocessing[Any, Tensor[T]]
): FeatureLabelPreprocessing[Any, Any, Sample[T]] = {
): FeatureLabelPreprocessing[Any, Any, Any, Sample[T]] = {
FeatureLabelPreprocessing(featureTransfomer, labelTransformer)
.asInstanceOf[FeatureLabelPreprocessing[Any, Any, Sample[T]]]
.asInstanceOf[FeatureLabelPreprocessing[Any, Any, Any, Sample[T]]]
}

def createChainedPreprocessing(list: JList[Preprocessing[Any, Any]]): Preprocessing[Any, Any] = {
Expand Down

0 comments on commit 746be93

Please sign in to comment.