OpenMDAO에서 Kriging 응답 곡면

Kriging 응답 곡면



이론적으로는 잘 이해되지는 않았지만 흩어져있는 샘플 포인트에서 곡면을 추정하는 방법입니다.
OpenMDAO에서 라틴 초방격 샘플링에 제시된 라틴어 초방격 샘플링과 궁합이 좋기 때문에 (산소한 샘플링), 공학적으로 CAE를 사용하여 응답 곡면을 추정 할 때 종종 사용됩니다.

OpenMDAO에서 포물면의 Kriging 응답 곡면



이니셔티브의 개요는 다음과 같습니다. 먼저 OpenMDAO에서 라틴 초방격 샘플링에서 실험 한 데이터 (doe_paraboloid 파일)를 읽습니다.
그런 다음로드 된 실험 데이터를 사용하여 Kriging 근사 모델을 단련하고 생성합니다.
마지막으로, 생성 된 Kriging 근사 모델에 의한 보간 값을 이론 해 (와이어 프레임) 플롯하여 모델의 유효성을 확인합니다. 다음 방정식은 이론 해입니다.
\begin{align}
& f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 \\
    {\rm subject \: to} \: \: \:&  -50.0\leq x \leq 50.0 \\
                                &  -50.0\leq y \leq 50.0
\end{align}

그룹 준비



아래 training_mm.py 파일 준비

training_mm.py
from __future__ import print_function
from openmdao.api import Group,  MetaModel,  FloatKrigingSurrogate

class TrainingMM(Group):
    ''' FloatKriging gives responses as floats '''

    def __init__(self):
        super(TrainingMM, self).__init__()

        # Create meta_model for f_x as the response
        mm = self.add("parabo_mm", MetaModel())
        mm.add_param('x', val=0.)
        mm.add_param('y', val=0.)
        mm.add_output('f_xy', val=0., surrogate=FloatKrigingSurrogate())

MetaModel이라는 근사 모델을 훈련하고 값을 평가하는 Component를 추가했습니다.
f_xy를 근사하기 위해 FloatKrigingSurrogate라는 SurrogateModel을 설정합니다.
FloatKrigingSurrogate 단체도 근사 모델의 훈련과 값을 평가하는 기능을 가지고 있지만,
MetaModel을 사용하면 여러 근사 모델을 동시에 훈련 할 수 있다고 공식 문서에 기록되어 있습니다.

Problem(문제) 설정



다음은 kriging_paraboloid.py를 준비합니다. 전반부는 실험 데이터를 읽고 Kriging 근사 모델을 훈련시키는 과정입니다.

kriging_paraboloid.py
#! /bin/python
import pickle
import numpy as np
import sqlitedict
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from openmdao.api import Problem
from training_mm import TrainingMM

db =sqlitedict.SqliteDict("doe_paraboloid","iterations")
res = np.array([[0.,0.,0.]] * len(db.items()))
for i, v in enumerate(db.items()):
    res[i,0] = v[1]["Unknowns"]["x"]
    res[i,1] = v[1]["Unknowns"]["y"]
    res[i,2] = v[1]["Unknowns"]["f_xy"]

prob = Problem()
prob.root = TrainingMM()
prob.setup()
prob["parabo_mm.train:x"] = res[:,0]
prob["parabo_mm.train:y"] = res[:,1]
prob["parabo_mm.train:f_xy"] = res[:,2]
prob.run()


후반부는 아래에 나와 있습니다. 작성한 kriging 근사 모델과 이론해의 비교를 플롯으로 실시하고 있다

kriging_paraboloid.py 계속
x = np.arange(-50., 50., 4.)
y = np.arange(-50., 50., 4.)

sg = prob.root.parabo_mm._init_unknowns_dict["f_xy"]["surrogate"]
f = open("./kriging_parabo","w")
pickle.dump(sg, f)
f.close()
f = open("./kriging_parabo_mm","w")
pickle.dump(prob.root.parabo_mm, f)
f.close()


xyzkrig = np.array([[xi,yi,sg.predict(np.array([xi,yi]))[0]] \
        for xi in x for yi in y])
#xyzkrig = np.array([[0.,0.,0.]]*(25*25))
#cnt = 0
#for xi in x:
#    for yi in y:
#        xyzkrig[cnt,0] = prob["parabo_mm.x"] = xi
#        xyzkrig[cnt,1] = prob["parabo_mm.y"] = yi
#        prob.run()
#        xyzkrig[cnt,2] = prob["parabo_mm.f_xy"]
#        cnt += 1

fig = plt.figure(figsize=(6,4)); ax = Axes3D(fig)
X, Y = np.meshgrid(x, y)
Z = (X-3.0)**2. + X*Y + (Y+4.0)**2. - 3.0
ax.plot_wireframe(X,Y,Z,label="theoretical surface")
ax.scatter3D(xyzkrig[:,0], xyzkrig[:,1], xyzkrig[:,2], c="r", marker="o",label="Interpolated value")
ax.set_xlabel('x'); ax.set_ylabel('y'); ax.set_zlabel('f_xy')
plt.legend()
plt.show()


kriging_paraboloid.py의 전반부는 설명을 생략하고 후반부에만 설명합니다.
첫째, Kriging 근사 모델을 평가하는 샘플 포인트를 작성했습니다.
이것은 LHS (라틴 초방격 샘플링) 한 점과는 다른 점이며,
$ -50\leq x, y\leq 50 $의 범위를 25로 나눈 25x25 샘플 포인트에서 평가되었습니다.
sg = prob.root.parabo_mm._init_unknowns_dict["f_xy"]["surrogate"]에서 개인 클래스 변수 (_init_unknowns_dict)에 액세스하여 MeataModel에 설치된 surrogate 모델을로드합니다.
칭찬받은 치료는 아니지만 두 가지 이유가 있습니다.
* 단련 된 근사 모델의 보존이 구현되지 않았습니다.
* MetaModel에서 근사 모델의 값을 평가하려고하면 약간 번잡합니다 (#xyzkrig = ・・・ 아래의 주석 행).

나머지는 플롯 처리입니다.
이론 해를 와이어 프레임에 Kriging 근사 모델에 의한 평가 값을 점으로 플롯합니다.

Kriging 근사 모델에 의한 값 보간



LHS의 샘플 수가 너무 많았기 때문에 상당히 정확합니다.

좋은 웹페이지 즐겨찾기