実際のベクトルを2進化するために、以下のカスタム操作をグラデーションで作成しました。 (このコードはhttps://gist.github.com/harpone/3453185b41d8d985356cbe5e57d67342からインスピレーションを受けている)Tensorflow:2つのネットワークで同時に使用されるカスタム操作では、ナノが生成されます
def py_func(func, inp, Tout, stateful=True, name=None, grad=None):
# Need to generate a unique name to avoid duplicates:
rnd_name = name+'PyFuncGrad' + str(np.random.randint(0, 1E+8))
tf.RegisterGradient(rnd_name)(grad) # see _MyBinarizerGrad for grad example
g = tf.get_default_graph()
with g.gradient_override_map({"PyFunc": rnd_name}):
return tf.py_func(func, inp, Tout, stateful=stateful, name=name)
def mycustombinarizer(x):
if _test_:
return x>0.5
sess_ = tf.Session()
probs = tf.constant(x)
probs = tf.reshape(probs,[-1])
probs = tf.pack([1-probs, probs], axis=1)
probs = tf.log(probs/(1-probs))
indexes = tf.multinomial(probs, 1)
indexes = tf.cast(tf.reshape(indexes, list(x.shape)),tf.float32)
with sess_.as_default():
binary_x = indexes.eval()
return binary_x
def binarizer(x, name=None):
with ops.name_scope(name, "Binarizer", [x]) as name:
sqr_x = py_func(mycustombinarizer,
[x],
[tf.float32],
name=name,
grad=_MyBinarizerGrad) # <-- here's the call to the gradient
return tf.reshape(sqr_x[0], tf.shape(x))
def _MyBinarizerGrad(op, grad):
return grad
この操作を使用してちょうど1のネットワークがある場合、これは完全に正常に動作します。しかし、同じネットワークの2つのコピーを作成し、このバイナリ演算を使用して結合コスト(cost_net1 + cost_net2)を最適化しようとすると、数回繰り返した後にナノコストが生成されます。
def network_(x, netname):
with tf.variable_scope(netname):
x = someoperation(x)
...
ret_tensor = binarizer(x,netname)
ypred1 = network_(input,'net1')
ypred2 = network_(input,'net2')
cost = costfn(ypred1,ytrue)+costfn(ypred2,ytrue)
誰でも私のカスタム機能の実装に間違いがありますか教えてください。セッションでmycustombinarizerのindexes.eval()を評価するのが問題なのですか、それともname_scope/variable_scopeに問題があるのでしょうか、まったく問題ですか?私はここで立ち往生している。
私はカスタムグラデーションを定義するためにpyfuncを書きました。このコードをテンソルフローコードでカスタムのグラデーションを得るために変換するにはどうすればいいですか? –
パブリックAPIでこれがうまくサポートされているとは思いません。 –