49621


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は、てれかさんの  
[クリスマスにもなってカノジョがいないからカノジョを作ってみた。](http://nonbiri-
tereka.hatenablog.com/entry/2016/12/25/000348)  
を参考にいたしました。

原因がわかる方や、これはエラーでは？と思われる方がおられたら何卒ご教授お願いいたします。

追記:  
[No AutoEncoder in keras code??](https://github.com/keras-
team/keras/issues/2269)

poem.txtのデータ  
朝霧 の 中 に 九段 の ともし 哉  
あたたか な 雨 が 降る なり 枯葎  
菜の花 や は つと 明るき 町 は づれ  
秋風 や 伊予 へ 流る る 汐 の 音  
長閑 さ や 障子 の 穴 に 海 見え て

keras_AE.py

[code]

    # 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')
    
[/code]

slackbot_setting.py

[code]

    API_TOKEN = "YOUR API TOKEN"
    
[/code]

keras_test.py

[code]

    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()
    
[/code]


CC BY-SA 4.0
2018-10-24T10:47:07.417
49613
2018-10-24T13:03:37.293
2018-10-24T12:51:19.710
30516
30516
question
python 機械学習
pythonで変数が次のコードへ継承されません


Pythonではファイル間での変数の共有はできないので、1ファイルでまとめる、データを他の場所(jsonなど)に保管するなどの工夫がいります。


CC BY-SA 4.0
2018-10-24T13:03:37.293
49621
2018-10-24T13:03:37.293
29212
49613
answer