質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.80%

tensorflowによるマルチラベル分類

解決済

回答 2

投稿

  • 評価
  • クリップ 2
  • VIEW 3,859

NeuralPochi

score 14

前提・実現したいこと

Pythonでマルチラベル分類を試みています.
機械学習として畳み込みネットをTensorflowで実装しました.
入力画像は7×252の大きさで,各ピクセル値が0以上1以下の
[0.1255,0.5251,0.2131,0.1632,0.7372, ... , 0.0562]
のようなfloat型です.
対するターゲットは
[0,1,0,0,1,0,1, ... ,0]
となるような,長さ88のバイナリベクトルです.
要は,入力画像に応じてバイナリベクトルの各要素の値が(独立して)決定されるような畳み込みネットを構築したいので,マルチラベル分類問題だと仮定してコードを記述しました.

発生している問題・エラーメッセージ

学習を重ねることによってエラー関数は収束(0.62から0.14程度にまで減少)したのですが、実際に学習させたデータを入力して再現を試みると,極端な話,どのような入力に対しても,
[0,0.3,1,0.5,0,...,0.7]
[0,0.3,1,0.5,0,...,0.7]
[0,0.3,1,0.5,0,...,0.7]
[0,0.3,1,0.5,0,...,0.7]
のような,全く同じパターンのバイナリベクトルが出力されてしまいます.

そもそも正論文を参考にネットワークを組んでいるので,畳み込みネットの構造(レイヤー数,活性化関数など)自体は保証されていると考えております.

該当のソースコード

記述されていない定数や関数に関しては適切なものが設定されていると仮定して下さい.
入力画像(x_input):1×1764(7×252にreshape)
ターゲット(y_):1×88 (バリナリベクトル)
誤差関数(cross_entoropy):tf.nn.sigmoid_cross_entropy_with_logits
出力(Output):出力層にsigmoid
以下のコードでは学習は一回ですが,実際はバリデーションデータを用いて収束が停滞するまで学習を繰り返し,入力データは毎回ランダムに並べ替えています.

def weight_variable(shape): 
  initial = tf.truncated_normal(shape,mean=0,stddev=0.5,dtype=tf.float32) 
  return tf.Variable(initial) 

def bias_variable(shape): 
  initial = tf.truncated_normal(shape,mean=0,stddev=0.5,dtype=tf.float32) 
  return tf.Variable(initial) 

def conv2d(x, W): 
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_1x3(x):
  return tf.nn.max_pool(x, ksize=[1, 1, 3, 1],strides=[1, 1, 3, 1], padding='SAME')

if __name__ == '__main__':

  x = tf.placeholder("float", shape=[None,252*7])
  y_ = tf.placeholder("float", shape=[None,88]) 
  sess = tf.InteractiveSession() 

  ######ConvNet#######
  x_input = tf.reshape(x, [-1,7,252,1]) 
  keep_prob = tf.placeholder("float")
  W_conv1 = weight_variable([w1_x, w1_y, 1, w1_outc]) 
  b_conv1 = bias_variable([w1_outc])
  h_conv1 = tf.tanh(conv2d(x_input, W_conv1) + b_conv1) 
  h_pool1 = max_pool_1x3(h_conv1) 
  h_conv1_drop = tf.nn.dropout(h_pool1, keep_prob)


  W_conv2 = weight_variable([w2_x, w2_y, w1_outc, w2_outc]) 
  b_conv2 = bias_variable([w2_outc]) 
  h_conv2 = tf.tanh(conv2d(h_conv1_drop, W_conv2) + b_conv2) 
  h_pool2 = max_pool_1x3(h_conv2)
  h_conv2_drop = tf.nn.dropout(h_pool2, keep_prob) 

  ######Fully connected #######
  W_fc1 = weight_variable([28*7*50, 1000]) 
  b_fc1 = bias_variable([1000])

  h_pool2_flat = tf.reshape(h_conv2_drop, [-1,28*7*50]) 
  h_fc1 = tf.sigmoid(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
  h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) 

  W_fc2 = weight_variable([1000, 200])
  b_fc2 = bias_variable([200]) 
  h_fc2 = tf.sigmoid(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
  h_fc2_drop = tf.nn.dropout(h_fc2, keep_prob)

  W_fc3 = weight_variable([200, 88])
  b_fc3 = bias_variable([88]) 
  y_conv=tf.matmul(h_fc2_drop, W_fc3) + b_fc3

  Sig_y_conv = tf.sigmoid(y_conv) #for output

  #cross entoropy and optimizer
  cross_entoropy = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=y_conv,labels= y_))
  batch = tf.Variable(0)
  train_step = tf.train.MomentumOptimizer(1e-2,0.9).minimize(cross_entoropy,global_step=batch) 

  sess.run(tf.initialize_all_variables())

  #getdata
 for datano in range(datanum) :
    input_data = DataLibrary[datano]
    target_label = LabelLibrary[datano]
    if dataconect == 0:
              train_data = input_data
              train_label = target_label 
    else :
              train_data = np.r_[train_data,input_data]
              train_label = np.r_[train_label,target_label]
 perm = np.arange(train_data.shape[0])
 np.random.shuffle(perm)
 train_data = train_data[perm]
 train_label = train_label[perm]

  #training
 for i in range(math.ceil(train_data.shape[0]/BATCH_SIZE)):
    batch = mini_batch(train_data, train_label, i)
    feed_dict = {x: batch[0], y_: batch[1], keep_prob: Drate}
    train_step.run(feed_dict=feed_dict)

  #Output
 Output = Sig_y_conv.eval(feed_dict={x: test_data, y_: test_label, keep_prob: 1.0})

試したこと

重み付けとバイアスの初期値を色々弄ってみました.
OptimizerもADADELTAやAtomに変更して行ってみました.
いずれも効果はありませんでした(そもそもほとんど収束しない).

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2017/06/17 14:56

    初投稿から一か月程度経ちますが、何か手掛かりはつかめましたか?

    キャンセル

回答 2

check解決した方法

+2

自己解決いたしましたので,質問を閉じさせて頂きます.
回答してくださった方,ありがとうございました.

1. 解決方法

結果的には,入力データを毎回ランダムに並べ替えていたことで精度が落ちてしまっていたようで,入力データをイタレーションごとに同じ並びにすることで,誤差(エラー関数)が0.03程度にまで収束し,求めていたような入力に適した出力を得ることに成功しました.
今回質問に記述させていただいたプログラム自体に問題はありませんでした.

2. 補足

今回の直接的な原因ではないようですが,デバッグの過程で,

  • 入力データ数の増加
    質問段階ではデータ数:500
    精度を確認した時点ではデータ数:3000
  • イタレーションによる学習率の減少率の調整
    初期値:0.01から,
    質問段階では1000回で線形的に0まで減少
    精度を確認した時点では10000回で0まで減少

の2点も精度に影響が出ましたので,似たような状況の方は是非お試し下さい.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

参考になるとよいのですが…

学習に使ったデータで検証をして精度が出ないのは不思議な状態ですので、まずはtensorboardに学習ステップ数と実際の精度をグラフにして、本当に学習ができているのか見てみてはいかがでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/21 21:18

    回答ありがとうございます.
    ご教授頂いたサイト,大変参考になりました.ありがとうございます.
    質問したプログラムのままでステップ数と精度を見てみたところ,学習は進んでいましたが,ある程度のところで止まってしまい,結局同じようなパターンを出力するのみでした.
    やはりネットワークのパラメータに問題があるようです.

    キャンセル

  • 2017/06/21 22:12

    >やはりネットワークのパラメータに問題があるようです.
    この件と全く異なる用法かもしれませんが、MNISTのようないじり倒されたTFの実例のパラメータを突っ込んでみてはいかがでしょうか?(テンソルの数合わせは必要になりますが…)

    キャンセル

  • 2017/06/25 01:00

    アドバイスありがとうございます.
    実は,このプログラムはMNISTから出発しているので,典型的なパラメータは一通り試しております.
    目的によってパラメータを調整するのは、思った以上に難しいようです.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る