2017-03-27 13 views
1

TFテンソルをカスタムケラス損失関数の内部に作り直す方法はありますか?私は畳み込みニューラルネットワークのためにこのカスタム損失関数を定義していますか?標準binary_crossentropy追加background_termを計算することに加えてケルナ損失関数のテンソルを変形させますか?

def custom_loss(x, x_hat): 
    """ 
    Custom loss function for training background extraction networks (autoencoders) 
    """ 

    #flatten x, x_hat before computing mean, median 
    shape = x_hat.get_shape().as_list() 
    batch_size = shape[0] 
    image_size = np.prod(shape[1:]) 

    x = tf.reshape(x, [batch_size, image_size]) 
    x_hat = tf.reshape(x_hat, [batch_size, image_size]) 

    B0 = reduce_median(tf.transpose(x_hat)) 
    # I divide by sigma in the next step. So I add a small float32 to F0 
    # so as to prevent sigma from becoming 0 or Nan. 

    F0 = tf.abs(x_hat - B0) + 1e-10 

    sigma = tf.reduce_mean(tf.sqrt(F0/0.5), axis=0) 

    background_term = tf.reduce_mean(F0/sigma, axis=-1) 

    bce = binary_crossentropy(x, x_hat) 

    loss = bce + background_term 

    return loss 

損失に添加されます。この用語は、ネットワークがバッチの中央値を近似する画像​​を予測するようにインセンティブを与える。 CNNの出力が2dで、reduce_medianが1dの配列でうまく動作するので、イメージを1次元の配列に再構成する必要があります。私はこのネットワークを訓練しようとすると、私はエラー

Traceback (most recent call last): 
    File "stackoverflow.py", line 162, in <module> 
    autoencoder = build_conv_autoencoder(lambda_W, input_shape, num_filters, optimizer, custom_loss) 
    File "stackoverflow.py", line 136, in build_conv_autoencoder 
    autoencoder.compile(optimizer, loss, metrics=[mean_squared_error]) 
    File "/usr/local/lib/python3.5/dist-packages/keras/models.py", line 594, in compile 
    **kwargs) 
    File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 667, in compile 
    sample_weight, mask) 
    File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 318, in weighted 
    score_array = fn(y_true, y_pred) 
    File "stackoverflow.py", line 26, in custom_loss 
    x = tf.reshape(x, [batch_size, image_size]) 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/gen_array_ops.py", line 2448, in reshape 
    name=name) 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/op_def_library.py", line 494, in apply_op 
    raise err 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/op_def_library.py", line 491, in apply_op 
    preferred_dtype=default_dtype) 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py", line 710, in internal_convert_to_tensor 
    ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref) 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/constant_op.py", line 176, in _constant_tensor_conversion_function 
    return constant(v, dtype=dtype, name=name) 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/constant_op.py", line 165, in constant 
    tensor_util.make_tensor_proto(value, dtype=dtype, shape=shape, verify_shape=verify_shape)) 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/tensor_util.py", line 441, in make_tensor_proto 
    tensor_proto.string_val.extend([compat.as_bytes(x) for x in proto_values]) 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/tensor_util.py", line 441, in <listcomp> 
    tensor_proto.string_val.extend([compat.as_bytes(x) for x in proto_values]) 
    File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/util/compat.py", line 65, in as_bytes 
    (bytes_or_text,)) 
TypeError: Expected binary or unicode string, got None 

を取得TensorFlowグラフがインスタンス化される前にKerasがcustom_lossを呼び出しているように思えます。これにより、実際の値の代わりにbatch_sizeがNoneになります。このエラーへの損失関数の内部でテンソルを再形成する適切な方法は避けられますか?あなたは完全なコードhereを見ることができます。

+0

は、あなたが最初の層または 'Input'層のいずれかに代わり、' input_shape'の 'batch_input_shape'を定義しようとしたことがありますか? –

+0

get_shape()。as_list()を使って 'shape'の値を確認できますか?私は 'x'と' x_hat'が正しいテンソルであると仮定しますが、それらが正しいことを確認できれば、問題を解決するのに大いに役立ちます – DarkCygnus

答えて

0

テンソルを再構築するための適切な方法は、あなたがKerasを使用している場合、我々はdocsで見ることができるようにあなたがtf.reshape(x,shape)のラッパーですK.reshape(x,shape)方法を、使用する必要があります...

あります。

私もKerasにあなたにも、このように、docsで述べたK.int_shape(x)でこれを行うことができたときに、あなたのテンソルの形状を得るためにget_shape()を使用しているがわかりますいくつかの他の操作があることのほかに

shape = K.int_shape(x_hat) 

Keraバックエンド(tf.abs()tf.reduce_mean()tf.transpose()など)の代わりに、Tensorflowインポートを直接呼び出すことができます。ケラスバックエンドの対応するラッパーを使用して、均一な表記を行い、より規則的な動作を保証することを検討する必要があります。また、Keranoバックエンドを使用することで、TheanoとTensorflowの両方とプログラムの互換性を持たせることができるので、考慮すべき大きなプラスです。

さらに、定義されていない次元を持つテンソルを扱う場合、TypeErrorが表示されることがあります。 this questionを見て、未定義の次元のテンソルを再構成することについて説明します。また、Kerasでの同等のために、this otherの質問をチェックしてください。答えでは、TensorflowでKerasをバックエンドとして使用する方法を説明しています。

...あなたのコードに関して。基本的に、未定義のディメンションがある場合は、値-1を渡して、それがどのサイズであっても形状を推測させることができます(これは最初のリンクされた質問で説明されていますが、docsでも見ることができます)。ような何か:

x = tf.reshape(x, [-1, image_size]) 

または使用Kerasバックエンド:

x = K.reshape(x, [-1, image_size]) 
関連する問題