zoukankan      html  css  js  c++  java
  • pytorch入门与实战学习->第一课(两层神经网络之numpypytorch实现)

    这篇博客早就想写了,因为这节课是我在疫情的假期里看的,还不错,准备一直看完。所有最近又复习了一遍。因为之前一直在学《动手学深度学习》PyTorch版,不过,我这个人真是懒,一直么学好,也断断续续。不过,我还是会把那本书接着学一遍,先看这个视频了,因为最近有可能用到。

    本系列博客是根据哔哩哔哩上pytorch入门与实战这个视频课程写的(主要是代码),因为是小白,死磕课本有点费劲,学习《动手学深度学习》PyTorch版时就发现了。

    哔哩哔哩上这系列课的网址:https://www.bilibili.com/video/BV12741177Cu?from=search&seid=17209581732555565064

    实现的两层神经网络的模型:    :为了简单实现,偏置项b不在网络中实现。

    $ h = w_{1}*X + b_{1} $

    $ a = max(0,h) $

    $ y_{hat} = w_{2}*a + b_{2} $

    以下代码是我为了记忆,自己直接敲的一遍,有错误请指出,谢谢了

    下面使用numpy实现该神经网络:1 2 3 4 步,所有的网络基本都是这几步,其他的就是数据处理什么的

    import numpy as np
    N, D_in, H, D_out = 64, 1000, 100, 10



    # 定义输入输出数据
    x = np.random.randn(D_in, H)
    y = np.random.randn(N, D_out)

    # 权重随机初始化
    w1 = np.random.randn(D_in, H)
    w2 = np.random.randn(H, D_out)

    learning_rate = 1e-6
    for it in range(500): # 对网络训练500次
      # 1 Forward pass,前向网络,也就是模型
      h = x.dot(w1) # .dot()在numpy中是计算向量点积的函数
      h_relu = np.maximum(h, 0)  # .maximum()是采用的ReLU激活函数
      y_pred = h_relu.dot(w2)
      
      # 2 计算损失函数
      loss = np.square(y_pred - y).sum() # 平方损失函数,.square()就是求平方,sum()求和
      print(it, loss)
      
      # 3 backward pass, 反向网络,也就是计算梯度。若是看代码费劲,可以先对上面提的神经网络模型公式进行求导,然后对应到Forward Pass中的定义即可。我的推导见附录一
      grad_y_pred = 2.0 * (y_pred - y)
      grad_w2 = h_relu.T.dot(grad_y_pred)
      grad_h_relu = grad_y_perd.dot(w2.T)
      grad_h = grad_h_relu.copy()
      grad_h[h<0] = 0
      grad_w1 = x.T.dot(grad_h)
      
      # 4 update weights of w1 and w2, 更新权重,也就是学习一个好的权重
      w1 -= learning_rate * grad_w1
      w2 -= learning_rate * grad_w2

    PyTorch实现上述两层神经网络模型:附录二有numpy和PyTorch的封装的函数的小差别对比

    import torch
    N, D_in, H, D_out
    = 64, 1000, 100, 10 # 定义输入输出数据 x = torch.randn(D_in, H) y = torch.randn(N, D_out) # 权重随机初始化 w1 = torch.randn(D_in, H) w2 = torch.randn(H, D_out) learning_rate = 1e-6 for it in range(500): # 对网络训练500次   # 1 Forward pass,前向网络,也就是模型   h = x.mm(w1) # .mm()在torch中是计算向量点积的函数   h_relu = h.clamp(min=0)  # .clamp()是采用的ReLU激活函数,是类似于range,一个min,一个max,夹在中间,大于max,就记为max,小于min,就记为min   y_pred = h_relu.mm(w2)      # 2 计算损失函数   loss = np.square(y_pred - y).sum() # 平方损失函数,.square()就是求平方,sum()求和   print(it, loss)      # 3 backward pass, 反向网络,也就是计算梯度。若是看代码费劲,可以先对上面提的神经网络模型公式进行求导,然后对应到Forward Pass中的定义即可。我的推导见附录一   grad_y_pred = (y_pred - y).pow(2)   grad_w2 = h_relu.t().mm(grad_y_pred)   grad_h_relu = grad_y_perd.mm(w2.t())   grad_h = grad_h_relu.clone()   grad_h[h<0] = 0   grad_w1 = x.t().mm(grad_h)      # 4 update weights of w1 and w2, 更新权重,也就是学习一个好的权重   w1 -= learning_rate * grad_w1   w2 -= learning_rate * grad_w2

    PyTorch简化版实现上述网络(torch.nn.Sequential()):(因为pytorch封装了好多方法和类,可以自动求梯度,不用自己实现)

    import torch.nn as nn
    N, D_in, H, D_out = 64, 1000, 100, 10
    x = torch.randn(D_in, H) 
    y = torch.randn(N, D_out)

    model = nn.Sequential(
      nn.Linear(D_in, H, bias=False),
      nn.ReLU(),
      nn.Linear(H, D_out)
    )

    nn.init.normal_(model[0].weight) # 初始化一下权重,否则会模型效果会差。
    nn.init.normal_(model[2].weight)

    loss_fn = nn.MSELoss(reduction='sum')

     learning_rate = 1e-6
     for it in range(500):

        y_pred = model(x)   # 相当于model.forward(x),model会自动做前向传播

        loss = loss_fn(y_pred, y)

        print(it, loss)

        loss.backward()

        with torch.no_grad():   #加入这句,可以不记录计算图的历史,节省内存

          for param in model.parameters(): # 遍历模型参数,优化

            param -= learning_rate * param.grad

        model.zero_grad()  # 计算下次梯度前,清零梯度

    PyTorch简化版实现上述网络(torch.nn.Module())

    
    
    import torch.nn as nn
    N, D_in, H, D_out = 64, 1000, 100, 10
    
    
    x = torch.randn(D_in, H) 
    y = torch.randn(N, D_out)

    class TwoLayerNet(nn.Module):
      def __init__(self, D_in, H, D_out):
        super(TwoLayerNet, self).__init__() # 必须这么写
        self.linear1 = nn.Linear(D_in, H, bias=False)
        self.linear2 = nn.Linear(H, D_out, bias=False)

      def forward(self,x):
        y_pred = self.linear2(self.linear1(x).clamp(min=0))
      return y_pred

    model = TwoLayreNet(D_in, H, D_out)
    loss_fn = nn.MSELoss(reduction='sum')
    learning_rate = 1e-4
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) # 若使用SGD优化器,需要初始化weight,否则效果不好,玄学。。。

    for it in range(500):
      y_pred = model(x)

      loss = loss_fn(y_pred,y)
      print(it, loss)
      
      # 三步操作:梯度清零,反向计算新梯度,一步优化(update parameter)
      optimizer.zero_grad()
      loss.backward()
      optimizer.step()

    上述torch.nn.Sequential和torch.nn.Modele,在我学习《动手学深度学习》时也介绍过,可以去我以前的博客看看,欢迎指点和探讨,我是小白,虽然我黑。

    附录一:(字体有点low了)

    附录二:(字体样子自动过滤)

  • 相关阅读:
    HDU_5688
    微服务的一致性问题
    我来博客园啦
    异常:This application has no explicit mapping for /error, so you are seeing this as a fallback.
    异常:Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException
    异常:Unknown lifecycle phase "mvn". You must specify a valid lifecycle
    SpringMVC中遇到页面跳转出现404错误的问题
    Could not resolve view with name '***' in servlet with name 'dispatcher'
    关于Could not resolve dependencies for project
    让我们相互交流
  • 原文地址:https://www.cnblogs.com/JadenFK3326/p/13110192.html
Copyright © 2011-2022 走看看