Switched from LibSVM to ThunderSVM for better performance.
This commit is contained in:
parent
ac95537694
commit
e854036e56
10 changed files with 708 additions and 61 deletions
|
|
@ -152,6 +152,7 @@ public class OpenSeeExpression : MonoBehaviour
|
|||
private string[] classLabels = null;
|
||||
private int[] indices = null;
|
||||
private PointSelection pointSelection;
|
||||
private bool thunderSVM = false;
|
||||
//private bool newModel = false;
|
||||
|
||||
static public void LoadSerialized(byte[] modelBytes, out Dictionary<string, List<float[]>> expressions, out SVMModel model, out string[] classLabels, out int[] indices, ref PointSelection pointSelection) {
|
||||
|
|
@ -163,7 +164,10 @@ public class OpenSeeExpression : MonoBehaviour
|
|||
oser = formatter.Deserialize(gzipStream) as OpenSeeExpressionRepresentation;
|
||||
}
|
||||
expressions = oser.expressions;
|
||||
model = new SVMModel(oser.modelBytes);
|
||||
if (oser.thunderSVM)
|
||||
model = new ThunderSVMModel(oser.modelBytes);
|
||||
else
|
||||
model = new SVMModel(oser.modelBytes);
|
||||
classLabels = oser.classLabels;
|
||||
indices = oser.indices;
|
||||
//pointSelection = oser.pointSelection;
|
||||
|
|
@ -185,6 +189,7 @@ public class OpenSeeExpression : MonoBehaviour
|
|||
oser.classLabels = classLabels;
|
||||
oser.indices = indices;
|
||||
oser.pointSelection = pointSelection;
|
||||
oser.thunderSVM = true;
|
||||
//oser.newModel = true;
|
||||
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
|
|
@ -357,7 +362,7 @@ public class OpenSeeExpression : MonoBehaviour
|
|||
}
|
||||
ResetInfo();
|
||||
expressions = new Dictionary<string, List<float[]>>();
|
||||
model = new SVMModel();
|
||||
model = new ThunderSVMModel();
|
||||
rnd = new System.Random();
|
||||
}
|
||||
|
||||
|
|
@ -411,7 +416,8 @@ public class OpenSeeExpression : MonoBehaviour
|
|||
return false;
|
||||
}
|
||||
modelReady = false;
|
||||
//model = new SVMModel();
|
||||
if (model is SVMModel)
|
||||
model = new ThunderSVMModel();
|
||||
SelectPoints();
|
||||
List<string> keys = new List<string>();
|
||||
List<string> accuracyWarnings = new List<string>();
|
||||
|
|
|
|||
|
|
@ -6,34 +6,61 @@ using System.Runtime.InteropServices;
|
|||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OpenSee {
|
||||
|
||||
public class SVMModel {
|
||||
#region DllImport
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern System.IntPtr trainModel(float[] features, float[] labels, float[] weights, int rows, int cols, int classes, int probability, float C);
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, EntryPoint = "trainModel")]
|
||||
private static extern System.IntPtr trainModelDll(float[] features, float[] labels, float[] weights, int rows, int cols, int classes, int probability, float C);
|
||||
protected virtual System.IntPtr trainModel(float[] features, float[] labels, float[] weights, int rows, int cols, int classes, int probability, float C) {
|
||||
Debug.Log("Training LibSVM");
|
||||
return trainModelDll(features, labels, weights, rows, cols, classes, probability, C);
|
||||
}
|
||||
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void predict(System.IntPtr model, float[] features, [Out] float[] predictions, [Out] double[] probabilities, int rows);
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, EntryPoint = "predict")]
|
||||
private static extern void predictDll(System.IntPtr model, float[] features, [Out] float[] predictions, [Out] double[] probabilities, int rows);
|
||||
protected virtual void predict(System.IntPtr model, float[] features, [Out] float[] predictions, [Out] double[] probabilities, int rows) {
|
||||
predictDll(model, features, predictions, probabilities, rows);
|
||||
}
|
||||
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
private static extern System.IntPtr loadModel([MarshalAs(UnmanagedType.LPStr)]string filename, int cols, int classes, double[] means, double[] sdevs);
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "loadModel")]
|
||||
private static extern System.IntPtr loadModelDll([MarshalAs(UnmanagedType.LPStr)]string filename, int cols, int classes, double[] means, double[] sdevs);
|
||||
protected virtual System.IntPtr loadModel([MarshalAs(UnmanagedType.LPStr)]string filename, int cols, int classes, double[] means, double[] sdevs) {
|
||||
return loadModelDll(filename, cols, classes, means, sdevs);
|
||||
}
|
||||
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
private static extern System.IntPtr loadModelString([MarshalAs(UnmanagedType.LPStr)]string modelString, int cols, int classes, double[] means, double[] sdevs);
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "loadModelString")]
|
||||
private static extern System.IntPtr loadModelStringDll([MarshalAs(UnmanagedType.LPStr)]string modelString, int cols, int classes, double[] means, double[] sdevs);
|
||||
protected virtual System.IntPtr loadModelString([MarshalAs(UnmanagedType.LPStr)]string modelString, int cols, int classes, double[] means, double[] sdevs) {
|
||||
Debug.Log("Loading LibSVM");
|
||||
return loadModelStringDll(modelString, cols, classes, means, sdevs);
|
||||
}
|
||||
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void getScales(System.IntPtr model, [Out] double[] means, [Out] double[] sdevs);
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, EntryPoint = "getScales")]
|
||||
private static extern void getScalesDll(System.IntPtr model, [Out] double[] means, [Out] double[] sdevs);
|
||||
protected virtual void getScales(System.IntPtr model, [Out] double[] means, [Out] double[] sdevs) {
|
||||
getScalesDll(model, means, sdevs);
|
||||
}
|
||||
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
private static extern int saveModel(System.IntPtr model, [MarshalAs(UnmanagedType.LPStr)]string filename);
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "saveModel")]
|
||||
private static extern int saveModelDll(System.IntPtr model, [MarshalAs(UnmanagedType.LPStr)]string filename);
|
||||
protected virtual int saveModel(System.IntPtr model, [MarshalAs(UnmanagedType.LPStr)]string filename) {
|
||||
return saveModelDll(model, filename);
|
||||
}
|
||||
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
private static extern string saveModelString(System.IntPtr model);
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "saveModelString")]
|
||||
private static extern string saveModelStringDll(System.IntPtr model);
|
||||
protected virtual string saveModelString(System.IntPtr model) {
|
||||
return saveModelStringDll(model);
|
||||
}
|
||||
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void destroyModel(System.IntPtr model);
|
||||
[DllImport("SVMModel", CallingConvention = CallingConvention.Cdecl, EntryPoint = "destroyModel")]
|
||||
private static extern void destroyModelDll(System.IntPtr model);
|
||||
protected virtual void destroyModel(System.IntPtr model) {
|
||||
destroyModelDll(model);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private bool haveModel = false;
|
||||
|
|
@ -43,51 +70,51 @@ public class SVMModel {
|
|||
|
||||
[Serializable]
|
||||
private class SVMModelRepresentation {
|
||||
private string modelString;
|
||||
private int cols;
|
||||
private int maxClasses;
|
||||
private double[] means;
|
||||
private double[] sdevs;
|
||||
public string modelString;
|
||||
public int cols;
|
||||
public int maxClasses;
|
||||
public double[] means;
|
||||
public double[] sdevs;
|
||||
}
|
||||
|
||||
static public System.IntPtr LoadSerialized(byte[] modelBytes, out int cols, out int maxClasses, bool compress) {
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
MemoryStream memoryStream = new MemoryStream(modelBytes);
|
||||
memoryStream.Position = 0;
|
||||
SVMModelRepresentation smr;
|
||||
if (compress) {
|
||||
using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) {
|
||||
smr = formatter.Deserialize(gzipStream) as SVMModelRepresentation;
|
||||
}
|
||||
} else {
|
||||
smr = formatter.Deserialize(memoryStream) as SVMModelRepresentation;
|
||||
public System.IntPtr LoadSerialized(byte[] modelBytes, out int cols, out int maxClasses, bool compress) {
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
MemoryStream memoryStream = new MemoryStream(modelBytes);
|
||||
memoryStream.Position = 0;
|
||||
SVMModelRepresentation smr;
|
||||
if (compress) {
|
||||
using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) {
|
||||
smr = formatter.Deserialize(gzipStream) as SVMModelRepresentation;
|
||||
}
|
||||
cols = smr.cols;
|
||||
maxClasses = smr.maxClasses;
|
||||
System.IntPtr model = loadModelString(smr.modelString, smr.cols, smr.maxClasses, smr.means, smr.sdevs);
|
||||
return model;
|
||||
} else {
|
||||
smr = formatter.Deserialize(memoryStream) as SVMModelRepresentation;
|
||||
}
|
||||
cols = smr.cols;
|
||||
maxClasses = smr.maxClasses;
|
||||
System.IntPtr model = loadModelString(smr.modelString, smr.cols, smr.maxClasses, smr.means, smr.sdevs);
|
||||
return model;
|
||||
}
|
||||
|
||||
static public byte[] ToSerialized(System.IntPtr model, int cols, int maxClasses, bool compress) {
|
||||
SVMModelRepresentation smr = new SVMModelRepresentation();
|
||||
smr.cols = cols;
|
||||
smr.maxClasses = maxClasses;
|
||||
smr.means = new double[cols];
|
||||
smr.sdevs = new double[cols];
|
||||
getScales(model, smr.means, smr.sdevs);
|
||||
smr.modelString = saveModelString(model);
|
||||
public byte[] ToSerialized(System.IntPtr model, int cols, int maxClasses, bool compress) {
|
||||
SVMModelRepresentation smr = new SVMModelRepresentation();
|
||||
smr.cols = cols;
|
||||
smr.maxClasses = maxClasses;
|
||||
smr.means = new double[cols];
|
||||
smr.sdevs = new double[cols];
|
||||
getScales(model, smr.means, smr.sdevs);
|
||||
smr.modelString = saveModelString(model);
|
||||
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
if (compress) {
|
||||
using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Compress)) {
|
||||
formatter.Serialize(gzipStream, smr);
|
||||
gzipStream.Flush();
|
||||
}
|
||||
} else {
|
||||
formatter.Serialize(memoryStream, smr);
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
if (compress) {
|
||||
using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Compress)) {
|
||||
formatter.Serialize(gzipStream, smr);
|
||||
gzipStream.Flush();
|
||||
}
|
||||
return memoryStream.ToArray();
|
||||
} else {
|
||||
formatter.Serialize(memoryStream, smr);
|
||||
}
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
|
||||
public void DestroyModel() {
|
||||
|
|
@ -99,7 +126,7 @@ public class SVMModel {
|
|||
|
||||
private void LoadModel(byte[] modelBytes, bool compress) {
|
||||
DestroyModel();
|
||||
model = SVMModelRepresentation.LoadSerialized(modelBytes, out cols, out maxClasses, compress);
|
||||
model = LoadSerialized(modelBytes, out cols, out maxClasses, compress);
|
||||
haveModel = true;
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +137,7 @@ public class SVMModel {
|
|||
private byte[] SaveModel(bool compress) {
|
||||
if (!haveModel)
|
||||
return null;
|
||||
return SVMModelRepresentation.ToSerialized(model, cols, maxClasses, compress);
|
||||
return ToSerialized(model, cols, maxClasses, compress);
|
||||
}
|
||||
|
||||
public byte[] SaveModel() {
|
||||
|
|
@ -143,7 +170,9 @@ public class SVMModel {
|
|||
|
||||
maxClasses = max + 1;
|
||||
this.cols = cols;
|
||||
float start = Time.realtimeSinceStartup;
|
||||
model = trainModel(features, labels, weights, rows, cols, maxClasses, probability, C);
|
||||
Debug.Log("Training took: " + (Time.realtimeSinceStartup - start).ToString());
|
||||
haveModel = true;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
71
Unity/Plugins/ThunderSVMModel.cs
Normal file
71
Unity/Plugins/ThunderSVMModel.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using OpenSee;
|
||||
using UnityEngine;
|
||||
|
||||
public class ThunderSVMModel : SVMModel {
|
||||
#region DllImport
|
||||
[DllImport("ThunderSVMWrapper", CallingConvention = CallingConvention.Cdecl, EntryPoint = "trainModel")]
|
||||
private static extern System.IntPtr trainModelDll(float[] features, float[] labels, float[] weights, int rows, int cols, int classes, int probability, float C);
|
||||
protected override System.IntPtr trainModel(float[] features, float[] labels, float[] weights, int rows, int cols, int classes, int probability, float C) {
|
||||
Debug.Log("Training ThunderSVM");
|
||||
return trainModelDll(features, labels, weights, rows, cols, classes, probability, C);
|
||||
}
|
||||
|
||||
[DllImport("ThunderSVMWrapper", CallingConvention = CallingConvention.Cdecl, EntryPoint = "predict")]
|
||||
private static extern void predictDll(System.IntPtr model, float[] features, [Out] float[] predictions, [Out] double[] probabilities, int rows);
|
||||
protected override void predict(System.IntPtr model, float[] features, [Out] float[] predictions, [Out] double[] probabilities, int rows) {
|
||||
predictDll(model, features, predictions, probabilities, rows);
|
||||
}
|
||||
|
||||
[DllImport("ThunderSVMWrapper", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "loadModel")]
|
||||
private static extern System.IntPtr loadModelDll([MarshalAs(UnmanagedType.LPStr)]string filename, int cols, int classes, double[] means, double[] sdevs);
|
||||
protected override System.IntPtr loadModel([MarshalAs(UnmanagedType.LPStr)]string filename, int cols, int classes, double[] means, double[] sdevs) {
|
||||
return loadModelDll(filename, cols, classes, means, sdevs);
|
||||
}
|
||||
|
||||
[DllImport("ThunderSVMWrapper", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "loadModelString")]
|
||||
private static extern System.IntPtr loadModelStringDll([MarshalAs(UnmanagedType.LPStr)]string modelString, int cols, int classes, double[] means, double[] sdevs);
|
||||
protected override System.IntPtr loadModelString([MarshalAs(UnmanagedType.LPStr)]string modelString, int cols, int classes, double[] means, double[] sdevs) {
|
||||
Debug.Log("Loading ThunderSVM");
|
||||
return loadModelStringDll(modelString, cols, classes, means, sdevs);
|
||||
}
|
||||
|
||||
[DllImport("ThunderSVMWrapper", CallingConvention = CallingConvention.Cdecl, EntryPoint = "getScales")]
|
||||
private static extern void getScalesDll(System.IntPtr model, [Out] double[] means, [Out] double[] sdevs);
|
||||
protected override void getScales(System.IntPtr model, [Out] double[] means, [Out] double[] sdevs) {
|
||||
getScalesDll(model, means, sdevs);
|
||||
}
|
||||
|
||||
[DllImport("ThunderSVMWrapper", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "saveModel")]
|
||||
private static extern int saveModelDll(System.IntPtr model, [MarshalAs(UnmanagedType.LPStr)]string filename);
|
||||
protected override int saveModel(System.IntPtr model, [MarshalAs(UnmanagedType.LPStr)]string filename) {
|
||||
return saveModelDll(model, filename);
|
||||
}
|
||||
|
||||
[DllImport("ThunderSVMWrapper", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "saveModelString")]
|
||||
private static extern string saveModelStringDll(System.IntPtr model);
|
||||
protected override string saveModelString(System.IntPtr model) {
|
||||
return saveModelStringDll(model);
|
||||
}
|
||||
|
||||
[DllImport("ThunderSVMWrapper", CallingConvention = CallingConvention.Cdecl, EntryPoint = "destroyModel")]
|
||||
private static extern void destroyModelDll(System.IntPtr model);
|
||||
protected override void destroyModel(System.IntPtr model) {
|
||||
destroyModelDll(model);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ThunderSVMModel() {
|
||||
}
|
||||
|
||||
public ThunderSVMModel(byte[] modelBytes) {
|
||||
LoadModel(modelBytes);
|
||||
}
|
||||
}
|
||||
BIN
Unity/Plugins/ThunderSVMWrapper.dll
Normal file
BIN
Unity/Plugins/ThunderSVMWrapper.dll
Normal file
Binary file not shown.
63
Unity/Plugins/ThunderSVMWrapper.dll.meta
Normal file
63
Unity/Plugins/ThunderSVMWrapper.dll.meta
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9c58dd9d1f0cf3140bd004d536712abb
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Editor: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 0
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Unity/Plugins/thundersvm.dll
Normal file
BIN
Unity/Plugins/thundersvm.dll
Normal file
Binary file not shown.
63
Unity/Plugins/thundersvm.dll.meta
Normal file
63
Unity/Plugins/thundersvm.dll.meta
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e549e6cbc6a547748abc7f1b05bfa7b4
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Editor: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 0
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Add table
Add a link
Reference in a new issue