74482


僕はまだPythonをはじめたばかりなのですが、[こちらのサイト](http://cedro3.com/ai/keras-lstm-text-
word/)を参考にして、文章(小説)を生成したいと思っています。すでに文章生成の元となるテキストファイルは作成しています(ファイル名…kokoro2.txt)。  
そこで、以下のコードを実行すると、

[code]

    from __future__ import print_function
    from keras.callbacks import LambdaCallback
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.layers import LSTM
    from keras.optimizers import RMSprop
    !pip install janome
    from janome.tokenizer import Tokenizer  # 追加
    import numpy as np
    import random
    import sys
    import io
    
    path = 'kokoro2.txt'
    with io.open(path, encoding='utf-8') as f:
        text = f.read().lower()
    print('corpus length:', len(text))
    
    #chars = sorted(list(set(text)))
    #print('total chars:', len(chars))
    #char_indices = dict((c, i) for i, c in enumerate(chars))
    #indices_char = dict((i, c) for i, c in enumerate(chars))
    
    text =Tokenizer().tokenize(text, wakati=True)  # 分かち書きする
    chars = text
    count = 0
    char_indices = {}  # 辞書初期化
    indices_char = {}  # 逆引き辞書初期化
    
    for word in chars:
        if not word in char_indices:  # 未登録なら
           char_indices[word] = count  # 登録する      
           count +=1
           print(count,word)  # 登録した単語を表示
    # 逆引き辞書を辞書から作成する
    indices_char = dict([(value, key) for (key, value) in char_indices.items()])
    
    # cut the text in semi-redundant sequences of maxlen characters
    maxlen = 5
    step = 1
    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('nb sequences:', len(sentences))
    
[/code]

以下のように、単語が出力された後、エラーが出てしまいました。

[code]

    ストリーミング出力は最後の 5000 行に切り捨てられました。
    1634 勉強
    1635 仕事
    1636 なさら
    (中略)
    6630 善悪
    6631 供する
    6632 保存
    6633 秘密
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-68-af900f3e4410> in <module>()
         41 sentences = []
         42 next_chars = []
    ---> 43 for i in range(0, len(text) - maxlen, step):
         44     sentences.append(text[i: i + maxlen])
         45     next_chars.append(text[i + maxlen])
    
    TypeError: object of type 'generator' has no len()
    
[/code]

自分でも調べて、`text =
list(text)`を、エラーが出た43行目の上に追加してみたところ、エラーは出なくなったのですが、(以下のように出力されました)

[code]

    ストリーミング出力は最後の 5000 行に切り捨てられました。
    1635 仕事
    1636 なさら
    1637 あの
    (中略)
    6631 供する
    6632 保存
    6633 秘密
    nb sequences: 0
    
[/code]

nb sequences: 0 と表示されてしまい、先程のコードに続くコードを実行すると、

[code]

    def on_epoch_end(epoch, _):
        # Function invoked at end of each epoch. Prints generated text.
        print()
        print('----- Generating text after Epoch: %d' % epoch)
    
        start_index = random.randint(0, len(text) - maxlen - 1)
        start_index = 0  # テキストの最初からスタート
        for diversity in [0.2]:  # diversity は 0.2のみ使用 
            print('----- diversity:', diversity)
    
            generated = ''
            sentence = text[start_index: start_index + maxlen]
            # sentence はリストなので文字列へ変換して使用
            generated += "".join(sentence)
            print(sentence)
            
            # sentence はリストなので文字列へ変換して使用
            print('----- Generating with seed: "' + "".join(sentence)+ '"')
            sys.stdout.write(generated)
    
    
            for i in range(400):
                x_pred = np.zeros((1, maxlen, len(chars)))
                for t, char in enumerate(sentence):
                    x_pred[0, t, char_indices[char]] = 1.
    
                preds = model.predict(x_pred, verbose=0)[0]
                next_index = sample(preds, diversity)
                next_char = indices_char[next_index]
    
                generated += next_char
                sentence = sentence[1:]
                # sentence はリストなので append で結合する
                sentence.append(next_char)  
    
                sys.stdout.write(next_char)
                sys.stdout.flush()
            print()
    
    print_callback = LambdaCallback(on_epoch_end=on_epoch_end)
    
    model.fit(x, y,
              batch_size=128,
              epochs=60,
              callbacks=[print_callback])
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-72-d09b1cbd7b9a> in <module>()
         40 print_callback = LambdaCallback(on_epoch_end=on_epoch_end)
         41 
    ---> 42 model.fit(x, y,
         43           batch_size=128,
         44           epochs=60,
    
    NameError: name 'model' is not defined
    
[/code]

とのエラーが出てしまいます。  
Google Colaboratory を使用していて、主にiPadからコーディングしています(Androidスマートフォンからも時々やります)。  
どうすれば解決できるのか分かりません。  
宜しくお願い致します。


CC BY-SA 4.0
2021-02-27T06:51:21.187
74296
2021-03-07T06:23:29.083
44132
question
python tensorflow keras google-colaboratory
TypeError: object of type 'generator' has no len() について


@metropolis さんのコメントで解決しましたので、コメント部分をコピーし、回答として載せさせていただきます。  
(以下引用)

元記事のコードには

[code]

    from __future__ import print_function 
    
[/code]

がありますので、Python2で実行しているものと思われます。そのため、text 変数はリスト型のインスタンスになります。一方、user15291523
(現在Y.y にユーザー名変更)さんのコードはおそらく Python3 で実行されていて、text 変数は(エラーメッセージの通り) generator
になります。そこで、generator をリストに変換するとよろしいかと思います。

[code]

    text = list(Tokenizer().tokenize(text, wakati=True))
    
[/code]

`Tokenizer().tokenize(text, wakati=True)` の部分を `list()`
で囲んでいます。分かりづらい場合は、`text =Tokenizer().tokenize(text, wakati=True)` の次の行に `text
= list(text)` を追加してみて下さい。

質問欄のコードには元記事のソースコードの `print('Vectorization...')` から
`model.compile(loss='categorical_crossentropy', optimizer=optimizer)`
までの部分がありませんが、この部分を Colaboratory で実行しましたか？(`model` の定義部分になります)


CC BY-SA 4.0
2021-03-07T06:23:29.083
74482
2021-03-07T06:23:29.083
44132
74296
answer