设立计算图并自动计算

【Task2(2天)】设立计算图并自动计算(给代码截图参考)

  1. numpy和pytorch实现梯度下降法
  2. 设定初始值 求取梯度
  3. 在梯度方向上进行参数的更新
  4. numpy和pytorch实现线性回归
  5. pytorch实现一个简单的神经网络

1. numpy和pytorch实现梯度下降法

numpy实现梯度下降


import numpy as np
 
#构造一个函数
def func(x,y):
    return (1-x)**2+100*(y-x**2)**2
 
#函数对x求导
def dz_dx(x,y):
    return 2*x-400*(y-x**2)*x-2
 
#函数对y求导
def dz_dy(x,y):
    return 200*(y-x**2)
 
#梯度下降
def Grad(learinng_rate,Max_iter):
    value = np.zeros(2)#构造初始值
    loss = 10.0
    iter_count = 0
 
    #当自变量的变化时因变量的变化非常小时或者迭代次数没有达到最大时
    while loss > 0.001 and iter_count < Max_iter:
        error = np.zeros(2)
        error[0] = dz_dx(value[0],value[1])
        error[1] = dz_dy(value[0],value[1])
 
        #当各自的偏导数求出来以后就需要对各自方向的值进行更新
        for i in range(2):
            value[i] = value[i]-learinng_rate*error[i]
        loss = func(value[0],value[1])
        print('迭代次数:',iter_count,'损失:',loss)
        iter_count += 1
    return value
 
if __name__ == '__main__':
    print(Grad(0.001,10000))

pytorch实现梯度下降法

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as f
import torch.optim as optim
import matplotlib.pyplot as plt

NUM = 100   #输入个数(输入层神经元个数)
hider_num = 300  #隐藏层神经元个数
class Net(nn.Module):
   def __init__(self):
       super(Net,self).__init__()

       self.fc1 = nn.Linear(NUM,hider_num)
       self.fc2 = nn.Linear(hider_num,NUM)

   def forward(self,x):
       x = f.relu(self.fc1(x))
       x = self.fc2(x)
       return x

x = torch.randn(NUM)
input = Variable(x)   #随机生成NUM个数据

target = Variable(0.5 * x + 0.3)   #用0.5 × x + 0.3 函生成目标数据

net = Net()   #网络对象
print(net)

optimizer = optim.SGD(net.parameters(),lr=0.01)  #随机梯度下降优化器
loss_list =[]                                #保存loss,便于画图
step = 500                                    #迭代次数

for epoch in range(step):
   optimizer.zero_grad()                    #参数梯度清零,因为会累加
   out = net(input)                         #通过一次网络的输出
   loss = nn.MSELoss()(out,target)           #计算输出与target数据的均方差
   loss_list.append(loss)                    #保存loss
   loss.backward()                           #loss反向传播
   optimizer.step()                          #更新参数w,b

plt.figure(1)
plt.plot(range(1,NUM+1),target.detach().numpy().tolist(),'*',ms=10,lw=1,color='black')
plt.plot(range(1,NUM+1),out.detach().numpy().tolist(),'o',ms=3,lw=1,color='red')
plt.show()   #画出target和输出的位置图
plt.figure(2)
plt.plot(range(1,step+1),loss_list,'o-',ms=3,lw=1,color='black')
plt.show()   #画loss图
梯度方向进行参数更新
import torch
x = torch.rand(2, 2, requires_grad=True)
learning_rate =0.1 #学习率
epoches =5 #学习周期

for epoch in range(epoches):
     y = x**2+2*x+1
     y.backward(torch.ones_like(x))
     print("grad",x.grad.data) #x的梯度值
     x.data = x.data - learning_rate*x.grad.data #更新x
     x.grad.data.zero_()
print(x.data)

grad tensor([[3.0078, 2.0366],
        [2.9530, 2.3452]])
grad tensor([[2.4063, 1.6292],
        [2.3624, 1.8761]])
grad tensor([[1.9250, 1.3034],
        [1.8899, 1.5009]])
grad tensor([[1.5400, 1.0427],
        [1.5120, 1.2007]])
grad tensor([[1.2320, 0.8342],
        [1.2096, 0.9606]])

tensor([[-0.5072, -0.6663],
        [-0.5162, -0.6158]])

2.numpy和pytorch实现线性回归

numpy实现线性回归

import numpy as np
import matplotlib.pyplot as plt
def get_fake_data(batch_size=8):
    ''' 产生随机数据:y=x*2+3,加上了一些噪声'''
    x = np.random.rand(batch_size, 1) * 5
    y = x * 2 + 3 + np.random.rand(batch_size, 1)*2
    return x, y
 
def get_gradient(theta,x,y):
    m=x.shape[0]
    Y_estimate=np.dot(x,theta)
    assert (Y_estimate.shape==(m,))
    error=Y_estimate-y
    assert (error.shape==(m,))
    cost =1.0/(2*m)*np.sum(error**2)
    #grad=(1.0/m)*np.dot(x.T,error).reshape(-1)#(2,)
    grad = (1.0 / m) * np.dot(error,x) # (2,)
    return grad,cost
def gradient_descent(x,y,iterations,alpha):
 
    theta=np.random.randn(2)
    costs=[]
    for i in range(iterations):
        grad,cost=get_gradient(theta,x,y)
        new_theta=theta-alpha*grad
        if i%100==0:
            print('{} iterations cost={}'.format(i,cost))
            costs.append(cost)
        theta=new_theta
    return costs,theta
 
def vis_data():
    # 来看看产生的x-y分布
    x, y = get_fake_data(batch_size=16)
    print(x.shape)
    print(y.shape)
    plt.scatter(np.squeeze(x), np.squeeze(y))
    plt.show()
if __name__=='__main__':
    batch_size=32
    data_x, data_y = get_fake_data(batch_size=batch_size)
    #添加一列为1的向量 实际上就是乘以 theta 就是b
    data_x=np.hstack((data_x,np.ones_like(data_x)))#(m,2)
    print(data_x)
    print(data_x.shape)
 
    costs,theta=gradient_descent(data_x,np.squeeze(data_y),iterations=50000,alpha=0.002)
    print(data_y.shape)
 
    #print(theta)
    y_predict=np.dot(data_x,theta)#theta[0]+theta[1]*data_x[:,1]
    print(y_predict.shape)
    plt.figure()

pytorch实现线性回归

import numpy as np
import matplotlib.pyplot as plt
import torch as t
 
device=t.device('cpu')
 
def get_fake_data(batch_size=8):
    ''' 产生随机数据:y=x*2+3,加上了一些噪声'''
    x = t.rand(batch_size, 1,device=device) * 5
    y = x * 2 + 3 + t.rand(batch_size, 1)*2
    return x, y
 
def vis_data():
    # 来看看产生的x-y分布
    x, y = get_fake_data(batch_size=16)
    print(x.shape)
    print(y.shape)
    plt.scatter(np.squeeze(x), np.squeeze(y))
    plt.show()
if __name__=='__main__':
    # vis_data()
 
    m=batch_size=32
    data_x, data_y = get_fake_data(batch_size=batch_size)
    #添加一列为1的向量 实际上就是乘以 theta 就是b
    data_x=t.from_numpy(np.hstack((data_x,np.ones_like(data_x))))#(m,2)
    print(data_x.shape)
 
    theta = t.randn((2, 1),requires_grad=True)
    iterations=500
    lr = 0.005  # 学习率
    losses=[]
    for i in range(iterations):
        # forward:计算loss
        y_pred = data_x.mm(theta)
        print('y_pred',y_pred.shape)
        loss = 1/(2*m) * (y_pred - data_y) ** 2
        print('loss',loss.shape)
        loss = loss.sum()
        print('loss', loss.shape)
        losses.append(loss.item())
 
        # backward:手动计算梯度
        loss.backward()
 
        # 更新参数
        theta.data.sub_(lr * theta.grad.data)
 
        # 梯度清零
        theta.grad.data.zero_()
    print('losses=',losses)
    # 画图
    plt.scatter(np.squeeze(data_x[:,0]), np.squeeze(data_y),c='red')
    y_predict=data_x.mm(theta)
    print('y_predict.shape',y_predict.shape)
    print(data_x.detach().numpy())
    plt.plot(data_x.detach().numpy()[:,0], y_predict.detach().numpy())  # predicted
	plt.show()

3.pytorch实现一个简单的神经网络

import torch
import torch.nn as nn

class ConvNet(nn.Module):
    def __init__(self):
        super().__init__()
        # 1,28x28
        self.conv1=nn.Conv2d(1,10,5) # 10, 24x24
        self.conv2=nn.Conv2d(10,20,3) # 128, 10x10
        self.fc1 = nn.Linear(20*10*10,500)
        self.fc2 = nn.Linear(500,10)
    def forward(self,x):
        in_size = x.size(0)
        out = self.conv1(x) #24
        out = F.relu(out)
        out = F.max_pool2d(out, 2, 2)  #12
        out = self.conv2(out) #10
        out = F.relu(out)
        out = out.view(in_size,-1)
        out = self.fc1(out)
        out = F.relu(out)
        out = self.fc2(out)
        out = F.log_softmax(out,dim=1)
        return out
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值