pythonで変数が次のコードへ継承されません
autoencoderで文章を学習したモデルをslackbotでテストしたいと考えています。
しかしながら、
Using TensorFlow backend.
Traceback (most recent call last):
File "/home/yudai/Desktop/keras_test.py", line 19, in
model = ae(len(word2id))
NameError: name 'ae' is not defined
keras_AE.pyで学習は可能ですが、次のkeras_test.pyでaeが使えません。
slackbot_setting.pyのせいかと思いましたが、関係ないようです。
slackbotは、てれかさんの
クリスマスにもなってカノジョがいないからカノジョを作ってみた。
を参考にいたしました。
原因がわかる方や、これはエラーでは?と思われる方がおられたら何卒ご教授お願いいたします。
追記:
No AutoEncoder in keras code??
poem.txtのデータ
朝霧 の 中 に 九段 の ともし 哉
あたたか な 雨 が 降る なり 枯葎
菜の花 や は つと 明るき 町 は づれ
秋風 や 伊予 へ 流る る 汐 の 音
長閑 さ や 障子 の 穴 に 海 見え て
keras_AE.py
# coding:utf-8
import numpy as np
import codecs
from keras.layers import Activation, Dense, Input
from keras.models import Model
#データの読み込み
with open(r'/home/yudai/Desktop/poem.txt', encoding='utf-8') as f:
poems = f.read().splitlines()
text = poems[0] # 1個目のデータ
print(text)
# コーパスの長さ
print('corpus length:', len(text))
# 文字数を数えるため、textをソート
chars = sorted(list(set(text)))
# 全文字数の表示
print('total chars:', len(chars))
# 文字をID変換
char_indices = dict((c, i) for i, c in enumerate(chars))
# IDから文字へ変換
indices_char = dict((i, c) for i, c in enumerate(chars))
#テキストを17文字ずつ読み込む
maxlen = 17
#サンプルバッチ数
step = 3
sentences = []
next_chars = []
for i in range(0, len(text) - maxlen, step):
sentences.append(text[i: i + maxlen])
next_chars.append(text[i + maxlen])
#学習する文字数を表示
print('Sequences:', sentences)
print('next_chars:', next_chars)
#ベクトル化する
print('Vectorization...')
x = np.zeros((len(sentences), maxlen, len(chars)),
dtype=np.bool)
y = np.zeros((len(sentences), len(chars)),
dtype=np.bool)
for i, sentence in enumerate(sentences):
for t, char in enumerate(sentence):
x[i, t, char_indices[char]] = 1
y[i, char_indices[next_chars[i]]] = 1
#モデルを構築する工程に入る
print('Build model...')
#encoderの次元
encoding_dim = 128
#入力用の変数
input_word = Input(shape=(maxlen, len(chars)))
#入力された語がencodeされたものを格納する
encoded = Dense(128, activation='relu')(input_word)
encoded = Dense(64, activation='relu')(encoded)
encoded = Dense(32, activation='relu')(encoded)
#潜在変数(実質的な主成分分析)
latent = Dense(8, activation='relu')(encoded)
#encodeされたデータを再構成
decoded = Dense(32, activation='relu')(latent)
decoded = Dense(64, activation='relu')(decoded)
decoded = Dense(12, activation='relu')(encoded)
ae = Model(input=input_word, output=decoded)
#Adamで最適化、loss関数をcategorical_crossentropy
ae.compile(optimizer='Adam',
loss='categorical_crossentropy')
ae.summary()
print(x.shape)
#autoencoderの実行
ae.fit(x, x,
epochs=500,
batch_size=256,
shuffle=False)
#モデルの構造を保存
model_json = ae.to_json()
with open('keras_AE.json', 'w') as json_file:
json_file.write(model_json)
#学習済みモデルの重みを保存
ae.save_weights('AE.h5')
slackbot_setting.py
API_TOKEN = "YOUR API TOKEN"
keras_test.py
from keras.models import Sequential
from keras.layers import Dense
from keras.models import model_from_json
import json
from collections import OrderedDict
import MeCab
import codecs
from slackbot.bot import default_reply
from slackbot.bot import Bot
import numpy
import os
import io, sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
tagger = MeCab.Tagger('mecabrc')
#モデルの構造を読む
id2word = json.load(open('keras_AE.json', 'r'))
id2word = {int(key): value for key, value in id2word.items()}
word2id
id2word.close()
#モデルをロードする
loaded_model = model_from json(id2word)
#重みを適用する
loded_model.load_weights('AE.h5')
model.train = False
@default_reply
def replay_message(message):
parsed_sentence = []
try:
for chunk in tagger.parse(message.body["text"].encode("utf-8")).splitlines()[:-1]:
(surface, feature) = chunk.decode("utf-8").split('\t')
parsed_sentence.append(surface)
parsed_sentence = ["<start>"] + parsed_sentence + ["<eos>"]
ids = []
for word in parsed_sentence:
if word in word2id:
id = word2id[word]
ids.append(id)
else:
ids.append(0)
ids_question = ids
sentence = "".join(model.generate_sentence(ids_question, dictionary=id2word)).encode("utf-8")
sentence = sentence.replace("◯", "")
message.reply(sentence)
except Exception as e:
print (e)
message.reply("解析できなかったのでもう一度おねがいします。")
def main():
bot = Bot()
bot.run()
if __name__ == "__main__":
main()