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

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

ただいまの
回答率

87.36%

Pytorch QRNN実装について pythonにおけるClassの書き方

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,447

score 25

https://github.com/salesforce/pytorch-qrnn
上記urlにて実装されたPytorchによるQRNNを学習させたく思い,
Pytorch tutorialのRNN word language modelである
https://github.com/pytorch/examples/tree/master/word_language_model
を参考に実装してみたのですが,

# At any point you can hit Ctrl + C to break out of training early.
epochs = 50
try:
    for epoch in range(1, epochs+1):
        epoch_start_time = time.time()
        train()
        val_loss = evaluate(val_data)
        print('-' * 89)
        print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | '
                'valid ppl {:8.2f}'.format(epoch, (time.time() - epoch_start_time),
                                           val_loss, math.exp(val_loss)))
        print('-' * 89)
        # Save the model if the validation loss is the best we've seen so far.
        if not best_val_loss or val_loss < best_val_loss:
            with open('model.pt', 'wb') as f:
                torch.save(model, f)
            best_val_loss = val_loss
        else:
            # Anneal the learning rate if no improvement has been seen in the validation dataset.
            lr /= 4.0
except KeyboardInterrupt:
    print('-' * 89)
    print('Exiting from training early')


にて,以下のエラーが排出されました.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-11-48e657d4a3b2> in <module>()
      4     for epoch in range(1, epochs+1):
      5         epoch_start_time = time.time()
----> 6         train()
      7         val_loss = evaluate(val_data)
      8         print('-' * 89)

<ipython-input-10-04629ba4da48> in train()
     47     start_time = time.time()
     48     ntokens = len(corpus.dictionary)
---> 49     hidden = model.init_hidden(batch_size)
     50     for batch, i in enumerate(range(0, train_data.size(0) - 1, bptt)):
     51         data, targets = get_batch(train_data, i)

<ipython-input-5-29d356b3a836> in init_hidden(self, bsz)
     21     def init_hidden(self, bsz):
     22         weight = next(self.parameters())
---> 23         return weight.new_zeros(self.layers, bsz, self.hidden_size)
     24 
     25     def init_weights(self):

~/anaconda3/envs/pytorch-py3.6/lib/python3.6/site-packages/torch/nn/modules/module.py in __getattr__(self, name)
    533                 return modules[name]
    534         raise AttributeError("'{}' object has no attribute '{}'".format(
--> 535             type(self).__name__, name))
    536 
    537     def __setattr__(self, name, value):

AttributeError: 'QRNNModel' object has no attribute 'layers'


エラーを起こしているのは,

def train():
    # Turn on training mode which enables dropout.
    model.train()
    total_loss = 0.
    start_time = time.time()
    ntokens = len(corpus.dictionary)
    hidden = model.init_hidden(batch_size)
    for batch, i in enumerate(range(0, train_data.size(0) - 1, bptt)):
        data, targets = get_batch(train_data, i)
        # Starting each batch, we detach the hidden state from how it was previously produced.
        # If we didn't, the model would try backpropagating all the way to start of the dataset.
        hidden = repackage_hidden(hidden)
        model.zero_grad()
        output, hidden = model(data, hidden)
        loss = criterion(output.view(-1, ntokens), targets)
        loss.backward()

        # `clip_grad_norm` helps prevent the exploding gradient problem in RNNs / LSTMs.
        torch.nn.utils.clip_grad_norm_(model.parameters(), clip)
        for p in model.parameters():
            p.data.add_(-lr, p.grad.data)

        total_loss += loss.item()

        if batch % log_interval == 0 and batch > 0:
            cur_loss = total_loss / log_interval
            elapsed = time.time() - start_time
            print('| epoch {:3d} | {:5d}/{:5d} batches | lr {:02.2f} | ms/batch {:5.2f} | '
                    'loss {:5.2f} | ppl {:8.2f}'.format(
                epoch, batch, len(train_data) // bptt, lr,
                elapsed * 1000 / log_interval, cur_loss, math.exp(cur_loss)))
            total_loss = 0
            start_time = time.time()



hidden = model.init_hidden(batch_size)
の部分であり,modelは

nhid=256
nlayers=2
dropout=0.5
nvocab = 35 # 最大35単語までのシーケンスを扱う

ntokens = len(corpus.dictionary)
model = QRNNModel(hidden_size=nhid, layers=nlayers, 
                  vocab=nvocab, dropout=0.5, parallel=True)
model = model.to(device)


で定義しているので,QRNNModelを見ると

class QRNNModel(nn.Module):

    def __init__(self, hidden_size=1024, parallel=True, layers=3, dropout=0.5, vocab=100):
        super().__init__()

        self.embedding = nn.Embedding(vocab, hidden_size)

        from torchqrnn import QRNN
        self.rnn = QRNN(input_size=hidden_size, hidden_size=hidden_size, 
                        num_layers=layers, dropout=0.5)
        #self.rnn = nn.LSTM(hidden_size, hidden_size)
        # Note: we tell DataParallel to split on the second dimension as RNNs are batch second by default in PyTorch
        if parallel: self.rnn = nn.DataParallel(self.rnn, dim=1)

    def forward(self, x):
        x = self.embedding(x)
        out, hidden = self.rnn(x)
        return out[:-1]

    def init_hidden(self, bsz):
        weight = next(self.parameters())
        return weight.new_zeros(self.layers, bsz, self.hidden_size)

    def init_weights(self):
        initrange = 0.1
        self.encoder.weight.data.uniform_(-initrange, initrange)
        self.decoder.bias.data.zero_()
        self.decoder.weight.data.uniform_(-initrange, initrange)


このクラス内の,

def __init__(self, hidden_size=1024, parallel=True, layers=3, dropout=0.5, vocab=100):
        super().__init__()


の箇所にてエラーで指摘された

AttributeError: 'QRNNModel' object has no attribute 'layers'


layersを入れているのでクリアしていると思ったのですが,できていないようです.

なぜなのかお教えいただけないでしょうか.
よろしくお願いいたします.

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

layersを入れているのでクリアしていると思ったのですが,できていないようです.

なぜなのかお教えいただけないでしょうか.

layers__init__の仮引数として名前が書かれているのと、self.rnn = QRNN(...)のコンストラクタに渡されているだけで、QRNNModelのインスタンスselfの属性に代入されてはいないからです。__init__の仮引数はインスタンス変数の定義などではありません。

__init__の中にself.layers = layersとでも書いておけばそのエラーだけは解消すると思います。ただしPytorchはまったく知らないので、正しい対処なのかどうかは私にはわかりません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/20 21:43

    ありがとうございます.
    大きな勘違いをしておりました.

    おかげさまで先ほどのエラーはなくなりました.
    ありがとうございました.

    キャンセル

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

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

関連した質問

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