딥 러 닝 프레임 워 크 PyTorch - 제4 장 신경 망 공구 상자

19678 단어 딥 러 닝PyTorch
"""
           nn
      ,  autograd         ,        ,             ,           。
      ,torch.nn    ,               。
torch.nn        Module,        ,              (layer),                 。
      ,         nn.Module,       / 。
         nn.Module         。
    ,     ,  y   x  y=wx+b,w b       。
"""
import torch as t
from torch import nn

class Linear(nn.Module):
    def __init__(self,in_features,out_features):
        super(Linear,self).__init__()#   nn.Module.__init__(self)
        self.w=nn.Parameter(t.rand(in_features,out_features))
        self.b=nn.Parameter(t.rand(out_features))

    def forward(self,x):
        x=x.mm(self.w)
        return x+self.b.expand_as(x)

layer = Linear(4,3)
input = t.randn(2,4)
output = layer(input)
print(output)

for name, parameter in layer.named_parameters():
    print(name, parameter) # w and b

"""
               :
1.    Linear    nn.Module,             nn.Moudle     
 super(Linear,self).__init__()  nn.Moudle.__init__(self),     
2.     __init__             ,    Parameter,        w b   parameter。
parameter      Tensor,        (requires_grad = True)
3.forward          ,           tensor
4.         ,nn.Module    autograd        ,   Function    。
5.   ,     layer          ,  layer(input)    input     。    layers.__call__(input), __call__   ,       layer.forward(x),            
6.Module           named_parameters()  parameters()     ,      parameter     ,        。
"""

"    Module       ,   Function       ,             。"


class Perceptron(nn.Module):
    def __init__(self,in_features,hidden_features,out_features):
        nn.Module.__init__(self)
        self.layer1 = Linear(in_features,hidden_features) #   Linear          
        self.layer2 = Linear(hidden_features,out_features)
    def forward(self, x):
        x= self.layer1(x)
        x=t.sigmoid(x)
        return self.layer2(x)

perceptron=Perceptron(3,4,1)
for name,param in perceptron.named_parameters():
    print(name,param.size())

"""
  ,            ,        。
    __init__ ,         Linear (module),    module      module,       ,      module      。

module parameter     :

    self.param_name = nn.Parameter(t.randn(3, 4)),   param_name
   Module  parameter,          Module   。   self.sub_module = SubModel(),SubModel   parameter     param_name,         parameter name   sub_module.param_name。
       ,PyTorch             layer,  layer    nn.Module,        parameter,    forward  ,        GPU     CuDNN  ,           。      nn.Module           ,             1  IPython/Jupyter   nn.layer?   。              :

       , nn.Linear(in_features, out_features, bias),           。
  、       module。 nn.Linear  weight bias       ,    module。
       , nn.linear      (N, input_features),   (N,output_features),N batch_size。
     layer         :         ,    batch。        ,     tensor.unsqueeze(0)   tensor[None]      batch_size=1 batch
"""

"""
4.1       
4.1.1     
            (Conv)、   (Pool) ,              (1D)、  (2D)、  (3D),
           (AvgPool)、     (MaxPool)、     (AdaptiveAvgPool) 。
               ,     (TransposeConv)。
"""
import matplotlib.pyplot as plt
from PIL import Image
from torchvision.transforms import ToTensor,ToPILImage

to_tensor=ToTensor()# img->tensor
to_pil=ToPILImage()
lena=Image.open('imags/lena.png')
plt.imshow(lena)
plt.show()

#     batch,batch_size=1
input=to_tensor(lena).unsqueeze(0)

#     
kernel=t.ones(3,3)/9
kernel[1][1]=1
conv=nn.Conv2d(1,1,(3,3),1,bias=False)

out=conv(input)
to_pil(out.data.squeeze(0))

"                ,     。           , weight    。"
pool=nn.AvgPool2d(2,2)
print(list(pool.parameters()))

"""
         ,               :

Linear:    。
BatchNorm:     ,  1D、2D 3D。     BatchNorm  ,            InstanceNorm 。
Dropout:dropout ,       ,    1D、2D 3D。               
"""

#    batch_size=2,  3
input = t.randn(2, 3)
linear = nn.Linear(3, 4)
h = linear(input)
print(h)


# 4 channel,       4,   0
bn = nn.BatchNorm1d(4)
bn.weight.data = t.ones(4) * 4
bn.bias.data = t.zeros(4)

bn_out = bn(h)
#           
#          ,          1
#   unbiased=False     1
print(bn_out.mean(0), bn_out.var(0, unbiased=False))

#      0.5     
dropout = nn.Dropout(0.5)
o = dropout(bn_out)
print(o) #          0

"""
4.1.2     
PyTorch          ,               1,            layer  
"""
relu = nn.ReLU(inplace=True)
input = t.randn(2, 3)
print(input)
output = relu(input)
print(output) #   0      0
#    input.clamp(min=0)

"""
ReLU    inplace  ,    True,             ,        /  。
             ReLU      ,                   。
       autograd    inplace  ( tensor.sigmoid_()),              ,        inplace  。
       ,                      ,            (feedforward neural network)。
               forward       ,          ,ModuleList Sequential。
  Sequential      module,      Module,                   。
ModuleList       module,       module,    list     ,          ModuleList。      
"""
# Sequential     
net1 = nn.Sequential()
net1.add_module('conv', nn.Conv2d(3, 3, 3))
net1.add_module('batchnorm', nn.BatchNorm2d(3))
net1.add_module('activation_layer', nn.ReLU())

net2 = nn.Sequential(
        nn.Conv2d(3, 3, 3),
        nn.BatchNorm2d(3),
        nn.ReLU()
        )

from collections import OrderedDict
net3= nn.Sequential(OrderedDict([
          ('conv1', nn.Conv2d(3, 3, 3)),
          ('bn1', nn.BatchNorm2d(3)),
          ('relu1', nn.ReLU())
        ]))
print('net1:', net1)
print('net2:', net2)
print('net3:', net3)

#            module
print(net1.conv, net2[0], net3.conv1)

input = t.rand(1, 3, 4, 4)
output = net1(input)
output = net2(input)
output = net3(input)
output = net3.relu1(net1.batchnorm(net1.conv(input)))


modellist = nn.ModuleList([nn.Linear(3,4), nn.ReLU(), nn.Linear(4,2)])
input = t.randn(1, 3)
for model in modellist:
    input = model(input)
#      ,  modellist    forward  
# output = modelist(input)

"""
    ,      ,       Python    list,        ?    ModuleList Module   ,  Module       ,        module。

      。
"""
class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.list = [nn.Linear(3, 4), nn.ReLU()]
        self.module_list = nn.ModuleList([nn.Conv2d(3, 3, 3), nn.ReLU()])
    def forward(self):
        pass
model = MyModule()
print(model)

for name, param in model.named_parameters():
    print(name, param.size())

"""
  ,list   module     module   , ModuleList   module    module   。
       list   module,        ,       module    。

 ModuleList    ParameterList,          parameter  list  。
      ,     ModuleList  。       __init__   list、tuple、dict    ,          ModuleList ParameterList  
"""


"""
4.1.3        (RNN)
                     ,RNN        ,  RNN     ,    colah   1  。
PyTorch            RNN:RNN(vanilla RNN)、LSTM GRU。         RNNCell。

RNN RNNCell                  ,                   ,            ,       。   RNN              RNNCell    
"""

t.manual_seed(1000)
#   :batch_size=3,      2,        4 
input = t.randn(2, 3, 4)
# lstm    4 ,   3,1 
lstm = nn.LSTM(4, 3, 1)
#     :1 ,batch_size=3,3    
h0 = t.randn(1, 3, 3)
c0 = t.randn(1, 3, 3)
out, hn = lstm(input, (h0, c0))
print(out)


t.manual_seed(1000)
input = t.randn(2, 3, 4)
#   LSTMCell          
lstm = nn.LSTMCell(4, 3)
hx = t.randn(3, 3)
cx = t.randn(3, 3)
out = []
for i_ in input:
    hx, cx=lstm(i_, (hx, cx))
    out.append(hx)
print(t.stack(out))


"               ,PyTorch     Embedding 。"
#  4  ,    5      
embedding = nn.Embedding(4, 5)
#               embedding
embedding.weight.data = t.arange(0,20).view(4,5)

input = t.arange(3, 0, -1).long()
output = embedding(input)
print(output)


"""
4.1.4     
                  (loss function),               layer,PyTorch           nn.Module   。
             loss function      ,        。
   loss       1,               CrossEntropyloss    
http://pytorch.org/docs/nn.html#loss-functions↩
"""
# batch_size=3,           (      )
score = t.randn(3, 2)
#         1,0,1 ,label   LongTensor
label = t.Tensor([1, 0, 1]).long()

# loss    layer   
criterion = nn.CrossEntropyLoss()
loss = criterion(score, label)
print(loss)



"""
4.2    
PyTorch                  torch.optim ,       ,                 。

             optim.Optimizer,           。            ——       (SGD)    。       :

1.           
2.                  
3.       
"""
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.features=nn.Sequential(
            nn.Conv2d(3,6,5),
            nn.ReLU(),
            nn.MaxPool2d(2,2),
            nn.Conv2d(6,16,5),
            nn.ReLU(),
            nn.MaxPool2d(2,2)
        )
        self.classifier=nn.Sequential(
            nn.Linear(16*5*5,120),
            nn.ReLU(),
            nn.Linear(120,84),
            nn.ReLU(),
            nn.Linear(84,10)
        )
    def forward(self,x):
        x=self.features(x)
        x=x.view(-1,16*5*5)
        x=self.classifier(x)
        return x
net=Net()

from torch import optim
optimizer=optim.SGD(params=net.parameters(),lr=1)
optimizer.zero_grad() #    ,   net.zero_grad()

input=t.randn(1,3,32,32)
output=net(input)
output.backward(output) #fake backward

optimizer.step()#    
#               , finetune     
#              ,            
optimizer=optim.SGD([
    {'params':net.features.parameters()},#    1e-5
    {'params':net.classifier.parameters(),'lr':1e-2}
],lr=1e-5)
print(optimizer)

#                 ,         
special_layers=nn.ModuleList([net.classifier[0],net.classifier[3]])
special_layers_params=list(map(id,special_layers.parameters()))
base_params=filter(lambda p : id(p) not in special_layers_params,net.parameters())

optimizer=t.optim.SGD([
    {'params':base_params},
    {'params':special_layers.parameters(),'lr':0.01}
],lr=0.001)
print(optimizer)

"""
         ,       。
     optimizer.param_groups       ,
                ——     ,  optimizer     ,      ,        optimizer。
              ( Adam),          ,                   
"""
#   1:      ,    optimizer
old_lr=0.1
optimizer1=optim.SGD([
    {'params':net.features.parameters()},
    {'params':net.classifier.parameters(),'lr':old_lr*0.1}
],lr=1e-5)
print(optimizer1)

#   2:      ,   decay,     
for param_group in optimizer.param_groups:
    param_group['lr']*=0.1#       0.1 
print(optimizer)

"""
4.3 nn.functional
nn           :nn.functional,nn     layer, functional             。
nn.functional     nn.Module       , nn.Module   layers       ,   class layer(nn.Module)  ,           。
 nn.functional          , def function(input)  。
      functional   ,          。
"""
input=t.randn(2,3)
model=nn.Linear(3,4)
output1=model(input)
output2=nn.functional.linear(input,model.weight,model.bias)
print(output1==output2)

b=nn.functional.relu(input)
b2=nn.ReLU()(input)
print(b==b2)

"""
        ,        nn.Module,      nn.functional ?
     ,           ,   nn.Module,       nn.functional     nn.Module,
            ,             。
     (ReLU、sigmoid、tanh),  (MaxPool)           ,        functional    ,
     、                  nn.Module。
      ,          nn.Module nn.functional。
    dropout          ,       nn.Dropout   nn.functional.dropout,  dropout                 ,  nn.Module      model.eval      。
"""
from torch.nn import functional as F
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv1=nn.Conv2d(3,6,5)
        self.conv2=nn.Conv2d(6,16,5)
        self.fc1=nn.Linear(16*5*5,120)
        self.fc2=nn.Linear(120,84)
        self.fc3=nn.Linear(84,10)

    def forward(self, x):
        x = F.pool(F.relu(self.conv1(x)), 2)
        x = F.pool(F.relu(self.conv2(x)), 2)
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
"""

            (   、    ),        ,              __init__ 。
           ,    functional   ,           ,        parameter,
             ,   weight bias         ,          parameter
"""
class MyLinear(nn.Module):
    def __init__(self):
        super(MyLinear, self).__init__()
        self.weight = nn.Parameter(t.randn(3, 4))
        self.bias = nn.Parameter(t.zeros(3))
    def forward(self):
        return F.linear(input, weight, bias)

"""
4.4      
                ,              ,       ,                  。
PyTorch nn.Module                   ,          ,                         。
       Parameter ,           , t.Tensor()           ,        ,                    。
PyTorch nn.init             ,         nn.init   ,            
"""
#  nn.init   
from torch.nn import init

linear=nn.Linear(3,4)

t.manual_seed(1)
#   linear.weight.data.normal_(0,std)
print(init.xavier_normal_(linear.weight))

#     
import math
t.manual_seed(1)

#xavier       
std=math.sqrt(2)/math.sqrt(7.)
print(linear.weight.data.normal_(0,std))

#             
for name,params in net.named_parameters():
    if name.find('linear')!=-1:
        #init linear
        params[0]#weight
        params[1]#bias
    elif name.find('conv')!=-1:
        pass
    elif name.find('norm')!=-1:
        pass

"""
4.5 nn.Module    
          nn.Module,          。     nn.Module       :
"""
def __init__(self):
    self._parameters = OrderedDict()
    self._modules = OrderedDict()
    self._buffers = OrderedDict()
    self._backward_hooks = OrderedDict()
    self._forward_hooks = OrderedDict()
    self.training = True

"""
           :

_parameters:  ,         parameter,self.param1 = nn.Parameter(t.randn(3, 3))     ,        key 'param',value   parameter item。 self.submodule = nn.Linear(3, 4)  parameter      。
_modules: module,  self.submodel = nn.Linear(3, 4)    module     。
_buffers:  。 batchnorm  momentum  ,                   。
_backward_hooks _forward_hooks:    ,        ,  variable hook。
training:BatchNorm Dropout                   ,    training          。
       ,_parameters、_modules _buffers         ,     self.key    ,     self._parameters['key'].
"""
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        #    self.register_parameter('param1' ,nn.Parameter(t.randn(3, 3)))
        self.param1=nn.Parameter(t.randn(3,3))
        self.submodel1=nn.Linear(3,4)
    def forward(self, input):
        x=self.param1.mm(input)
        x=self.submodel1(x)
        return x
net=Net()
print(net)
print(net._modules)
print(net._parameters)
print(net.param1)#    net._parameters['param1']
for name ,param in net.named_parameters():
    print(name,param.size())


for name, submodel in net.named_modules():
    print(name, submodel)

bn = nn.BatchNorm1d(2)
input = t.rand(3, 2)
output = bn(input)
print(bn._buffers)

# """
# nn.Module            ,  module      module,    module        module。
#           module,nn.Module       ,   children       module,  module        module(    module)。
#           named_childen named_modules,      module            。
# """
#
# input = t.arange(0, 12).view(3, 4)
# model = nn.Dropout()
# #      ,             0
# print(model(input))
#
#
# model.training  = False
# #      ,dropout     
# model(input)


"""

4.6 nn autograd   
nn.Module     autograd  ,            。 forward   ,nn.Module    tensor       ,        autograd  。      autograd.Function nn.Module     :

autograd.Function   Tensor autograd     , autograd       op,                   
nn.Module   autograd  , nn       ,            。          ,autograd          
nn.functional   autograd     ,        
       PyTorch     ,               ?
       , autograd     ,      Function              。        autograd      ,     Function       ,    ,         Sigmoid  ,     autograd        。
                 ,  nn.Module           。
"""

"""
4.7     :  ResNet
Kaiming He       (ResNet)[^7]                  ,ResNet         CV          ,                          。
     ResNet     ,      ResNet     :ResNet34。ResNet       4-2  ,                       ,             ,                   shortcut。
ResNet             Residual block,     4-3  ,              ,     ,               ,      1,                    ,      。
        Residual block         ,     pool             Residual block  ,          ,             Residual block        layer,       layer    ,   layer       。
   Residual block layer     ,             Module   。     Residual block      moduke,  layer       。       ,      :
          ,    module         modulemake_layer
nn.Module nn.Functional    
    nn.Seqential
"""

from torch import  nn
import torch as t
from torch.nn import  functional as F


class ResidualBlock(nn.Module):
    '''
       module: Residual Block
    '''

    def __init__(self, inchannel, outchannel, stride=1, shortcut=None):
        super(ResidualBlock, self).__init__()
        self.left = nn.Sequential(
            nn.Conv2d(inchannel, outchannel, 3, stride, 1, bias=False),
            nn.BatchNorm2d(outchannel),
            nn.ReLU(inplace=True),
            nn.Conv2d(outchannel, outchannel, 3, 1, 1, bias=False),
            nn.BatchNorm2d(outchannel))
        self.right = shortcut

    def forward(self, x):
        out = self.left(x)
        residual = x if self.right is None else self.right(x)
        out += residual
        return F.relu(out)


class ResNet(nn.Module):
    '''
       module:ResNet34
    ResNet34     layer,  layer     residual block
      module   residual block, _make_layer     layer
    '''

    def __init__(self, num_classes=1000):
        super(ResNet, self).__init__()
        #        
        self.pre = nn.Sequential(
            nn.Conv2d(3, 64, 7, 2, 3, bias=False),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(3, 2, 1))

        #    layer,   3,4,6,3 residual block
        self.layer1 = self._make_layer(64, 64, 3)
        self.layer2 = self._make_layer(64, 128, 4, stride=2)
        self.layer3 = self._make_layer(128, 256, 6, stride=2)
        self.layer4 = self._make_layer(256, 512, 3, stride=2)

        #        
        self.fc = nn.Linear(512, num_classes)

    def _make_layer(self, inchannel, outchannel, block_num, stride=1):
        '''
          layer,    residual block
        '''
        shortcut = nn.Sequential(
            nn.Conv2d(inchannel, outchannel, 1, stride, bias=False),
            nn.BatchNorm2d(outchannel))

        layers = []
        layers.append(ResidualBlock(inchannel, outchannel, stride, shortcut))

        for i in range(1, block_num):
            layers.append(ResidualBlock(outchannel, outchannel))
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.pre(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = F.avg_pool2d(x, 7)
        x = x.view(x.size(0), -1)
        return self.fc(x)

model = ResNet()
input  = t.randn(1, 3, 224, 224)
o = model(input)
print(o)


"""
  , PyTorch        torchvision                  ,     ResNet34,              :
"""
from torchvision import models
model = models.resnet34()

좋은 웹페이지 즐겨찾기