[PYTHON] Tensorflow C ++에서 그래프를 내보내고 실행하는 다양한 방법
PYTHONTensorflow C ++에서 그래프를 내보내고 실행하는 다양한 방법
훈련 된 네트워크를 C ++로 가져 오려면 네트워크를 내보낼 수 있어야합니다. 많은 것을 검색하고 그것에 대한 정보를 거의 찾지 못한 후에는 freeze_graph ()를 사용하여이를 수행 할 수 있어야한다는 것을 분명히했습니다.
Tensorflow의 새로운 0.7 버전 덕분에, 그들은 그것의 문서를 추가했습니다.
문서를 조사한 결과 유사한 방법이 거의 없다는 것을 알았습니다. freeze_graph ()와 다음과 같은 점을 구분할 수 있습니까? tf.train.export_meta_graph 그것은 비슷한 매개 변수를 가지고 있지만 C ++로 모델을 임포트하는 데에도 사용될 수 있습니다. (차이점은이 메소드로 파일 출력을 사용하면 import_graph_def () 만 사용할 수 있다는 것입니다. 그밖에?)
또한 write_graph ()를 사용하는 방법에 대한 하나의 질문 : 문서화에서 graph_def는 sess.graph_def로 주어 지지만 freeze_graph ()의 예제에서는 sess.graph.as_graph_def ()입니다. 이 둘의 차이점은 무엇입니까?
이 질문은이 문제와 관련이 있습니다.
고맙습니다!
해결법
-
==============================
1.여기에 TF 0.12에서 도입 된 V2 체크 포인트를 활용하는 내 솔루션이 있습니다.
여기에 TF 0.12에서 도입 된 V2 체크 포인트를 활용하는 내 솔루션이 있습니다.
모든 변수를 상수로 변환하거나 그래프를 고정 할 필요가 없습니다.
명확성을 위해 V2 검사 점은 내 디렉토리 모델에서 다음과 같이 보입니다.
checkpoint # some information on the name of the files in the checkpoint my-model.data-00000-of-00001 # the saved weights my-model.index # probably definition of data layout in the previous file my-model.meta # protobuf of the graph (nodes and topology info)
파이썬 파트 (저장)
with tf.Session() as sess: tf.train.Saver(tf.trainable_variables()).save(sess, 'models/my-model')
tf.trainable_variables ()를 사용하여 Saver를 생성하면 두통과 저장 공간을 절약 할 수 있습니다. 그러나 좀 더 복잡한 모델의 경우 모든 데이터를 저장해야하는 경우이 인수를 Saver로 제거하고 그래프를 만든 후에 Saver를 만들도록하십시오. 또한 모든 변수 / 레이어에 고유 한 이름을 지정하는 것이 좋습니다. 그렇지 않으면 다른 문제로 실행할 수 있습니다.
파이썬 부분 (추론)
with tf.Session() as sess: saver = tf.train.import_meta_graph('models/my-model.meta') saver.restore(sess, tf.train.latest_checkpoint('models/')) outputTensors = sess.run(outputOps, feed_dict=feedDict)
C ++ 부분 (추론)
checkpointPath는 기존 파일에 대한 경로가 아니며 공통 접두어 만 사용합니다. 실수로 .index 파일에 경로를 넣으면 TF가 잘못되었다는 사실을 알려주지 않지만 초기화되지 않은 변수로 인해 추측 중에 죽을 것입니다.
#include <tensorflow/core/public/session.h> #include <tensorflow/core/protobuf/meta_graph.pb.h> using namespace std; using namespace tensorflow; ... // set up your input paths const string pathToGraph = "models/my-model.meta" const string checkpointPath = "models/my-model"; ... auto session = NewSession(SessionOptions()); if (session == nullptr) { throw runtime_error("Could not create Tensorflow session."); } Status status; // Read in the protobuf graph we exported MetaGraphDef graph_def; status = ReadBinaryProto(Env::Default(), pathToGraph, &graph_def); if (!status.ok()) { throw runtime_error("Error reading graph definition from " + pathToGraph + ": " + status.ToString()); } // Add the graph to the session status = session->Create(graph_def.graph_def()); if (!status.ok()) { throw runtime_error("Error creating graph: " + status.ToString()); } // Read weights from the saved checkpoint Tensor checkpointPathTensor(DT_STRING, TensorShape()); checkpointPathTensor.scalar<std::string>()() = checkpointPath; status = session->Run( {{ graph_def.saver_def().filename_tensor_name(), checkpointPathTensor },}, {}, {graph_def.saver_def().restore_op_name()}, nullptr); if (!status.ok()) { throw runtime_error("Error loading checkpoint from " + checkpointPath + ": " + status.ToString()); } // and run the inference to your liking auto feedDict = ... auto outputOps = ... std::vector<tensorflow::Tensor> outputTensors; status = session->Run(feedDict, outputOps, {}, &outputTensors);
-
==============================
2.예측 (그리고 다른 모든 작업)에 대해 다음과 같이 할 수 있습니다.
예측 (그리고 다른 모든 작업)에 대해 다음과 같이 할 수 있습니다.
우선 파이썬에서 미래의 사용을 위해 변수 또는 연산의 이름을 지정해야합니다.
self.init = tf.initialize_variables(tf.all_variables(), name="nInit")
교육을 마친 후 계산이 너무 많아서 할당 된 변수가있을 때 그래프를 통해 상수로 저장됩니다. (거의 같은 동결 도구를 사용하여 수행 할 수 있습니다,하지만 난 보통 자신에 의해 그것을 확인, "이름 = nWeights"py와 아래 cpp에서 확인)
def save(self, filename): for variable in tf.trainable_variables(): tensor = tf.constant(variable.eval()) tf.assign(variable, tensor, name="nWeights") tf.train.write_graph(self.sess.graph_def, 'graph/', 'my_graph.pb', as_text=False)
이제 C ++로 가서 저장된 상수로부터 그래프와로드 변수를로드하십시오.
void load(std::string my_model) { auto load_graph_status = ReadBinaryProto(tensorflow::Env::Default(), my_model, &graph_def); auto session_status = session->Create(graph_def); std::vector<tensorflow::Tensor> out; std::vector<string> vNames; int node_count = graph_def.node_size(); for (int i = 0; i < node_count; i++) { auto n = graph_def.node(i); if (n.name().find("nWeights") != std::string::npos) { vNames.push_back(n.name()); } } session->Run({}, vNames, {}, &out);
이제 모든 신경 회로망 무게 또는 다른 변수가로드되었습니다.
마찬가지로 다른 작업을 수행 할 수 있습니다 (이름은 기억하고 있습니까?). 적절한 크기의 입력 및 출력 텐서를 만들고, 데이터로 텐서를 입력하고 세션을 다음과 같이 실행하십시오 :
auto operationStatus = session->Run(input, {"put_your_operation_here"}, {}, &out);
from https://stackoverflow.com/questions/35508866/tensorflow-different-ways-to-export-and-run-graph-in-c by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 숫자의 숫자 합계 - 파이썬 (0) | 2018.10.07 |
---|---|
[PYTHON] 파이썬의 'in'연산자를 재정의 하시겠습니까? (0) | 2018.10.07 |
[PYTHON] Python readlines () 읽기 및 사용법 (0) | 2018.10.07 |
[PYTHON] 중첩 된 사전의 항목에서 팬더 DataFrame 구성 (0) | 2018.10.07 |
[PYTHON] 파이썬 목록에서 중복을 제거하고 순서를 유지하는 방법? [복제] (0) | 2018.10.07 |