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

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

ただいまの
回答率

88.34%

tensorflowのSaverについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 323

yone_yone

score 28

tensorflowでニューラルネットワークの学習器の保存について質問させていただきます。

python_train.pyがニューラルネットワークを学習させるプログラムで、
python_test.pyが学習させたニューラルネットワークをテストさせるプログラムになります。

以下にコードを記載しています。
※汚いコードですみません。。。

#python_train.py

# coding: utf-8                                                                                      

import tensorflow as tf
import numpy as np
import pandas as pd
import glob
import os
import math
from AdaBound import AdaBoundOptimizer                                                            

def read_file(filename):
    ds_tmp = []
    with open(filename, 'r') as f:
        print(filename)
        for i in f:
            txt = i.split()
            del txt[0]
            txt = [ float(s) for s in txt]
            ds_tmp.append(txt)

        ds = np.array(ds_tmp)
        return ds


def process(label,path,Range):
    train_filename = path + "input_train_{}_rev.txt".format(label)
    test_filename = path + "input_val_{}.txt".format(label)
    train_data = read_file(train_filename)
    test_data = read_file(test_filename)                                                          
    y_train = train_data[:, 5:]/50.0                                               
    x_train = train_data[:, :5]                                                    
    y_test = test_data[:, 5:]/50.0
    x_test = test_data[:, :5]

    num_examples = y_train.shape[0]
    num_input = x_train.shape[1]
    bias_with_x = np.insert(x_train, 0, 1, axis=1).astype(np.float32)
    bias_with_x_test = np.insert(x_test, 0, 1, axis=1).astype(np.float32)

    #パラメータの設定                                                                                
    num_hidden1 = 30
    num_hidden2 = 30
    training_steps = 25000
    learning_rate = 0.005
    lambda_2 = 0.00000001
    MAE_train_ave = 0
    MAE_test_ave = 0
    MAE_val_ave = 0

    for seed in range(1,2):
        losses = []

        with tf.Session() as sess:
            # SET UP ALL THE TENSORS, VARIABLES, AND OPERATIONS.                                     
            input = tf.constant(bias_with_x)
            target = tf.constant(np.transpose([y_train]).astype(np.float32))

            # 重みの初期化                                                                           
            shape = [num_input+1, num_hidden1]
            n = shape[0] * shape[1]
            stddev = math.sqrt(1.0 / n)
            initial = tf.truncated_normal(shape=shape, stddev=stddev)
            initial = tf.truncated_normal(shape=shape, stddev=stddev, seed=seed)
            weights = tf.Variable(initial, name="weights")                                                                                                 

            shape = [num_hidden1, num_hidden2]
            n = shape[0] * shape[1]
            stddev = math.sqrt(1.0 / n)
            initial = tf.truncated_normal(shape=shape, stddev=stddev)
            initial = tf.truncated_normal(shape=shape, stddev=stddev, seed=seed)
            weights1 = tf.Variable(initial, name="weights1")

            shape = [num_hidden2, 1]
            n = shape[0] * shape[1]
            stddev = math.sqrt(1.0 / n)
            initial = tf.truncated_normal(shape=shape, stddev=stddev)
            initial = tf.truncated_normal(shape=shape, stddev=stddev, seed=seed)
            weights2 = tf.Variable(initial, name="weights2")

            # 層の中の計算(活性化関数, 正則化, 損失関数)                                             
            y1 = tf.sigmoid(tf.matmul(input, weights))
            y2 = tf.sigmoid(tf.matmul(y1, weights1))
            yhat = tf.sigmoid(tf.matmul(y2, weights2))
            yerror = tf.subtract(yhat, target)
            loss1 = tf.nn.l2_loss(yerror)
            L2_sqr = tf.nn.l2_loss(weights) + tf.nn.l2_loss(weights1) + tf.nn.l2_loss(weights2)
            loss = loss1 + lambda_2 * L2_sqr

            update_weights = AdaBoundOptimizer(learning_rate=0.01, final_lr=0.1,
                                                        beta1=0.9, beta2=0.999,
                                                        amsbound=False).minimize(loss)

            tf.global_variables_initializer().run()

            for i in range(training_steps):
                update_weights.run()
                losses.append(loss.eval())

            # 学習器保存                                                                             
            saver = tf.train.Saver()       
            saver.save(sess, "../../nn_train/nn/sig_h2_n30/BED600444/{}km/in5_BED600444_h2_n30_{}".format(Range, seed))

            # 検証データ                                                                             
            input_test = tf.constant(bias_with_x_test)
            target_test = tf.constant(np.transpose([y_test]).astype(np.float32))
            y1_test = tf.sigmoid(tf.matmul(input_test, weights))
            y2_test = tf.sigmoid(tf.matmul(y1_test, weights1))
            yhat_test = tf.sigmoid(tf.matmul(y2_test, weights2))


            # Training is done, get the final values for the graphs                                  
            betas = weights.eval()
            yhat = yhat.eval()
            error = np.sqrt(((y_train-yhat)*(y_train-yhat)).mean())                     

            size = len(y_train)
            MAE = (np.sum(np.abs(y_train-yhat)))/size                                                                            

            yhat_test = yhat_test.eval()
            size = len(y_test)
            MAE_val = (np.sum(np.abs(y_test-yhat_test)))/size

            MAE_train_ave += MAE                                                                     
            MAE_val_ave += MAE_val

    Train = MAE_train_ave                                                                    
    Val = MAE_val_ave                                                                            
    print('train_error : %s' % Train)
    print('val_error : %s' % Val)

    return Train, Val


def main():
    count = 0
    bool = True
    while bool:
        with open('../../../../text/in5_ver3/point/rev/label_BED600444.txt', 'r') as label:
            a_list = [line.rstrip() for line in label]                                                                        

        for label in a_list:
            ini = process(label, '../../../../text/in5_ver3/point/rev/', 3)
            count += 1

        with open('../../../../text/in5/4km/point/rev/label_BED600444.txt', 'r') as label:
            a_list = [line.rstrip() for line in label]

        for label in a_list:
            r4 = process(label, '../../../../text/in5/4km/point/rev/', 4)
            count += 1

        with open('../../../../text/in5/2km/point/rev/label_BED600444.txt', 'r') as label:
            a_list = [line.rstrip() for line in label]

        for label in a_list:
            r2 = process(label, '../../../../text/in5/2km/point/rev/', 2)
            count += 1

        print(min(r2[1], ini[1], r4[1]), count)

if __name__ == '__main__':
    main()
#python_test.py

import tensorflow as tf
import numpy as np
import pandas as pd
import glob
import os
import math


def read_file(filename):
    ds_tmp = []
    with open(filename, 'r') as f:
        print(filename)
        for i in f:
            txt = i.split()
            del txt[0]
            txt = [ float(s) for s in txt ]
            ds_tmp.append(txt)

        ds = np.array(ds_tmp)
        return ds

def process(label, path):
    test_filename = path + "input_train_{}_rev.txt".format(label)
    test_data = read_file(test_filename)
    y_test = test_data[:, 5:]/50.0
    x_test = test_data[:, :5]

    bias_with_x_test = np.insert(x_test, 0, 1, axis=1).astype(np.float32)
    input_test = tf.constant(bias_with_x_test)
    target_test = tf.constant(np.transpose([y_test]).astype(np.float32))

    with tf.Session() as sess:
        # 復元                                                                                       
        saver = tf.train.import_meta_graph('./in5_BED600444_h2_n30_1.meta')
        saver.restore(sess, tf.train.latest_checkpoint('./'))                                              
        graph = tf.get_default_graph()
        weights = graph.get_tensor_by_name("weights:0")
        weights1 = graph.get_tensor_by_name("weights1:0")
        weights2 = graph.get_tensor_by_name("weights2:0")
        print(sess.run('weights:0'))

        # テスト地点の計算                                                                           
        y1_test = tf.sigmoid(tf.matmul(input_test, weights))
        y2_test = tf.sigmoid(tf.matmul(y1_test, weights1))
        yhat_test = tf.sigmoid(tf.matmul(y2_test, weights2))

        size = len(y_test)                                     
        MAE_test = (np.sum(np.abs(y_test-yhat_test)))
        y = sess.run(MAE_test)

        return y

def main():
    with open('../../../../../../../text/in5/5km/point/rev/label_BED600444.txt', 'r') as label:
        a_list = [line.rstrip() for line in label]                                                                               

    for label in a_list:
        test_error = process(label, '../../../../../../../text/in5/5km/point/rev/')

    print('test_error : %s' % test_error.mean())

if __name__ == '__main__':
    main()


python_train.pyで学習させた重みをtf.train.Saver()で保存したのち、
きちんと保存できているか同じデータを使って確認したところ、
train_errorが異なりました。
tf.train.Saver()を入れる箇所が違うのかと思い、
他にも入れる箇所を変えてみましたが変わりませんでした。
分かる方がいましたら、回答いただけると助かります。

※ご回答いただいた内容に質問させていただくこともあるかと思いますので、
※よろしければご返信いただければと思います。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • fourteenlength

    2019/10/29 06:50

    Q.1
    > きちんと保存できているか同じデータを使って確認したところ、
    > train_errorが異なりました
    train_errorの値は、train.pyの方で確認した(二回train.pyの方を走らせた)、で良いでしょうか?
    Q.2
    def main():の中で、for label in a_list:で一行ずつ学習、保存をしているように見えます。この理解であっていますか?
    Q.3
    def main():の中で、同じ順番で複数の設定ファイルを読みだして、同じ学習結果に保存しているように見えます。この理解で合っていますか?

    キャンセル

  • yone_yone

    2019/10/30 00:07

    fourteenlengthさん、ありがとうございます。
    以下、質問に対する回答になります。

    Q.1
    train_errorの値はtrain.pyとtest.pyで同じデータを読み込ませた時の値になります。
    (train.pyは最後に更新した重みで出力させています。)

    Q.2
    そのような理解で合っています。
    厳密には、for label in a_list:複数のデータが入っているファイルを読み込み、
    学習したい(している)と思っています。

    Q.3
    もしかしたら、そこが問題になっているかもしれないです。
    同じ学習結果に保存するのではなく、
    seedと設定ファイルごとに保存しなければならないかもしれません。

    全体的にやりたい事としては、ざっくりですが、
    train.pyでの出力結果に対して、
    test.pyでも同様に復元したいということになります。

    キャンセル

回答 1

checkベストアンサー

+1

手元にデータがないので確証はありませんが、以下のことが考えられます。

Q.1
train_errorの値はtrain.pyとtest.pyで同じデータを読み込ませた時の値になります。
(train.pyは最後に更新した重みで出力させています。)

Script 出力値 出力値の元
train.py train_error  '(略)/in5_ver3/(略)','(略)/in5/4km/(略)','(略)/in5/2km/(略)'
test.py test_error  '(略)/in5/5km/(略)'

当たり前といえば当たり前かもしれませんが、train.pytest.pyとで中身が異なっていますので、計算結果が異なっているのは正しいこと(思い通り動いている)ではないでしょうか?
もし、testの方だけスコアがやけに悪いようであれば過学習が疑われます。

Q.2
そのような理解で合っています。
厳密には、for label in a_list:複数のデータが入っているファイルを読み込み、
学習したい(している)と思っています。

これは、一行ずつ処理するとオーバーヘッドするのかな、と思い確認しただけの質問でした。

Q.3
もしかしたら、そこが問題になっているかもしれないです。
同じ学習結果に保存するのではなく、
seedと設定ファイルごとに保存しなければならないかもしれません。

1)ある設定値のみに特化した回答
本題とは異なる回答かもしれませんが、学習時に同じ内容であってもシャッフルさせて学習させた方がスコアがあがります。A->B->C->Dと常に学習させるより、A->D->B->Cのような風にすると効果が出ます。

2)複数の設定値についての回答
もし、設定値同士に何らかの関係がある場合は一緒の方がよいかもしれません。
例えば画像を学習させるとして、以下の設定であれば共用させた方が良いような気はします。
設定1:25m先の象
設定2:15m先の象
設定3:10m先の象

もし、これが全く異なるもの(象の画像、人の音声、センサーの出す信号)であれば分けた方が良さそうです。やってみて比べるしかない話かもしれません。適当に何ステップか学習させて様子を見てはいかがでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/11/02 15:15

    回答ありがとうございます。
    様子を見てみたいと思います。

    ちなみにですが、tain.pyとtest.pyの処理を同時に行うファイルを作り、そこでのtest_errorとtest.pyのtest_errorの結果が異なりました。
    私自身としては、ここのtest_errorを一致させたいと考えています。
    これについて何か分かることはありますでしょうか?

    キャンセル

  • 2019/11/04 02:07

    > そこでのtest_errorとtest.pyのtest_error
    test_errorはtest.pyにしかないようですが、1つ目のtest_errorはどこに由来しますか?

    キャンセル

  • 2019/11/04 10:35

    1つ目のtest_errorは#検証データの後の処理後にコードを付け加えて、計算しました。このとき、テストデータをdef processの冒頭で新しく読み込んでいます。

    (追記でコードを書こうと思いましたが字数制限でかけませんでした。。。)

    キャンセル

  • 2019/11/04 16:36

    python_train.pyの中のmain()の中で何回かprocessが呼ばれており、この中で都度、test_error = process(label, '../../../../../../../text/in5/5km/point/rev/')のようなコードが挟まれているということでしょうか?ここに原因がありそうな気がします。
    分割するか該当部分の画像化など、何らかの方法で完全なコードが表示する必要がありそうです。

    キャンセル

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

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

関連した質問

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