私は現在、Tensorflowライブラリに精通していますが、私はバグという根本的な疑問を持っています。Tensorflow:レイヤーサイズはバッチサイズに依存しますか?
MNIST分類用の畳み込みニューラルネットワークを構築しているうちに、自分のmodel_fnを使用しようとしました。通常、次の行が入力フィーチャの形状を変更するために発生します。
であり、-1は入力バッチサイズを表します。
私は私の畳み込み層への入力として、このノードを使用しているので、
x = tf.reshape(x, shape=[-1, 28, 28, 1])
conv1 = tf.layers.conv2d(x, 32, 5, activation=tf.nn.relu)
は、このサイズのすべての私のネットワーク層は、バッチサイズに依存していることを意味するのでしょうか?
私はn = batch_sizeテストイメージを提供する場合にのみ動作する、単一のテスト入力でグラフをフリーズして実行しようとしました。
予測中に入力バッチサイズでネットワークを実行する方法に関するヒントを教えてもらえますか? また、ネットワーク定義のtf.reshapeノード(最初のノードはcnn_layoutを参照)を使用するのが最良の入力ではないと思います。
私は私のネットワーク層アップとmodel_fn
def cnn_layout(features,reuse,is_training):
with tf.variable_scope('cnn',reuse=reuse):
# resize input to [batchsize,height,width,channel]
x = tf.reshape(features['x'], shape=[-1,30,30,1], name='input_placeholder')
# conv1, 32 filter, 5 kernel
conv1 = tf.layers.conv2d(x, 32, 5, activation=tf.nn.relu, name='conv1')
# pool1, 2 stride, 2 kernel
pool1 = tf.layers.max_pooling2d(conv1, 2, 2, name='pool1')
# conv2, 64 filter, 3 kernel
conv2 = tf.layers.conv2d(pool1, 64, 3, activation=tf.nn.relu, name='conv2')
# pool2, 2 stride, 2 kernel
pool2 = tf.layers.max_pooling2d(conv2, 2, 2, name='pool2')
# flatten pool2
flatten = tf.contrib.layers.flatten(pool2)
# fc1 with 1024 neurons
fc1 = tf.layers.dense(flatten, 1024, name='fc1')
# 75% dropout
drop = tf.layers.dropout(fc1, rate=0.75, training=is_training, name='dropout')
# output logits
output = tf.layers.dense(drop, 1, name='output_logits')
return output
def model_fn(features, labels, mode):
# setup two networks one for training one for prediction while sharing weights
logits_train = cnn_layout(features=features,reuse=False,is_training=True)
logits_test = cnn_layout(features=features,reuse=True,is_training=False)
# predictions
predictions = tf.round(tf.sigmoid(logits_test),name='predictions')
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode, predictions=predictions)
# define loss and optimizer
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits_train,labels=labels),name='loss')
optimizer = tf.train.AdamOptimizer(learning_rate=LEARNING_RATE, name='optimizer')
train = optimizer.minimize(loss, global_step=tf.train.get_global_step(),name='train')
# accuracy for evaluation
accuracy = tf.metrics.accuracy(labels=labels,predictions=predictions,name='accuracy')
# summarys for tensorboard
tf.summary.scalar('loss',loss)
# return training and evalution spec
return tf.estimator.EstimatorSpec(
mode=mode,
predictions=predictions,
loss=loss,
train_op=train,
eval_metric_ops={'accuracy':accuracy}
)
感謝を追加します!
(output_graph_def.SerializeToString()) 'を実行します。しかし、私はこれもグラフにミニサイズのサイズを凍結すると思います。 だから明確にする。私は訓練されたモデルを実行するために標準的なテンソルフローライブラリの代わりにサーババックエンドを提供する必要がありますか?私のモデルは本当に小さく、非常に高速に実行する必要があるので、私はかなりリーンなソリューションを探しています。 – openloop
グラフをフリーズしてバッチサイズをグラフにフリーズするかどうかはわかりません。私はそれをすべきではないと言いたい。サーバーのバックエンドなしで比較的簡単に訓練モデルを実行できることに注意してください。モデルをSavedModelとしてエクスポートすることをお勧めします(グラフはフリーズできます)。これにより、移植性が向上し、より良い移植性のライブラリが提供されます(必要に応じて、より高度な提供ソリューションに簡単に卒業するオプションもあります)。 SavedModelで予測を行う方法については、https://stackoverflow.com/a/46139198/1399222をご覧ください。 – rhaertel80
SavedModelを使いたくない場合は、基本的な考え方は 'tensorflow.python.training.saver.import_meta_graph'を使用し、' session.Run'を使用して入力をフィードし、出力をフェッチすることです。そのトリックは、入力と出力のテンソルの正しい名前を取得しています。 – rhaertel80