Pytorch入门深度学习

numpy搭建两层神经网络

#用numpy搭建两层神经网络
N,D_in,H,D_out=64,1000,100,10 #输入64*1000,隐藏层为64*100,输出64*10
x=np.random.randn(N,D_in)
w1=np.random.randn(D_in,H)
w2=np.random.randn(H,D_out)
y = np.random.randn(N, D_out)
learn_rate=1e-6
for it in range(500):
    #forward pass 前向传递
    h=x.dot(w1)#点乘
    h_relu=np.maximum(0,h)
    y_pred=h_relu.dot(w2)
    #compute loss,采用均方差损失函数
    loss = np.square(y_pred-y).sum()
    print(it,loss)
    #backward pass
    grad_y_pred=2.0*(y_pred-y)
    grad_w2=h_relu.T.dot(grad_y_pred)
    grad_h_relu=grad_y_pred.dot(w2.T)
    grad_h=grad_h_relu.copy()
    grad_h[h<0]=0
    grad_w1=x.T.dot(grad_h)
    w1 -=learn_rate*grad_w1
    w2 -=learn_rate*grad_w2

结果如下
在这里插入图片描述

pytorch改写网络

import torch
N,D_in,H,D_out=64,1000,100,10 #输入64*1000,隐藏层为64*100,输出64*10
x=torch.randn(N,D_in)
# x=torch.randn(N,D_in).to("cuda:0")
# x=torch.randn(N,D_in).cuda()将变量传至cuda运算
w1=torch.randn(D_in,H,requires_grad=True)
w2=torch.randn(H,D_out,requires_grad=True)
y = torch.randn(N, D_out)
learn_rate=1e-6
for it in range(500):
    #forward pass 前向传递
    h=x.mm(w1)#点乘
    h_relu=h.clamp(min=0)#相当于relu函数
    y_pred=h_relu.mm(w2)
    # y_pred=x.mm(w1).clamp(min=0).mm(w2)
    #compute loss,采用均方差损失函数
    loss = (y_pred - y).pow(2).sum()
    print(it,loss.item())#将tensor转化为数值
    #backward pass
    loss.backward()
    with torch.no_grad():#清除grad内存
        w1 -=learn_rate*w1.grad
        w2 -=learn_rate*w2.grad
        w1.grad.zero_()
        w2.grad.zero_()

由于torch和numpy其实是共用内存的,其很多语法都是共用的,不过torch处理的是向量,numpy处理的是矩阵,数值,因此代码方面没有很大的改动。而且pytorch里是有autograd的,可以自动反向求导,因此反向求导的过程就不需要我们编写代码,需要注意的是每次参数更新后,反向传播前需要清理梯度内存。结果如下:

在这里插入图片描述

torch.nn包搭建网络

#用torch.nn包来搭建网络
import  torch
import torch.nn as nn
import torch.nn.functional as F
N,D_in,H,D_out=64,1000,100,10
x=torch.randn(N,D_in)
y=torch.randn(N,D_out)
#定义一个网络
model=nn.Sequential(
    torch.nn.Linear(D_in,H),
    torch.nn.ReLU(),
    torch.nn.Linear(H,D_out)
)
torch.nn.init.normal_(model[0].weight)#使用normal去初始化参数,效果会好一些
torch.nn.init.normal_(model[2].weight)
loss_fn=nn.MSELoss(reduction='sum')#nn包中自带有MSE损失函数
learn_rate=1e-6
for it in range(500):
    y_pred=model(x)
    loss=loss_fn(y_pred,y)
    print(it,loss.item())
    loss.backward()#反向传播
    with torch.no_grad():
        for parm in model.parameters():#可看到所有网络中参数
            parm -= learn_rate*parm.grad#更新参数
    model.zero_grad()#清空梯度内存很重要,否则梯度会叠加

这里我们采用了torch.nn.Sequential来定义一个网络,我们看到网络调整的比较慢,这里可以采用torch.nn.init.normal_来初始化参数使得网络效果更好,当然也可以通过调整学习率来加速网络的训练。
在这里插入图片描述
当遇到要建立更加复杂的网络结构的问题时,则更倾向于用自定义子类torch.nn.Module来构建一个网络

import torch.nn as nn
import torch.nn.functional as F
import torch.optim
N,D_in,H,D_out=64,1000,100,10
x=torch.randn(N,D_in)
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)
        self.linear2=nn.Linear(H,D_out)
    def forward(self,x):
        y_pred=self.linear2(F.relu(self.linear1(x)))
        return  y_pred
model=TwolayerNet(D_in,H,D_out)

# torch.nn.init.normal_(model[0].weight)#使用normal去初始化参数,效果会好一些
# torch.nn.init.normal_(model[2].weight)
loss_fn=nn.MSELoss(reduction='sum')#nn包中自带有MSE损失函数
learn_rate=1e-4
optimizer=torch.optim.Adam(model.parameters(),lr=learn_rate)
for it in range(500):
    y_pred=model(x)
    loss=loss_fn(y_pred,y)
    print(it,loss.item())
    optimizer.zero_grad()#求导前把梯度内存清空
    loss.backward()#反向传播
    optimizer.step()#求导后更新参数

torch.optim更新参数

如果你想使用不同的更新规则,类似于 SGD, Nesterov-SGD, Adam,RMSProp等,可使用torch.optim

import torch.nn as nn
import torch.nn.functional as F
import torch.optim
N,D_in,H,D_out=64,1000,100,10
x=torch.randn(N,D_in)
y=torch.randn(N,D_out)
#定义一个网络
model=nn.Sequential(
    torch.nn.Linear(D_in,H),
    torch.nn.ReLU(),
    torch.nn.Linear(H,D_out)
)
# torch.nn.init.normal_(model[0].weight)#使用normal去初始化参数,效果会好一些
# torch.nn.init.normal_(model[2].weight)
loss_fn=nn.MSELoss(reduction='sum')#nn包中自带有MSE损失函数
learn_rate=1e-4
optimizer=torch.optim.Adam(model.parameters(),lr=learn_rate)
for it in range(500):
    y_pred=model(x)
    loss=loss_fn(y_pred,y)
    print(it,loss.item())
    optimizer.zero_grad()#求导前把梯度内存清空
    loss.backward()#反向传播
    optimizer.step()#求导后更新参数

Reference:
https://www.bilibili.com/video/BV12741177Cu/?p=4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值