Skip to content
lisahua edited this page Jul 31, 2014 · 14 revisions

Table of Content

Example of using Shifu-plugin-encog

Initialize Encog model and PMML model with stats and transformations.

protected void initModels() {
		pmml = PMMLUtils.loadPMML(initPmmlPath);
		mlModel = (BasicNetwork) new PersistBasicNetwork().read(new FileInputStream(mlModelPath));
}

Adapt Encog model to PMML model

protected void adaptModelToPMML() {
	NeuralNetwork pmmlNN = (NeuralNetwork) pmml.getModels().get(0);
	pmmlNN = new EncogNeuralNetworkToPMMLModel().adaptModelToPMML(mlModel,pmmlNN);
	pmml.getModels().set(0, pmmlNN);
}

Validate the score calculated by PMML evaluator with the score calculated by Encog

private void evaluate(EncogTestDataGenerator evalInput) {
	 for (Map<FieldName, String> map : evalInput.getEvaluatorInput()) {
		MLData data = evalInput.normalizeData(context);
		Assert.assertEquals(getPMMLEvaluatorResult(map),mlModel.compute(data).getData(0), DELTA);
}

Encog EG file format

       encog,BasicNetwork,java,3.1.0,1,1328887171549
       [BASIC]
       [BASIC:PARAMS]
       [BASIC:NETWORK]
       beginTraining=0
       endTraining=3
       hasContext=f
       inputCount=30
       layerCounts=1,46,31
       layerFeedCounts=1,45,30
       layerIndex=0,1,47
       output=0,0,0,0,0,0,0, ...
       outputCount=1
       weightIndex=0,46,1441
       weights=##0
       ##double#3511
       -0.661653975,-0.1598418241,-0.1579810695,0.184999618, ...
       -0.2078151175,-0.851479728,-0.3689467346,-0.4818813258, ...
       ...
       ##end
       biasActivation=0,1,1,1
       [BASIC:ACTIVATION]
       "ActivationSigmoid"
       "ActivationSigmoid"
       "ActivationSigmoid"
       "ActivationLinear"

By default, Encog models are stored in the format of EG file. Depending on different Encog neural network structure, some changes are needed to load the EG file using PersistBasicNetwork:

  • Remove the first line: e.g., encog,BasicNetwork,java,3.1.0,1,1328887171549
  • If there are more than 2048 weights in the neural network model, Encog will write it to multiple lines, we should append multiple lines of weights into one line and remove some fields: e.g. weights=##0 ##double#3511 ..##end should be changed to weights= -0.7086695506,....

Feedforward Structure

  • The neural layers in Encog NeuralNetwork class are listed in a reversed order.

PMML conversion

Convert from Encog NeuralNetwork model to PMML

       public class EncogNeuralNetworkToPMMLModel  implements ModelToPMMLBuilder<org.dmg.pmml.NeuralNetwork, org.encog.neural.networks.BasicNetwork> {
       	public org.dmg.pmml.NeuralNetwork adaptMLModelToPMML(org.encog.neural.networks.BasicNetwork bNetwork, org.dmg.pmml.NeuralNetwork pmmlModel) {
       		pmmlModel = new NeuralNetworkModelIntegrator().adaptPMMLStatsModel(pmmlModel);
       		double[] weights = network.getWeights();
       		for (int i = 0; i < numLayers - 1; i++) {
       			NeuralLayer layer = new NeuralLayer();
       			int layerID = numLayers - i - 1;
       			for (int j = 0; j < layerFeedCount[i]; j++) {
       				Neuron neuron = new Neuron(String.valueOf(layerID + "," + j));
       				neuron.setBias(0.0);// bias of each neuron, set to 0
       				for (int k = 0; k < layerFeedCount[i + 1]; k++) {
       					neuron.withConnections(new Connection(String.valueOf(layerID - 1 + "," + k),weights[weightID++]));
       				}// weights
       				neuron.withConnections(new Connection(biasValue,weights[weightID++]));
       			}// bias neuron for each layer
       			layer.withNeurons(neuron);
       			}// finish build Neuron
       			layerList.add(layer);
       		}// finish build layer
       		// reserve the layer list to fit fot PMML format
       		Collections.reverse(layerList);
       		pmmlModel.withNeuralLayers(layerList);
       		// set neural output based on target id
       		pmmlModel.withNeuralOutputs(PMMLAdapterCommonUtil.getOutputFields(pmmlModel.getMiningSchema(), numLayers - 1));
       		return pmmlModel;
       	}

Convert from PMML to Encog NeuralNetwork model

       public class EncogNeuralNetworkFromPMML implements PMMLToModel<BasicNetwork, NeuralNetwork> {
       	BasicNetwork mlModel = new BasicNetwork();
       	private NeuralNetwork pmmlModel;
       	private List<HashMap<String, Integer>> neuronMap = new ArrayList<HashMap<String, Integer>>();
       	@Override
       	public BasicNetwork createMLModelFromPMML(NeuralNetwork pmmlModel) {
       		this.pmmlModel = pmmlModel;
       		readNeuronInputLayer();
       		initNNLayer();
       		setWeight();
       		return mlModel;
       	}
  
       	private void initMLModelStructure() {
       		List<NeuralLayer> layerList = pmmlModel.getNeuralLayers();
       		for (NeuralLayer layer : layerList) {
       			mlModel.addLayer(new BasicLayer(transformActivationFunction(layer.getActivationFunction()), true, layer.getNeurons().size()));
       		}
       		mlModel.getStructure().finalizeStructure();
       	}
       
       	private void setModelWeight() {
       		List<NeuralLayer> layerList = pmmlModel.getNeuralLayers();
       		HashMap<String, Integer> prevNameLocMap;
       		int lenLayer = layerList.size();
       		// get each layer
       		for (int layerID = 0; layerID < lenLayer; layerID++) {
       			NeuralLayer layer = layerList.get(layerID);
       			prevNameLocMap = neuronMap.get(layerID);
       			// create new nameLocMap
       			HashMap<String, Integer> nameLocMap = new HashMap<String, Integer>();
       			int neuronNum = layer.getNeurons().size();
       			for (int nID = 0; nID < neuronNum; nID++) {
       				Neuron neuron = layer.getNeurons().get(nID);
       				// add to nameLocMap
       				nameLocMap.put(neuron.getId(), nID);
       				for (Connection con : neuron.getConnections()) {
       					mlModel.setWeight(layerID, prevNameLocMap.get(con.getFrom()), nID, con.getWeight());
       				}
       			}// end of each neuron
       			nameLocMap.put("bias", neuronNum);
       			neuronMap.add(nameLocMap);
       		}// end of a neural layer
       	}
       }
Clone this wiki locally