Caffeで最初に実装されたピクセルラベリング(FCNスタイル)のコードをTensorFlowに移植します。私はSlimのResNets(ResNet-101)の実装を16pxのストライドで使用し、それをアップコンバルションレイヤーでさらにアップサンプリングして8pxの最終的なストライドを達成しました。入力画像は任意のサイズであるため、私はbatch_size = 1を持っています。問題は、トレーニングが本当に遅いことです。オリジナルのcaffeの実装は、同じハードウェア(Tesla K40m)で30秒で実行しますが、約3.5分で100の画像を処理します。ここで私が持っているコードの縮小版だ:TF-Slimを使用した完全畳み込みResNetsが非常に遅いです。
import datetime as dt
import tensorflow as tf
import tensorflow.contrib.slim as slim
from tensorflow.contrib.slim.nets import resnet_v1
from MyDataset import MyDataset
from TrainParams import TrainParams
dataset = MyDataset()
train_param = TrainParams()
#tf.device('/gpu:0')
num_classes = 15
inputs = tf.placeholder(tf.float32, shape=[1, None, None, 3])
with slim.arg_scope(resnet_v1.resnet_arg_scope(False)):
mean = tf.constant([123.68, 116.779, 103.939],
dtype=tf.float32, shape=[1, 1, 1, 3], name='img_mean')
im_centered = inputs - mean
net, end_points = resnet_v1.resnet_v1_101(im_centered,
global_pool=False, output_stride=16)
pred_upconv = slim.conv2d_transpose(net, num_classes,
kernel_size = [3, 3],
stride = 2,
padding='SAME')
targets = tf.placeholder(tf.float32, shape=[1, None, None, num_classes])
loss = slim.losses.sigmoid_cross_entropy(pred_upconv, targets)
log_dir = 'logs/'
variables_to_restore = slim.get_variables_to_restore(include=["resnet_v1"])
restorer = tf.train.Saver(variables_to_restore)
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
sess.run(tf.initialize_local_variables())
restorer.restore(sess, '/path/to/ResNet-101.ckpt')
optimizer = tf.train.GradientDescentOptimizer(learning_rate=.001)
train_step = optimizer.minimize(loss)
t1 = dt.datetime.now()
for it in range(10000):
n1=dt.datetime.now()
batch = dataset.next_batch() # my function that prepares training batch
sess.run(train_step, feed_dict={inputs: batch['inputs'],
targets: batch['targets']})
n2=dt.datetime.now()
time = (n2-n1).microseconds/(1000)
print("iteration ", it, "time", time)
私はフレームワークを学んでいる、と私は日のカップルで一緒にこのコードを置くので、私はそれは素敵ではないかもしれない理解しています。わかりましたように、私はまた、データ準備コードとネットワークの前方 - 後方パスにかかる実際の時間を測定しようとします。そして、この時間は実際のランタイムと比較して100回の反復で合計した場合、実際にはずっと小さくなります。私はいくつかのスレッド/プロセスの同期が進行していると思われますが、それは測定されていませんが、私はそれがかなり奇妙であることがわかります。 topコマンドは、おそらくそれによって生成された主なものと同じタイトルの約10のプロセスを表示します。
私はこれをどのようにスピードアップすることができますか?
ありがとうございました。
更新。より多くの研究の結果、私は「フィード」データがキューに比べて遅くなることが分かったので、別のスレッドでキューにコードを再実装しました:https://gist.github.com/eldar/0ecc058670be340b92e5a1044dc8a089しかし、ランタイムはほぼ同じです。
UPDATE2。速度に関する問題が何であるかを考えたようです。私は完全畳み込みで練習し、私のイメージは任意のサイズとアスペクト比です。固定サイズのダミーのランダムな数のテンソルを送ると、速く動作します。 10個の定義済みサイズの入力テンソルを生成する場合、最初の10回の反復は遅くなりますが、その後は高速化されます。 TensorFlowのように見えますが、各繰り返しですべてのテンソルのサイズ変更はCaffeほど効率的ではありません。プロジェクトのGitHubでチケットを発行します。
はそれがおかしくなり、巨大なモデルだということを覚えておいてください
ソリューションは、環境変数
TF_CUDNN_USE_AUTOTUNE=0
を設定しました。 resnet_v1_101の "101"は、それが101コンバートのレイヤーであることに由来します。 – Juliusあなたが得るものが期待されるかどうかわからないのに – Julius
afaik彼らはそれを訓練するためにいくつかの異なるマシンを使用します – Julius