TensorFlow で CNN をトレーニングして、回帰を使用してテキストの周囲に境界ボックスを出力することにより、画像内のテキスト ローカリゼーションを実行しようとしています。テキストを含まないさまざまな画像に IIIT 5K-Word データセットの画像を貼り付けてカスタム データセットを作成し、[pos_x、pos_y、幅、高さ] の形式で各画像の境界ボックスのラベルを作成しました。各画像にはテキストが 1 つしか含まれていないため、ネットワークは画像ごとに 1 つのバウンディング ボックスを予測するだけで済みます。例えば:
l2lossとブログから、tensorflow の l2_loss がこのタスクに適しているかもしれないという印象を受けました。しかし、私の損失は周期的なパターンで振動することにより、非常に奇妙な振る舞いをします。ハイパーパラメータの選択が不適切なため、奇妙に見えます。損失の計算方法に問題があると思われます(例: 以下)。YOLO や R-CNN などのより複雑なモデル以外のオブジェクト検出の実装に関する多くの情報を見つけることができませんでした。
これが私のモデルです:
# create_batches returns an iterator containing
(images[i:i+batch_size],labels[i:i+batch_size])
# Each image has size (128, 128, 3) and each label (1,4)
dataset = tf.data.Dataset.from_generator(create_batches, (tf.float32, tf.int64), ([None, 128, 128, 3], [None, 4])).repeat()
iterator = dataset.make_one_shot_iterator()
XX, y_ = iterator.get_next()
# Define Model
# 1. Define Variables and Placeholders
# Convolutional Layers
W_conv1 = tf.Variable(tf.truncated_normal([5, 5, 3, 4], stddev=0.1))
b_conv1 = tf.Variable(tf.constant(0.1, shape=[4]))
W_conv2 = tf.Variable(tf.truncated_normal([5, 5, 4, 8], stddev=0.1))
b_conv2 = tf.Variable(tf.constant(0.1, shape=[8]))
W_conv3 = tf.Variable(tf.truncated_normal([5, 5, 8, 16], stddev=0.1))
b_conv3 = tf.Variable(tf.constant(0.1, shape=[16]))
# Densely Connected Layer
W1 = tf.Variable(tf.truncated_normal([409600,200], stddev=0.1))
b1 = tf.Variable(tf.zeros([200]))
# Output Layer
W5 = tf.Variable(tf.zeros([200,4])) #truncated_normal([30,10], stddev=0.1))
b5 = tf.Variable(tf.zeros([4]))
#Conv. layers
y1conv = tf.nn.relu(tf.nn.conv2d(XX, W_conv1, strides=[1, 2, 2, 1], padding='SAME')+b_conv1)
y2conv = tf.nn.relu(tf.nn.conv2d(y1conv, W_conv2, strides=[1, 2, 2, 1], padding='SAME')+b_conv2)
y3conv = tf.nn.relu(tf.nn.conv2d(y2conv, W_conv3, strides=[1, 2, 2, 1], padding='SAME')+b_conv3)
# Re-shape output from conv-layers
conved_input = tf.reshape(y3conv, [-1, 409600])
y4 = tf.nn.relu(tf.matmul(conved_input, W1) + b1)
y = tf.nn.softmax(tf.matmul(y4, W5) + b5)
# 3. Define the loss function
y_fl = tf.to_float(y_)
diff = tf.subtract(y_fl,y)
loss = tf.nn.l2_loss(diff)
# 4. Define an optimizer
train_step = tf.train.AdamOptimizer(0.005).minimize(loss)
# initialize
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
20 エポックのトレーニング後、損失は次のようになります。
損失を tf.reduce_mean(tf.nn.l2_loss(diff)) に変更してバッチ全体の平均誤差を取得しようとしましたが、同じ種類のプロットが生成されました。バッチの損失を計算する方法に明らかな間違いはありますか?