93350


PyTorchのまだ初心者ですが、NLPのシンプルなRNN構築を目指しております。  
CPUでは動くのですが、デバイスをGPUにするとCPU、GPUの混在エラーが解消できません。  
hidden層あたりが原因と考えてるのですが、どうやっても解消できず。  
どなたか助言をいただけますと助かります。

# RNNクラス

[code]

    class RNN(nn.Module):
      def __init__(self, vocab_size, emb_size, hidden_size, output_size):
        super().__init__()
        self.hidden_size = hidden_size
        self.emb = nn.Embedding(vocab_size, emb_size)
        self.rnn = nn.RNN(emb_size, hidden_size, nonlinearity='tanh', batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)
    
      def forward(self, x):
        self.batch_size = x.size()[0]
        hidden = self.init_hidden()
        emb = self.emb(x)
        out, hidden = self.rnn(emb, hidden)
        out = self.fc(out[:, -1, :])
        return out
    
      def init_hidden(self):
        hidden = torch.zeros(1, self.batch_size, self.hidden_size)
        return hidden
    
[/code]

上記で、  
self.to(device)  
hidden = torch.zeros(1, self.batch_size, self.hidden_size).to(device)  
などとしてみましたが、エラーが解消できません。

# device

[code]

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    
[/code]

# 変数

[code]

    VOCAB_SIZE = len(word_id.keys()) +1
    EMB_SIZE = 300
    OUTPUT_SIZE = 4
    HIDDEN_SIZE = 50
    model = RNN(VOCAB_SIZE,EMB_SIZE, HIDDEN_SIZE, OUTPUT_SIZE)
    model = model.to(device)
    
[/code]

# 予測

[code]

    for i in range(10):
      # datasetet　の、リスト０indexに入力要素
      X, y = dataset_train[i]
      X = X.to(device)
      print(torch.softmax(model(X.unsqueeze(0)), dim=1))
    
[/code]

上記のコードは、CPUでは動きましたが、to(device)で、modelとデータを送ったところ、CPUとGPUの混在エラーが出てしまいます。

# エラーメッセージ

[code]

    Input and hidden tensors are not at the same device, found input tensor at cuda:0 and hidden tensor at cpu
    
[/code]

原因となる箇所を、ご指摘いただけますと幸甚です。


CC BY-SA 4.0
2022-10-09T04:08:39.693
91502
2023-01-15T06:17:12.887
2022-10-09T04:55:53.933
3060
54705
question
python google-colaboratory pytorch
PyTorchでのNLP_RNNにて、CPU GPU混在エラー


時間も経過しており既に解決済みかもしれませんが，Google Colab (python 3.8.16, torch 1.13.0+cu116)
を使って下記の記述例で確認する限りでは

[code]

            # hidden = torch.zeros(1, self.batch_size, self.hidden_size)
            hidden = torch.zeros(1, self.batch_size, self.hidden_size).to(device)
    
[/code]

の変更でエラーは発生しなくなりました。なお，`train.txt`
は[【python】言語処理100本ノック2020を解く(第9章前半)](https://mori-
memo.hateblo.jp/entry/2022/10/16/173011) を基に作らせていただきました。

[code]

    import pandas as pd
    from collections import Counter
    import torch
    from torch import nn
    
    
    class RNN(nn.Module):
        def __init__(self, vocab_size, emb_size, hidden_size, output_size):
            super().__init__()
            self.hidden_size = hidden_size
            self.emb = nn.Embedding(vocab_size, emb_size)
            self.rnn = nn.RNN(emb_size, hidden_size, nonlinearity='tanh',
                              batch_first=True)
            self.fc = nn.Linear(hidden_size, output_size)
    
        def forward(self, x):
            self.batch_size = x.size()[0]
            hidden = self.init_hidden()
            emb = self.emb(x)
            out, hidden = self.rnn(emb, hidden)
            out = self.fc(out[:, -1, :])
            return out
    
        def init_hidden(self):
            # hidden = torch.zeros(1, self.batch_size, self.hidden_size)
            hidden = torch.zeros(1, self.batch_size, self.hidden_size).to(device)
            return hidden
    
    def tokenizer(txt):
        ws = txt.rstrip().split()
        return [word_id.get(w, 0) for w in ws]
    
    
    # device
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    
    # read data
    train = pd.read_csv('train.txt', sep='\t')
    
    # dictionary for tokenizer()
    words = []
    for text in train['TITLE']:
        for word in text.rstrip().split():
            words.append(word)
    c = Counter(words)
    word_id = {}
    for i, cnt in enumerate(c.most_common()):
        if cnt[1] > 1:
            word_id[cnt[0]] = i + 1
    
    # dataset_train
    train['TTL'] = train['TITLE'].apply(tokenizer)
    train['CAT'] = train['CATEGORY'].map({'b': 0, 't': 1, 'e': 2, 'm': 3})
    dataset_train = []
    for i in train.index:
        dataset_train.append(
            [torch.tensor(train.loc[i, 'TTL'], dtype=torch.int),
             torch.tensor(train.loc[i, 'CAT'], dtype=torch.int)])
    
    # model
    VOCAB_SIZE = len(word_id.keys()) + 1
    EMB_SIZE = 300
    OUTPUT_SIZE = 4
    HIDDEN_SIZE = 50
    model = RNN(VOCAB_SIZE, EMB_SIZE, HIDDEN_SIZE, OUTPUT_SIZE).to(device)
    
    # initial prediction
    for i in range(5):
        X, y = dataset_train[i]
        X = X.to(device)
        print(torch.softmax(model(X.unsqueeze(0)), dim=1))
    
[/code]

[code]

    tensor([[0.2418, 0.2491, 0.3167, 0.1924]], device='cuda:0',
           grad_fn=<SoftmaxBackward0>)
    tensor([[0.3865, 0.1211, 0.3834, 0.1089]], device='cuda:0',
           grad_fn=<SoftmaxBackward0>)
    tensor([[0.1702, 0.3075, 0.3873, 0.1349]], device='cuda:0',
           grad_fn=<SoftmaxBackward0>)
    tensor([[0.3631, 0.1873, 0.1873, 0.2623]], device='cuda:0',
           grad_fn=<SoftmaxBackward0>)
    tensor([[0.3344, 0.2631, 0.2306, 0.1719]], device='cuda:0',
           grad_fn=<SoftmaxBackward0>)
    
[/code]


CC BY-SA 4.0
2023-01-15T06:17:12.887
93350
2023-01-15T06:17:12.887
54588
91502
answer