2017-09-07 7 views
2

Tensorflow C++ APIを使用してグラデーションを計算したいとします。私はtf.gradientsはPythonのAPIで動作しました:保存されたグラフに基づいてTensorflow C++ APIのグラジエントを計算する方法

import tensorflow as tf 

with tf.Session() as sess: 
    a = tf.Variable([[5.0,1.0,2.0]], name='a') 
    b = tf.Variable([[9.0,2.0,0.0]], name='b') 
    c = tf.matmul(a, tf.transpose(b), name="c") 
    deriv = tf.gradients(c,a, name="deriv") #\partial c/\partial a 

    sess.run(tf.global_variables_initializer()) 
    print(sess.run(deriv)) 

    #### get the tensor by name #### 
    tmp = tf.get_default_graph().get_tensor_by_name("deriv/c_grad/MatMul:0") 
    print(sess.run(tmp)) 

    #### save graph #### 
    tf.train.write_graph(sess.graph_def, './', 'graph.pb', as_text=False) 
    tf.train.write_graph(sess.graph_def, './', 'graph.pbtxt', as_text=True) 


    saver = tf.train.Saver() 
    saver.save(sess, "variable", global_step=0) 

私はprint(sess.run(deriv))print(sess.run(tmp))両方から正しい答えを持って、graph.pb生成しました。次に、次のC++コードを使用してグラフを読み込み、Pythonで行ったのと同様の方法で勾配計算を行いました。

#include "tensorflow/core/public/session.h" 
#include "tensorflow/core/platform/env.h" 
#include "tensorflow/cc/framework/ops.h" 

void checkStatus(const tensorflow::Status& status) { 
    if (!status.ok()) { 
    std::cout << status.ToString() << std::endl; 
    exit(1); 
    } 
} 

int main(int argc, char** argv) { 
    namespace tf = tensorflow; 

    tf::Session* session; 
    tf::Status status = tf::NewSession(tf::SessionOptions(), &session); 
    checkStatus(status); 

    tf::GraphDef graph_def; 
    status = ReadBinaryProto(tf::Env::Default(), "graph.pb", &graph_def); 
    checkStatus(status); 

    status = session->Create(graph_def); 
    checkStatus(status); 

    tf::Input::Initializer xi({1.0,2.0,-6.0}); 
    tf::Input::Initializer yi({9.0,2.0,0.0}); 
    std::vector<std::pair<tf::string, tf::Tensor>> input_tensors = {{"a", xi.tensor}, {"b", yi.tensor}}; 
    std::vector<tf::Tensor> output_tensors; 
    status = session->Run(input_tensors, {"deriv/c_grad/MatMul"}, {}, &output_tensors); 
    checkStatus(status); 

    tf::Tensor output = output_tensors[0]; 
    auto out = output.vec<float>(); 
    std::cout << out(0) << " " << out(1) << " " << out(2) << std::endl; 
    session->Close(); 
    return 0; 
} 

コンパイルがスムーズに走ったが、私はランタイムエラーました:

内部を:double型の出力0は、ノード_recv_b_0 = _Recvclient_terminated =真、recv_device = "/ジョブの宣言出力float型と一致していません。タスク名:0 /タスク:0/cpu:0」、send_device = "/ job:localhost/replica:0/task:0/cpu:0"、send_device_incarnation = -3399984051910545345、tensor_name = "b"、tensor_type = DT_FLOAT "deriv/c_grad/MatMul"の他に、graph.pbtxtの "deriv"に関連する他のすべての名前も試しましたが、いずれも機能しません。

私の質問はどのように勾配計算のノードを参照するのですか? Pythonは "deriv/c_grad/MatMul"を受け入れますが、C++では受け入れられません。私はまたそれを行うための一般的な方法があるかどうか疑問に思っています。ドットプロダクトではなくニューラルネットワーク出力を区別することができます。将来の入力テンソル、MatMulはもう最後のステップにはなりません。

答えて

0

yi入力テンソルを正しく初期化していないようです。ダブルスとして、あなたのサンプルで

Internal: Output 0 of type double does not match declared output type float 
for node _recv_b_0 = _Recvclient_terminated=true, 
recv_device="/job:localhost/replica:0/task:0/cpu:0", 
send_device="/job:localhost/replica:0/task:0/cpu:0", 
send_device_incarnation=-3399984051910545345, 
tensor_name="b",tensor_type=DT_FLOAT, 
_device="/job:localhost/replica:0/task:0/cpu:0" 

あなたはYIを初期化します。

tf::Input::Initializer yi({9.0f, 2.0f, 0.0f}); 

tf::Input::Initializer yi({9.0,2.0,0.0}); 

あなたはおそらくちょうど試してみてください(注F年代を追加しました)

関連する問題