Pytorch 학습된 모델로 식별 [MNIST]

처음에


  • Pytorch에서 CNN을 구축하고 MNIST 데이터 세트를 학습했습니다.
  • 학습한 모델을 읽어 사용하는 프로그램을 짜냈다. (의외로 기사 적었다)
  • 모델의 작성은 이전 기사로 했으므로 좋으면 꼭. ( 여기 참조)

  • <대상>
    - 기계 학습 초보자(세세한 내용에 대한 해설은 하지 않습니다)
    - PyTorch 만지기 시작한 분
    - 아바웃한 해설에서도 견딜 수 있는 분
    <비대상>
    - Pytorch 자세한 내용
    - 정밀도 향상하고 싶은 분

    [환경]
    파이썬 3.6.9
    torch 1.6.0
    numpy 1.16.4
    Pillow 6.2.0

    모델 저장


    PATH = "./my_mnist_model.pt"
    torch.save(net.state_dict(), PATH)
    

    학습된 모델을 저장합니다.torch.save() 의 인수를 net.state_dict() 로 함으로써 네트워크 구조나 각 레이어의 인수를 생략하고 보존한다. 이것에 의해 보존한 모델의 용량을 삭감할 수 있는 것 같다.
    반대로, 모델을 로드하는 측은 네트워크 구조를 기술할 필요가 있다.

    모델 활용


    import torch
    import torch.nn as nn
    import torch.nn.functional as f
    import torchvision
    from torchvision import datasets, transforms
    from PIL import Image, ImageOps
    from torchsummary import summary
    
    # モデルの定義
    class MyNet(nn.Module):
        def __init__(self):
            super(MyNet,self).__init__()
            self.conv1 = nn.Conv2d(1,32,3,1)
            self.conv2 = nn.Conv2d(32,64,3,1)
            self.pool = nn.MaxPool2d(2,2)
            self.dropout1 = nn.Dropout2d(0.25)
            self.dropout2 = nn.Dropout2d(0.5)
            self.fc1 = nn.Linear(12*12*64,128)
            self.fc2 = nn.Linear(128,10)
    
        def forward(self,x):
            x = self.conv1(x)
            x = f.relu(x)
            x = self.conv2(x)
            x = f.relu(x)
            x = self.pool(x)
            x = self.dropout1(x)
            x = x.view(-1,12*12*64)
            x = self.fc1(x)
            x = f.relu(x)
            x = self.dropout2(x)
            x = self.fc2(x)
    
            return f.log_softmax(x, dim=1)
    
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = 0
    model = MyNet().to(device)
    print(device)
    print(model)
    print(summary(model, (1, 28, 28)))
    
    # 学習モデルをロードする
    model.load_state_dict(torch.load("my_mnist_model.pt", map_location=lambda storage, loc: storage))
    model = model.eval()
    
    # 画像ファイルを読み込む(黒背景, 白文字を想定)
    PATH = "mnist/3.jpg"
    image = Image.open(PATH)
    image = ImageOps.invert(image)
    image = image.convert('L').resize((28,28))
    # データの前処理の定義(モデル生成の際と同じ平均値と標準偏差で正規化する)
    transform = transforms.Compose([
                                    transforms.ToTensor(),
                                    transforms.Normalize((0.1307,), (0.3081,))
                                    ])
    
    # 元のモデルに合わせて次元を追加
    image = transform(image).unsqueeze(0)
    
    # 予測を実施
    output = model(image.to(device))
    _, prediction = torch.max(output, 1)
    # 結果を出力
    print("{} -> result = ".format(PATH) + str(prediction[0].item()))
    

    실행 결과



    결과①

    mnist/2.jpg -> result = 2
    

    결과②

    mnist/6.jpg -> result = 6
    

    요약



    뭔가 잘 어울리는 분위기.
    PyTorch는 OpenCV가 아니라 Pillow를 사용하는 경우가 많다.
    모델 자체의 정확도는 그다지 높지 않았다. 과학하고 있을지도 모른다.

    좋은 웹페이지 즐겨찾기