zoukankan      html  css  js  c++  java
  • L0 torch 构建网络初步

    L0 pytorch 构建简单网络

    本文是L0, 目的是把pytorch构建感知器的程序,仔细剖析理解。

    import torch
    from torch import nn
    
    torch.__version__
    
    '1.3.0'
    

    STEP 1 手工定义全连接层Linear

    #torch.nn是专门为深度学习设计的模块。torch.nn的核心数据结构是Module
    #它是一个抽象的概念,#既可以表示神经网络中的某个层(layer),
    #也可以表示一个包含很多层的神经网络
    #class Linear(nn.Module):
    #    def __init__(self,in_dim,out_dim):
    #    def forward(self,x):
    
    
    # 手工定义全连接层,写forward
    class Linear(nn.Module):
        def __init__(self,in_dim,out_dim):
            super(Linear,self).__init__() 
            #调用nn.Moudule 的初始化函数,首先找到Linear的父类nn.Moudle
            #然后把类Linear的对象self转换为类nn.Moudle的对象,然后“被转换”的类nn.Moudle对象调用自己的__init__函数
            #也可以写成nn.Module.__init__(self)
            
            #在构造函数__init__中必须自己定义可学习的参数,并封装成Parameter
            # parameter是一种特殊的Variable,但其默认需要求导(requires_grad = True)
            self.w = nn.Parameter(torch.randn(in_dim,out_dim))
            self.b = nn.Parameter(torch.randn(out_dim))
            
        def forward(self ,x):
            x=x.matmul(self.w) #使用Tensor.matmul 实现w*x矩阵相乘
            y=x+self.b.expand_as(x) #即 y=wx + b 使用Tensor.expand_as 保证x 和b形状一致
            print("调式点1:y的输出维度为",y.shape) #测试x的维度
            return y
      
    

    STEP2 测试Linear 层是否能正常工作

    # 初始化 Linear层结构为 4*3 
    layer = Linear(4, 3)
    
    # 测试喂数据,是否有输出,理解输入输出的维度
    #from torch.autograd import Variable as V
    #input = V(torch.randn(2, 4))
    input = torch.randn(2,4)#输入为二行样本,每行4个特征
    output = layer(input)   #模型每次输入4个特征,输出3个值。
    print(output) # 二行样本,输出2个3维的结果,因此y的输入维度为  torch.size([2,3])
    
    调式点1:y的输出维度为 torch.Size([2, 3])
    tensor([[-1.2798, -1.4936,  0.2399],
            [-1.1742,  1.2190, -2.8469]], grad_fn=<AddBackward0>)
    

    理解
    input = torch.randn(2,4)
    output = layer(input)
    1) 定义layer对输入形状都有假设:输入的不是单行样本数据,而是一个batch。此处batch的大小为2
    2)若想输入单行样本数据 必须调用unsqueeze(0)函数将数据伪装成batch_size=1的batch。

    # 原数据2*4,为batch为2,每batch数据为4维
    #通过unsqueeze 将2*4的数据伪装成 1*2*4的数据,batch变成1,每个batch数据变成2*4
    input = torch.randn(2,4)
    input.unsqueeze(0).size()
    
    torch.Size([1, 2, 4])
    
    
    
    # 测试目前网络的参数,理解参数的维度
    for name, param in layer.named_parameters():
        print(name) 
        print(param) 
        #w 维度为4*3 b的维度为1*3
    
    w
    Parameter containing:
    tensor([[-0.3579, -0.6608,  0.1783],
            [ 1.6277, -0.4486, -1.9849],
            [ 0.9500, -0.1879,  1.7154],
            [-0.5778, -0.2012,  1.5576]], requires_grad=True)
    b
    Parameter containing:
    tensor([-0.9491, -0.1104, -1.2390], requires_grad=True)
    
    for name, param in layer.named_parameters():
        print(name, param.size())
    
    w torch.Size([4, 3])
    b torch.Size([3])
    

    module中parameter的命名规范:
    1)对于类似self.param_name = nn.Parameter(t.randn(3, 4)),命名为param_name
    2)对于子Module中的parameter,会其名字之前加上当前Module的名字。
    如对于self.sub_module = SubModel(),SubModel中有个parameter的名字叫做param_name,
    那么二者拼接而成的parameter name 就是sub_module.param_name。
    见后续采用Linear类进一步构建多层感知器的例子

    STEP3 组建 二个全连接层的感知器

    class Perceptron (nn.Module):
        def __init__(self, in_features, hidden_features, out_features):
            super(Perceptron,self).__init__()  #或写成nn.Module.__init__(self)
            # 利用 Linear subModel组建 layer 1 ,layer 2
            self.layer1 = Linear(in_features, hidden_features)
            self.layer2 = Linear(hidden_features, out_features)
             
        def forward(self, x):
            x = self.layer1(x)
            x = torch.sigmoid(x)
            x = self.layer2(x)
            y = torch.sigmoid(x)
            return y
     
    per = Perceptron(3, 4, 1)
    
    
    per
    
    Perceptron(
      (layer1): Linear()
      (layer2): Linear()
    )
    
    # 测试网络参数
    for name, param in per.named_parameters():
        print("sub_module.param_name::",name, param.size())
    
    sub_module.param_name:: layer1.w torch.Size([3, 4])
    sub_module.param_name:: layer1.b torch.Size([4])
    sub_module.param_name:: layer2.w torch.Size([4, 1])
    sub_module.param_name:: layer2.b torch.Size([1])
    

    1)Module中的可学习参数可以通过**named_parameters()**或者parameters()返回迭代器,前者会给每个parameter都附上名字,使其更具有辨识度。
    2)Module能够自动检测到自己的Parameter,并将其作为学习参数。

    # 测试网络输入,输出
    data=torch.randn(4,3)
    output=per(data)
    output
    
    调式点1:y的输出维度为 torch.Size([4, 4])
    调式点1:y的输出维度为 torch.Size([4, 1])
    
    
    
    
    
    tensor([[0.5478],
            [0.6146],
            [0.6252],
            [0.8016]], grad_fn=<SigmoidBackward>)
    

    STEP 4 利用nn.Sequential 快速搭建网络

    从上面的例子,可以看出在forward()方法中必须理解网络结构,并根据网络层次的之间的关系完成网络组装。
    当模型仅仅是简单的前馈网络时,可以采用nn.Sequentail()模块来快速搭建模块,而不必手动的在forward()方法手工构建。
    Image Name

    class Seq_Perceptron (nn.Module):
        
        def __init__(self, in_features, hidden_features, out_features):
            super(Seq_Perceptron ,self).__init__()  #或写成nn.Module.__init__(self)
            # 利用 Linear subModel组建 layer 1 ,layer 2
            #self.layer1 = Linear(in_features, hidden_features)
            #self.layer2 = Linear(hidden_features, out_features)
            self.seq_layer = nn.Sequential(
                nn.Linear(in_features,hidden_features),
                nn.Sigmoid(),
                nn.Linear(hidden_features,out_features),
                nn.Sigmoid()
                )
           
        def forward(self, x):
            y =  self.seq_layer(x)
            return y
    
    # 测试网络输入,输出
    per = Seq_Perceptron(3, 4, 1)
    data=torch.randn(4,3)
    output=per(data)
    output
    
    tensor([[0.5853],
            [0.6061],
            [0.5967],
            [0.6131]], grad_fn=<SigmoidBackward>)
    
    
    
  • 相关阅读:
    leetcode 122. Best Time to Buy and Sell Stock II
    leetcode 121. Best Time to Buy and Sell Stock
    python 集合(set)和字典(dictionary)的用法解析
    leetcode 53. Maximum Subarray
    leetcode 202. Happy Number
    leetcode 136.Single Number
    leetcode 703. Kth Largest Element in a Stream & c++ priority_queue & minHeap/maxHeap
    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
    正则表达式
    十种排序算法
  • 原文地址:https://www.cnblogs.com/supercodeing/p/12332772.html
Copyright © 2011-2022 走看看