Shifu Plugin Encog - ShifuML/shifu GitHub Wiki
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
EG file
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 ..##endshould be changed toweights= -0.7086695506,....
BasicNetwork EG file and Feedforward Structure

- The neural layers in Encog
NeuralNetworkclass 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
}
}