我需要在C ++构建目标系统中部署SVM。因此,我想使用dlib和python / numpy训练SVM,将其序列化并在目标系统中进行评估。
dlib的python文档对我来说相当模糊,所以任何人都可以帮我解决这个最小的例子吗?
import dlib
# My data in numpy
feature_column_1 = np.array([-1, -2, -3, 1, 2, 3])
feature_column_2 = np.array([1, 2, 3, -1, -2, -3])
labels = np.array([True, True, True, False, False, False])
# Features
feature_vectors = dlib.vectors()
for feature_column in [feature_column_1, feature_column_2]:
feature_vectors.append(dlib.vector(feature_column.tolist()))
# Labels
labels_array = dlib.array(labels.tolist())
# Train
svm = dlib.svm_c_trainer_linear()
svm.train(feature_vectors, labels_array)
# Test
y_probibilities = svm.predict(labels_array_new)
我收到了以下关于培训的错误:
---> 18 svm.train(vectors, array)
ValueError: Invalid inputs
答案 0 :(得分:3)
我刚刚为dlib添加了一个官方示例。当我看时,我很惊讶地发现它没有被包括在内。它可以在这里找到:https://github.com/davisking/dlib/blob/master/python_examples/svm_binary_classifier.py。以下是相关细节:
import dlib
import pickle
x = dlib.vectors()
y = dlib.array()
# Make a training dataset. Here we have just two training examples. Normally
# you would use a much larger training dataset, but for the purpose of example
# this is plenty. For binary classification, the y labels should all be either +1 or -1.
x.append(dlib.vector([1, 2, 3, -1, -2, -3]))
y.append(+1)
x.append(dlib.vector([-1, -2, -3, 1, 2, 3]))
y.append(-1)
# Now make a training object. This object is responsible for turning a
# training dataset into a prediction model. This one here is a SVM trainer
# that uses a linear kernel. If you wanted to use a RBF kernel or histogram
# intersection kernel you could change it to one of these lines:
# svm = dlib.svm_c_trainer_histogram_intersection()
# svm = dlib.svm_c_trainer_radial_basis()
svm = dlib.svm_c_trainer_linear()
svm.be_verbose()
svm.set_c(10)
# Now train the model. The return value is the trained model capable of making predictions.
classifier = svm.train(x, y)
# Now run the model on our data and look at the results.
print("prediction for first sample: {}".format(classifier(x[0])))
print("prediction for second sample: {}".format(classifier(x[1])))
# classifier models can also be pickled in the same was as any other python object.
with open('saved_model.pickle', 'wb') as handle:
pickle.dump(classifier, handle)
但是,如果你想使用C ++,你应该只使用C ++。 Dlib主要是一个C ++库而不是python库。 dlib的重点是为想要进行机器学习的人提供一个很好的C ++ API。所以你最好只使用C ++进行培训。 dlib和完整的C ++ API文档附带了99个完整的C ++示例。例如,这是一个相关示例http://dlib.net/svm_c_ex.cpp.html。
我真的应该强调dlib的C ++ API比python API更灵活。实际上,dlib的目的是在C ++中简化机器学习,dlib的python API是事后的想法。实际上,dlib的许多功能都是用C ++模板表达的,这些模板在Python中没有可能的相关性(例如,因为python没有像C ++模板那样),因此这些功能不会暴露给python。所以,如果你想使用C ++,那么使用C ++。 如果您知道如何编写C ++ ,则没有理由使用Python API。
答案 1 :(得分:2)
不是一个完整的答案,而是一些评论:
您观察到的错误至少部分是由于支票here。
for (long r = 0; r < x_labels.nr(); ++r)
{
if (x_labels(r) != -1 && x_labels(r) != 1)
return false;
表示: labels = np.array([True, True, True, False, False, False])
错误,而labels = np.array([1, 1, 1, -1, -1, -1])
是正确的。
通常,在大多数MLlib中,数据格式为(n_samples,n_features),其中行是观察值。
打印出你的特征向量时,这看起来是正确的,但你的代码,在更改(1)之后仍然会抛出相同的错误,除非你把它当作另一种方式处理:所以另一个解释是:你有2个样本,每个6个特征。使用这个假设,y需要有2个值。 Etvoilà......至少是训练!
import dlib
import numpy as np
# My data in numpy
feature_column_1 = np.array([-1, -2, -3, 1, 2, 3])
feature_column_2 = np.array([1, 2, 3, -1, -2, -3])
labels = np.array([-1, 1]) # +1/-1 & size == 2
# Features
feature_vectors = dlib.vectors()
for feature_column in [feature_column_1, feature_column_2]:
feature_vectors.append(dlib.vector(feature_column.tolist()))
# Labels
labels_array = dlib.array(labels.tolist())
# Train
svm = dlib.svm_c_trainer_linear()
svm.be_verbose = 10
svm.train(feature_vectors, labels_array)
print('k')
dlib的python-API没有predict()
函数。 C ++ - API有一些用于预测的learned_function属性,但this和this表示你必须自己做(可能使用c_class1
和co。因为我无法映射其他任何可用于API-doc候选人的东西。)
编辑:我错误的预测,正如dlib的维护者/开发人员在评论中提到的那样!
我真的不喜欢这个状态,会用别的东西! (或改进dlib)。
不确定如何解释您的环境限制,但是:
答案 2 :(得分:0)
当我将for循环更改为此时(我没有dlib):
for feature_column in [feature_column_1, feature_column_2]:
print(feature_column.tolist())
我得到了这个结果
[-1, -2, -3, 1, 2, 3]
[1, 2, 3, -1, -2, -3]
我认为您的数据应如下所示:
[-1, 1]
[-2, 2]
[-2, 2]
[1, -1]
[2, -2]
[3, -3]
使用这段代码可以得到什么:
features = [[-1,1],[-2,2],[-2,2],[1,-1],[2,-2],[3,-3]]
for feature in features:
feature_vectors.append(dlib.vector(feature_column.tolist()))