Встраивание Python в C ++: импорт модулей в сценарии Python работает во время одного вызова функции, но не другого

Я пишу программу, которая использует C ++ в качестве бэкэнда управления данными и может вызывать созданные пользователем скрипты Python для выполнения различных задач. Я сталкиваюсь с проблемой, хотя и связанной с импортом модулей в скрипте Python. Я передаю значения из C ++ в python и выполняю Гауссовскую регрессию процесса из sklearn для этих значений и просто возвращаю оптимизированные значения модели или неопределенности GPR обратно в C ++. У меня есть эти две ситуации (оптимизация модели и проверка модели) как две отдельные функции в скрипте Python, так как они будут вызываться из разных мест из C ++.

Когда я запускаю первую функцию (оптимизация модели), все отлично работает, и я получаю оптимизированные гиперпараметры, чтобы вернуться к C ++ без происшествий. Однако во время второго вызова функции сценарий завершается ошибкой, поскольку он не может импортировать модули GPR из sklearn (те же модули, которые успешно импортировала предыдущая функция). Я не слишком знаком со встраиванием python в C ++, поэтому вполне возможно, что я просто что-то упускаю или не до конца понимаю правила. Невозможно предоставить код со стороны C ++, который может быть запущен сам по себе, поэтому я сделаю все возможное, чтобы предоставить как можно больше встроенного кода. Сценарии Python ниже показаны полностью. Если вам нужна дополнительная информация, пожалуйста, дайте мне знать, я рад предоставить ее. Спасибо за любую помощь, которую вы можете оказать.

C ++: Main

//other stuff

Py_Initialize();

//do more other stuff (embedding happens here)

Py_Finalize();

//do even more other stuff

C ++: оптимизация модели

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");

pName = PyString_FromString(file.c_str());

pModule = PyImport_Import(pName);
Py_DECREF(pName);

if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, function.c_str());

pArgs = PyTuple_New(size);

PyTuple_SetItem(pArgs, 0, PyLong_FromLong(gp->getInnerFPSize()));
PyTuple_SetItem(pArgs, 1, PyLong_FromLong(ntrain));

k = 2;

for(i = 0; i < trainingFP[modelNumber].size(); i++){
for(j = 0; j < trainingFP[modelNumber][i].size(); j++){
PyTuple_SetItem(pArgs, k,
PyFloat_FromDouble(trainingFP[modelNumber][i][j]));
k++;
}
}
for(i = 0; i < trainingForces[modelNumber].size(); i++){
PyTuple_SetItem(pArgs, k,
PyFloat_FromDouble(trainingForces[modelNumber][i]));
k++;
}
Py_INCREF(pValue);
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);

}else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", function.c_str());
return 1;
}

Py_XDECREF(pFunc);
Py_DECREF(pModule);

optimalSigma = PyFloat_AsDouble(PyList_GetItem(pValue, 1));
optimalSigmaN = PyFloat_AsDouble(PyList_GetItem(pValue, 0));
optimalSigmaF = PyFloat_AsDouble(PyList_GetItem(pValue, 2));

Py_DECREF(pValue);

C ++: проверка модели

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");

pName = PyString_FromString(file.c_str());

pModule = PyImport_Import(pName);
Py_DECREF(pName);

if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, function.c_str());

pArgs = PyTuple_New(size);

PyTuple_SetItem(pArgs, 0, PyFloat_FromDouble(testFP[0].size()));
PyTuple_SetItem(pArgs, 1, PyFloat_FromDouble(testFP.size()));
PyTuple_SetItem(pArgs, 2, PyFloat_FromDouble(trainingFP.size()));
PyTuple_SetItem(pArgs, 3, PyFloat_FromDouble(sigma));
PyTuple_SetItem(pArgs, 4, PyFloat_FromDouble(sigmaN));
PyTuple_SetItem(pArgs, 5, PyFloat_FromDouble(sigmaF));

k = 6;

for(i = 0; i < testFP.size(); i++){
for(j = 0; j < testFP[i].size(); j++){
PyTuple_SetItem(pArgs, k, PyFloat_FromDouble(testFP[i][j]));
k++;
}
}
for(i = 0; i < trainingFP.size(); i++){
for(j = 0; j < trainingFP[i].size(); j++){
PyTuple_SetItem(pArgs, k, PyFloat_FromDouble(trainingFP[i][j]));
k++;
}
}
for(i = 0; i < trainingFP.size(); i++){
PyTuple_SetItem(pArgs, k, PyFloat_FromDouble(trainingForces[i]));
k++;
}
Py_INCREF(pValue);
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);

}else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", function.c_str());
}

Py_XDECREF(pFunc);
Py_DECREF(pModule);

for(i = 0; i < testFP.size(); i++)
prediction[i] = PyFloat_AsDouble(PyList_GetItem(pValue, i));

Py_DECREF(pValue);

питон

def GPR(*X):

from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel
import re

#initialize local variables
counter = 0
sigma_l_initial = 1
sigma_n_initial = 1
sigma_f_initial = 2
innerFPSize = int(X[0])
ntrain = int(X[1])

optimized_hyperparameters = []
forces = []
fp = []
sigma_l_bounds = [.01,100]
sigma_n_bounds = [.001,.1]

fp.append([])
#pass values from c++ conversion tuple to local lists
for x in X:
if counter > 1 and counter < 2 + innerFPSize * ntrain:
fp[len(fp) - 1].append(x)
elif counter >= 2 + innerFPSize * ntrain:
forces.append(x)

counter += 1

if len(fp[len(fp) -1]) == innerFPSize:
if len(fp) < ntrain:
fp.append([])

#GPR routine
krbf = sigma_f_initial*RBF(length_scale=sigma_l_initial,length_scale_bounds=(sigma_l_bounds[0],sigma_l_bounds[1]))
noise_kernel = WhiteKernel(noise_level=sigma_n_initial,noise_level_bounds=(sigma_n_bounds[0],sigma_n_bounds[1]))

gp = GaussianProcessRegressor(kernel=krbf + noise_kernel,normalize_y=True,n_restarts_optimizer=25)
gp.fit(fp, forces)

#get optimized hyperparameters
rr = re.findall("[-+]?[.]?[\d]+(?:,\d\d\d)*[\.]?\d*(?:[eE][-+]?\d+)?", str(gp.kernel_))
optimized_hyperparameters.append(float(rr[-1]))
optimized_hyperparameters.append(float(rr[-2]))
optimized_hyperparameters.append(float(rr[0]))

return optimized_hyperparameters
def GPR_unc(*X):

try:
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel
except:
print 'THIS REFUSES TO WORK'

#initialize variables
uncertainty = []
testFP = []
trainingFP = []
trainingForces = []

innerFPSize = int(X[0])
testSize = int(X[1])
ntrain = int(X[2])
sigma = float(X[3])
sigma_n = float(X[4])
sigma_f = float(X[5])

counter = 0

setTrainFP = setTrainForces = False
setTestFP = True

testFP.append([])
trainingFP.append([])

#parse data from C++ arrays
for x in X:

try:
if counter > 5 and setTestFP == True:
testFP[len(testFP) - 1].append(x)
elif setTrainFP == True:
trainingFP[len(trainingFP) - 1].append(x)
elif setTrainForces == True:
trainingForces.append(x)

if counter > 5 and setTestFP == True:
if len(testFP[len(testFP) -1]) == innerFPSize:
if len(testFP) + 1 <= testSize:
testFP.append([])
else:
setTestFP = False
setTrainFP = True
elif setTrainFP == True:
if len(trainingFP[len(trainingFP) -1]) == innerFPSize:
if(len(trainingFP)) + 1 <= ntrain:
trainingFP.append([])
else:
setTrainFP = False
setTrainForces = True
counter += 1
except:
print 'ERROR'

#perform static "optimization" of gpr kernel to get gpr object
krbf = sigma_f**2*RBF(length_scale=sigma,length_scale_bounds=(sigma,sigma))
noise_kernel = WhiteKernel(noise_level=sigma_n,noise_level_bounds=(sigma_n,sigma_n))
gp = GaussianProcessRegressor(kernel=krbf + noise_kernel,normalize_y=True, optimizer=None)
gp.fit(trainingFP, trainingForces)

#get uncertanties on test set
val,std=gp.predict(testFP,return_std=True)

#ensure that the uncertainty is loaded into a float list in order to be sent back to c++
for x in std:
uncertainty.append(float(x))
for x in std:
uncertainty.append(float(x) * float(x))

return uncertainty

Сценарий python завершается неудачно при попытке импортировать модули из функции GPR_unc (вторая функция из кода python).

2

Решение

Во время функции проверки модели кортеж Python:

pArgs = PyTuple_New(size);

был передан неправильный размер по сравнению с тем, что было добавлено к нему. Авария закончилась тем, что была простой «записью за конец массива без изменения его размера».

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]