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

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

ただいまの
回答率

88.92%

pythonでの機械学習時のエラー

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 211

akamini

score 10

【Python】Pytorchのモデル保存・読み込みをもっと簡単にしたい!
PyTorchで訓練されたモデルを保存するための最良の方法は?
上記のサイトを参考にpytorchのモデルの保存・読み込みのコードを書いて実行し、保存した重みを使って読み込みをしようとしたところ下記のようなエラーが出て実行できません。対処法を教えていただきたいです。

(base) xxxxxxx python % /opt/anaconda3/bin/python /Users/xxxxxx/Downloads/python/pytourch_study/weights/sumple_cnn.py
test
Traceback (most recent call last):
  File "/Users/xxxxxx/Downloads/python/pytourch_study/weights/sumple_cnn.py", line 98, in <module>
    model.load_state_dict(torch.load("weights/weights_2.pth"))
  File "/opt/anaconda3/lib/python3.7/site-packages/torch/serialization.py", line 584, in load
    with _open_file_like(f, 'rb') as opened_file:
  File "/opt/anaconda3/lib/python3.7/site-packages/torch/serialization.py", line 234, in _open_file_like
    return _open_file(name_or_buffer, mode)
  File "/opt/anaconda3/lib/python3.7/site-packages/torch/serialization.py", line 215, in __init__
    super(_open_file, self).__init__(open(name, mode))
FileNotFoundError: [Errno 2] No such file or directory: 'weights/weights_2.pth'

階層は下記です。
イメージ説明
書いたコードは下記に示してあります。重みを使用する際にはtrainのところをコメントアウトして実行を試そうと思っているのですが、うまくいきません。

環境は
vs code
python3.7.6 
tensorflow1.14.0
です。

import torch
from torchvision.datasets import MNIST
from torchvision import transforms
from torch.utils.data import DataLoader
from torch import nn
import cloudpickle


class cnn(nn.Module):
    def __init__(self):
        super().__init__()
        self.layers = nn.Sequential(
            nn.Conv2d(1, 6, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2),
            nn.Conv2d(6, 16, kernel_size=5),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(16*5*5, 120),
            nn.ReLU(inplace=True),
            nn.Linear(120, 84),
            nn.ReLU(inplace=True),
            nn.Linear(84, 10),
            nn.Softmax(dim=1),
        )

        # weight init
        for m in self.layers.children():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
            if isinstance(m, nn.Linear):
                nn.init.kaiming_normal_(m.weight)

    def forward(self, x):
        return self.layers(x)


if __name__ == '__main__':

    # GPU or CPUの自動判別
    device = 'cuda' if torch.cuda.is_available() else 'cpu'

    # modelの定義
    model = cnn().to(device)
    opt = torch.optim.Adam(model.parameters())

    # datasetの読み出し
    bs = 128  # batch size
    transform = transforms.Compose([transforms.ToTensor(),
                                    transforms.Normalize((0.5,), (0.5,))])

    trainset = MNIST(root='./data', train=True,
                     download=True, transform=transform)
    trainloader = DataLoader(trainset, batch_size=bs, shuffle=True)

    testset = MNIST(root='./data', train=False,
                    download=True, transform=transform)
    testloader = DataLoader(testset, batch_size=bs, shuffle=False)

    #   training
    print('train')
    model = model.train()
    for iepoch in range(3):
      for iiter, (x, y) in enumerate(trainloader, 0):

        # toGPU (CPUの場合はtoCPU)
            x = x.to(device)
            y = torch.eye(10)[y].to(device)

            # 推定
            y_ = model.forward(x)
            # y_.shape = (bs, 84)

            # loss: cross-entropy
            eps = 1e-7
            loss = -torch.mean(y*torch.log(y_+eps))

            opt.zero_grad()  # 勾配初期化
            loss.backward()  # backward (勾配計算)
            opt.step()  # パラメータの微小移動

            # 100回に1回進捗を表示(なくてもよい)
            if iiter % 100 == 0:
                print('%03d epoch, %05d, loss=%.5f' %
                      (iepoch, iiter, loss.item()))

            if iepoch % 2 == 0:
                torch.save(model.state_dict(),
                           "weights_{}.pth".format(iepoch))

    torch.save(model.state_dict(), PATH)

    # test
    print('test')
    total, tp = 0, 0

    model.load_state_dict(torch.load("weights/weights_2.pth"))
    model.eval()
    # the_model = TheModelClass(*args, **kwargs)
    # model.load_state_dict(torch.load(PATH))
    for (x, label) in testloader:

        # to GPU
        x = x.to(device)

        # 推定
        y_ = model.forward(x)
        label_ = y_.argmax(1).to('cpu')

        # 結果集計
        total += label.shape[0]
        tp += (label_ == label).sum().item()
    acc = tp/total
    print('test accuracy = %.3f' % acc)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • can110

    2020/07/06 23:17

    提示コードのどの行でエラーが発生したか分かるようにエラーは全文(Traceback)を提示ください。

    キャンセル

  • akamini

    2020/07/06 23:20

    エラー文全文を編集いたしました。

    キャンセル

回答 1

checkベストアンサー

0

保存しているパスが "weights_{}.pth" で、読み込もうとしているパスが "weights/weights_2.pth" なので、保存先と読み込み先のパスが合致していません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/07 18:12

    ls の結果に weights ディレクトリはないように見えますが、消したのですか?

    キャンセル

  • 2020/07/07 18:15

    画像をよくみたら、pytourch_study ディレクトリの中に weights ディレクトリがあるように見えますが、sumple_cnn.py などがある1つ上の階層にあるべきではないですか?

    キャンセル

  • 2020/07/07 18:29

    完全にweightsのディレクトリの作成場所が間違っていました。ひとつ上に移動させ一から学習とその重みを使用して読み込みまで行ったところ無事に成功することができました。
    結果として初歩的なミスではありましたが、ありがとうございました。

    キャンセル

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

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

関連した質問

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