Pytorch入門深度学習(3)——Pytorch入門及びMNIST実現(OOP)


一、Pytorch紹介
1)Pytorch紹介PyTorchはPythonにおけるTorchの派生である.TorchはLua言語を使用するニューラルネットワークライブラリであるため、Torchは使いやすいが、Luaは特に流行していないため、すべての開発チームはLuaのTorchをより流行している言語Pythonに移植した.2)PytorchとTensorflow Pyrtochの最大の利点は、ニューラルネットワークが動的であることであり、静的TensorFlowと比較して、いくつかの問題をより効果的に処理することができ、Tensorflowの静的計算図はRNN上で少し受動的である(他の方法で解決されたが)、PyTorchを使用すると、このような動的RNNをよりよく理解することができる.そしてTensorflowの高度な工業化、その下層コード...あなたは理解できません.PyTorchは少しいいですが、APIに深く入り込むと、少なくともTensorflowを見るよりもPyTorchの下層が何をしているのか理解することができます.
ダイナミックマップ:BPアルゴリズムを構築し、まず計算図、すなわちネットワークの構造トポロジーマップを構築します.3層構造を構築すると、前項の計算時にネットワークを計算図に追加し、前項が終わると構造図があり、逆伝播すると、図の最後の層から逆さまに押して、各層の勾配を1層ずつ計算し、パラメータを更新します.Tensorflowはまず構造図を構築し,パラメータを更新し,柔軟性が足りない.しかし、分布式訓練はできます.3)NumpyかPytorch Torchかはニューラルネットワーク界のNumpyを自称しているが,torchで発生したtensorをGPUに置いて加速演算することができ,NumpyはarrayをCPUに置いて加速演算すると考えられる.したがって,ニューラルネットワークでは,Torchのtensor形式がより優れている.
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np

#     tensor  
a = torch.tensor(3)#   
print(a)
a = torch.tensor([3]) #  
print(a)
print(type(a))
b = torch.tensor([1,2,3], dtype=torch.float32)
print(b)

a = torch.Tensor([1,2])#   
print(a)
a = torch.tensor([1,2])
print(a)

a = torch.tensor([[1,2,3],[4,5,6]])
b = torch.tensor([[1,2,3],[4,5,6]])
print(a * b)
print(a + b)
print(a - b)
print(a / b)
print(torch.mm(a,b.t()))#    
print(torch.dot(a[0],b[0]))#   (torch.dot      )

out: tensor(3) tensor([3]) tensor([1., 2., 3.]) tensor([1., 2.]) tensor([1,2])tensor([1,4,9],[16,25,36]])tensor([2,4,6],[8,10,12]])tensor([0,0,0],[0,0,0]])tensor([1,1,1,[1,1])tensor([14,77]])tensor(14)4)Pytorchとは何ですか.PytorchはPythonベースの科学計算ツールパッケージで、主に2つのシーンに向いています.Numpyの代わりにGPUの計算力を使用することができます.深さ学習研究プラットフォームで、最大の柔軟性と速度を提供することができます.
x = torch.tensor([1,2])
#x.to(device="cuda")
y = torch.tensor([3,4])
if torch.cuda.is_available():
    x = x.cuda() #  x  GPU    
    y = y.cuda()   # cpu convert cuda
    y = y.cpu() # cuda convert cpu
else:
    print(x, y)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(type(device))
x = x.to(device)
print(x)
x.cpu()

out: tensor([1, 2]) tensor([3, 4]) tensor([1, 2])
# numpy torch
a = np.array([1,2,3])
b = torch.tensor([1,2,3])
c = (torch.from_numpy(a))
print(type(c))
print(type(b.numpy()))
a[0] = 5
print(c)#          
print(torch.tensor(a))#   Tensor

out: tensor([5, 2, 3], dtype=torch.int32) tensor([5, 2, 3], dtype=torch.int32)
二、Pytorchの使用方法
1)Autograd:自動導出(automatic differentiation)Pytorchのすべてのニューラルネットワークのコアはautogradパケットである.Autogradパッケージは、テンソル上のすべての操作を自動的に導出します.これは、実行時に定義されたフレームワークです.これは、逆伝播がコードの実行方法に基づいて定義され、反復ごとに異なることを意味します.2)変数(Variable)autograd.Variableはautogradパッケージのコアクラスで、テンソルをパッケージし、ほとんどのテンソルの操作をサポートしています.順方向計算が完了すると、通過できます.backward()法はすべての勾配を自動的に計算し、通過することができる.Data属性は変数中の元のテンソルにアクセスし、この変数の勾配について計算する.gradプロパティ
import torch
from torch.autograd import Variable

x = torch.tensor([1.,2,3], requires_grad=True)
# x = Variable(x, requires_grad=True) #       
y = x.mean() # y = 1/3*(x1+x2+x3)#          
z = y**2
w = 3*z
w.backward()

print(w)
print(z)
print(y)
print(x.grad)#   x   
print(x.data)

out: tensor(12., grad_fn=) tensor(4., grad_fn=) tensor(2., grad_fn=) tensor([4., 4., 4.]) tensor([1., 2., 3.])
#      
_x = [i/100 for i in range(100)]
_y = [5*i + 3 for i in _x]

w = torch.rand(1,requires_grad=True)
b = torch.rand(1,requires_grad=True)
optimizer= torch.optim.SGD([w,b],lr=0.1)

for i in range(100):
    for x,y in zip(_x, _y):
        z = w*x + b
        loss = torch.pow((z-y),2)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        print(w,b)

out:40回以上tensor([5.0000],requires_grad=True)tensorを得る([3.000],requires_grad=True)
四、PytorchがCNNを実現
MNISTピクチャの平均値と分散を計算する
import torch
from torchvision import datasets, transforms

if __name__ == '__main__':
	train_dataset = datasets.MNIST("datasets/", train=True, download=True, transform=transforms.ToTensor())
	testdataset = datasets.MNIST("datasets/", train=False, download=True, transform=transforms.ToTensor())
	dataset = train_dataset+testdataset
	dataloader = torch.utils.data.DataLoader(dataset, batch_size=70000, shuffle=True)
	data = next(iter(dataloader))[0]#       ,        ,   0   
	mean = torch.mean(data,dim=(0,2,3))
	std = torch.std(data,dim=(0,2,3))
	print(mean)
	print(std)

out: tensor([0.1309]) tensor([0.3084])
from torchvision import datasets, transforms
import numpy as np
if __name__ == '__main__':

	train_dataset = datasets.MNIST("datasets/", train=True, download=True, transform=transforms.ToTensor())
	testdataset = datasets.MNIST("datasets/", train=False, download=True, transform=transforms.ToTensor())
	mnist_data = train_dataset + testdataset
	_data = [d[0].data.cpu().numpy() for d in mnist_data]
	print(np.mean(_data))
	print(np.std(_data))

out: tensor([0.1309]) tensor([0.3084])
五、Pytorch実現MNIST(OOP実現)
MyNet.py
import torch

class MLPNet(torch.nn.Module):

    def __init__(self):
        super().__init__()
        self.layer1 = torch.nn.Linear(784,128)
        self.layer2 = torch.nn.Linear(128,256)
        self.layer3 = torch.nn.Linear(256,512)
        self.layer4 = torch.nn.Linear(512,256)
        self.layer5 = torch.nn.Linear(256,128)
        self.layer6 = torch.nn.Linear(128,10)

    def forward(self, x):
        x = torch.reshape(x, (-1,784))
        x = torch.relu(self.layer1(x))
        x = torch.relu(self.layer2(x))
        x = torch.relu(self.layer3(x))
        x = torch.relu(self.layer4(x))
        x = torch.relu(self.layer5(x))
        x = self.layer6(x)#        softmax
        return x


Train.py用語:ラウンド10反復回数120 batch_size mini_batch:一つのサンプルの汎用性は広くない
from MyNet import MLPNet
import torch
import torch.nn.functional as F
from torchvision.datasets import MNIST
import torchvision.transforms as trans
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np

class Trainer:
    def __init__(self):
        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        self.net = MLPNet().to(self.device)
        self.loss_func = torch.nn.MSELoss()
        self.opt = torch.optim.Adam(self.net.parameters())
        self.trainset, self.testset = self.get_dataset()
    def get_dataset(self):
        transformer = trans.Compose([
            trans.ToTensor(),
            trans.Normalize((0.1309,), (0.3084,))
        ])

        trianData = MNIST(root="datasets/", train=True, download=False, transform=transformer)
        testData = MNIST(root="datasets/", train=False, download=False, transform=transformer)
        return trianData, testData

    def loader_data(self):
        trainloader = DataLoader(dataset=self.trainset, batch_size=512, shuffle=True)
        testloader = DataLoader(dataset=self.testset, batch_size=512, shuffle=True)
        return trainloader, testloader

    def train(self):
        trainloader, testloader = self.loader_data()
        losses = []
        for i in range(10):
            print("epochs:{}".format(i))
            for j, (x, y) in enumerate(trainloader):
                x = x.to(self.device)
                y = F.one_hot(y.long()).float().to(self.device)#(500,10)
                #y = torch.zeros(y.size(0),10).scatter_(1, y.view(-1, 1), 1).to(self.device)
                out = self.net(x)
                loss = self.loss_func(out, y)
                if j % 10 == 0:
                    print("{}/{},loss{}".format(j, len(trainloader), loss.float()))
                    losses.append(loss.float())
                    plt.clf()
                    plt.plot(losses)
                    plt.pause(0.01)

                self.opt.zero_grad()
                loss.backward()
                self.opt.step()

            torch.save(self.net, "models/net.pth")
            self.test(testloader)#         

    def test(self, testloader):
        total = 0
        for x ,y in testloader:
            x = x.to(self.device)
            y = y.to(self.device)
            out = self.net(x)
            predict = torch.argmax(out, dim=1)
            total += (predict == y).sum()

        print("   :{}".format(total.item() / len(self.testset) * 100))

    def testPic(self):
        net = torch.load("models/net.pth")
        img = Image.open("8.jpg")
        img = trans.Resize(28)(img)
        img = trans.Grayscale()(img)
        img = trans.ToTensor()(img)
        img = 1. - img
        img = trans.Normalize((0.1309,),(0.3084,))(img)
        img = img.unsqueeze(0)
        # print(img)
        """
                0.5,       [-1,1],  
            255 - 0       1 - 0,       0 - 1
                  0 - 1, 1-img  
        
        """
        out = net(img.to(self.device))
        print("AI    :{}".format(out.argmax(dim=1)))
        # img.show()

    def testPic2(self):
        net = torch.load("models/net.pth")
        transformer = trans.Compose([
            trans.Resize(28),
            trans.CenterCrop(28),
            trans.Grayscale(),
            trans.ToTensor(),
            trans.Normalize((0.5,),(0.5,))
        ])
        """
          :-1  1  
          :     ,         ,         ,
             255 - 0       1,-1
            0 - 255,     -1,1,   img.unsqueeze(0)*-1    
        """
        img = transformer(Image.open("8.jpg")).unsqueeze(0)*-1
        output = net(img.to(self.device))
        print("AI    :{}".format(output.argmax(dim=1)))

    def test2(self, testloader):#     
        net = torch.load("models/net.pth")
        for x ,y in testloader:
            x = x.to(self.device)
            datas = (x * 0.3084 + 0.1309) * 255
            datas = datas.cpu().numpy().astype(np.uint8)
            for i in range(x.shape[0]):
                data = datas[i].squeeze()
                out = net(x[i])
                predict = out.argmax(1)
                plt.clf()
                plt.subplot(1,2,1)
                plt.imshow(data)
                plt.subplot(1,2,2)
                plt.ylim(20)
                plt.xlim(20)
                plt.text(15,10, s="Result is :{}".format(predict.item()), color="r", fontsize=20)
                plt.pause(1)
if __name__ == '__main__':
    t = Trainer()
    train,test = t.loader_data()
    t.test2(test)
"""
self, dim, index ,value
torch.scatter() value  index  dim     self 
"""
index = torch.tensor([0,2,4,1])
src = torch.zeros(4,5)
src = torch.scatter(src, dim=1, index=index.view(-1,1), value=1)
print(src)

a = F.one_hot(index)#  long()
print(a)

out: tensor([[1., 0., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., 0., 1.], [0., 1., 0., 0., 0.]]) tensor([[1, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 1], [0, 1, 0, 0, 0]])