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

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

新規登録して質問してみよう
ただいま回答率
87.20%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

受付中

TensorFlowでモデルを保存して復元できない

donafudo
donafudo

総合スコア0

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1回答

0評価

0クリップ

3601閲覧

投稿2018/08/05 08:01

###問題
本を参考にしながらRNNで言語モデルを作って、いざ文章を生成しようとすると、
トレーニングと生成を同時に実行するとそれらしい文章が出来るが、
トレーニングと生成を別々に実行すると、ちゃんとrestoreされていないのか、でたらめな文章が生成される。

saver.save()で保存されたファイルは以下の4つ
checkpoint
language-model.ckpt.data-00000-of-00001
language-model.ckpt.index
language-model.ckpt.meta

tensorflowのあるバージョンからはmetaファイルが生成されるので
self.saver = tf.train.import_meta_graph(os.path.join(ckpt_dir, 'language-model.ckpt.meta'))
が必要という情報があったので試してみても結果は変わらず、
エラーも特に出ていないので手詰まり状態です。
下記のコードに問題があるところはありますでしょうか?

#####環境
OS:macOS High Sierra 10.13.6
tensorflow 1.9.0
Pyton3.6

python

import numpy as np # テキストを読み込んで処理 with open('wordDataSet', 'r', encoding='utf-8')as f: text = f.read() text = text[:] chars = set(text) char2int = {ch: i for i, ch in enumerate(chars)} int2char = dict(enumerate(chars)) text_ints = np.array([char2int[ch] for ch in text], dtype=np.int32) def reshape_data(sequence, batch_size, num_steps): tot_batch_length = batch_size * num_steps num_batches = int(len(sequence) / tot_batch_length) print(len(sequence)) if num_batches * tot_batch_length + 1 > len(sequence): num_batches = num_batches - 1 # シーケンスの最後の部分から完全なバッチにならない半端な文字を削除 x = sequence[0:num_batches * tot_batch_length] y = sequence[1:num_batches * tot_batch_length + 1] # xとyをシーケンスのバッチのリストに分割 x_batch_splits = np.split(x, batch_size) y_batch_splits = np.split(y, batch_size) # それらのバッチを結合 # batch_size×tot_batch_length x = np.stack(x_batch_splits) y = np.stack(y_batch_splits) return x, y def create_batch_generator(data_x, data_y, num_steps): batch_size, tot_batch_length = data_x.shape num_batches = int(tot_batch_length / num_steps) for b in range(num_batches): yield (data_x[:, b * num_steps:(b + 1) * num_steps], data_y[:, b * num_steps:(b + 1) * num_steps]) def get_top_char(probas, char_size, top_n=2): p = np.squeeze(probas) p[np.argsort(p)[:-top_n]] = 0.0 p = p / np.sum(p) ch_id = np.random.choice(char_size, 1, p=p)[0] return ch_id import tensorflow as tf import os class CharRNN(object): def __init__(self, num_classes, batch_size=64, num_steps=100, lstm_size=128, num_layers=1, learning_rate=0.001, keep_prob=0.5, grad_clip=5, sampling=False): self.num_classes = num_classes self.batch_size = batch_size self.num_steps = num_steps self.lstm_size = lstm_size self.num_layers = num_layers self.learning_rate = learning_rate self.keep_prob = keep_prob self.grad_clip = grad_clip self.g = tf.Graph() with self.g.as_default(): tf.set_random_seed(123) self.build(sampling=sampling) self.saver = tf.train.Saver(max_to_keep=2) self.init_op = tf.global_variables_initializer() def build(self, sampling): if sampling == True: batch_size, num_steps = 1, 1 else: batch_size = self.batch_size num_steps = self.num_steps tf_x = tf.placeholder(tf.int32, shape=[batch_size, num_steps], name='tf_x') tf_y = tf.placeholder(tf.int32, shape=[batch_size, num_steps], name='tf_y') tf_keepprob = tf.placeholder(tf.float32, name='tf_keepprob') # one-hotエンコーディングを適用 x_onehot = tf.one_hot(tf_x, depth=self.num_classes) y_onehot = tf.one_hot(tf_y, depth=self.num_classes) # 多層RNNのセルを構築 cells = tf.contrib.rnn.MultiRNNCell([tf.contrib.rnn.DropoutWrapper( tf.contrib.rnn.BasicLSTMCell(self.lstm_size), output_keep_prob=tf_keepprob) for _ in range(self.num_layers)]) # 初期状態を定義 self.initial_state = cells.zero_state(batch_size, tf.float32) # RNNで各シーケンスステップを実行 lstm_outputs, self.final_state = tf.nn.dynamic_rnn(cells, x_onehot, initial_state=self.initial_state) print(' << lstm_outputs >>', lstm_outputs) # 二次元テンソルに変形 seq_output_reshaped = tf.reshape(lstm_outputs, shape=[-1, self.lstm_size], name='seq_output_reshaped') # そう入力を取得 logits = tf.layers.dense(inputs=seq_output_reshaped, units=self.num_classes, activation=None, name='logits') # 次の文字バッチの確率を計算 proba = tf.nn.softmax(logits, name='probabilities') # コスト関数を定義 y_reshaped = tf.reshape(y_onehot, shape=[-1, self.num_classes], name='y_reshaped') cost = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_reshaped), name='cost') # 勾配発散問題を回避するための勾配刈り込み tvars = tf.trainable_variables() grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars), self.grad_clip) # オプティマイザを定義 optimizer = tf.train.AdamOptimizer(self.learning_rate) train_op = optimizer.apply_gradients(zip(grads, tvars), name='train_op') def train(self, train_x, train_y, num_epochs, ckpt_dir='./model/'): # チェックポイントディレクトリがまだ存在しない場合は作成 if not os.path.exists(ckpt_dir): os.mkdir(ckpt_dir) with tf.Session(graph=self.g) as sess: sess.run(self.init_op) n_batches = int(train_x.shape[1] / self.num_steps) iterations = n_batches * num_epochs for epoch in range(num_epochs): # ネットワークをトレーニング new_state = sess.run(self.initial_state) loss = 0 # ミニバッチジェネレータ bgen = create_batch_generator(train_x, train_y, self.num_steps) for b, (batch_x, batch_y) in enumerate(bgen, 1): iteration = epoch * n_batches + b feed = {'tf_x:0': batch_x, 'tf_y:0': batch_y, 'tf_keepprob:0': self.keep_prob, self.initial_state: new_state} batch_cost, _, new_state = sess.run( ['cost:0', 'train_op', self.final_state], feed_dict=feed) if iteration % 10 == 0: print('Epoch %d/%d iteration %d| Training loss: %.4f' % (epoch + 1, num_epochs, iteration, batch_cost)) # トレーニング済みのモデルを保存 self.saver.save(sess, os.path.join(ckpt_dir, 'language-model.ckpt')) def sample(self, output_length, ckpt_dir, starter_seq="電子書籍"): observed_seq = [ch for ch in starter_seq] with tf.Session(graph=self.g)as sess: self.saver = tf.train.import_meta_graph(os.path.join(ckpt_dir, 'language-model.ckpt.meta')) self.saver.restore(sess, tf.train.latest_checkpoint(ckpt_dir)) # 1: starter_seqを使ってモデルを実行 new_state = sess.run(self.initial_state) for ch in starter_seq: x = np.zeros((1, 1)) x[0, 0] = char2int[ch] feed = {'tf_x:0': x, 'tf_keepprob:0': 1.0, self.initial_state: new_state} proba, new_state = sess.run( ['probabilities:0', self.final_state], feed_dict=feed) ch_id = get_top_char(proba, len(chars)) observed_seq.append(int2char[ch_id]) # 2: 更新されたobserved_seqを使ってモデルを実行 for i in range(output_length): x[0, 0] = ch_id feed = {'tf_x:0': x, 'tf_keepprob:0': 1.0, self.initial_state: new_state} proba, new_state = sess.run( ['probabilities:0', self.final_state], feed_dict=feed) ch_id = get_top_char(proba, len(chars)) observed_seq.append(int2char[ch_id]) return ''.join(observed_seq) batch_size = 32 num_steps = 30 train_x, train_y = reshape_data(text_ints, batch_size, num_steps) # モデルのトレーニング rnn=CharRNN(num_classes=len(chars),batch_size=batch_size) rnn.train(train_x,train_y,num_epochs=1000,ckpt_dir='./model-100/') del rnn # 文章生成 np.random.seed(123) rnn = CharRNN(len(chars), sampling=True) print(rnn.sample(ckpt_dir='./model-100/', output_length=500,starter_seq='明日は'))

良い質問の評価を上げる

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

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

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

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

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

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

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

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

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

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。