为了小论文之李沐带你学ai(二)

一个非常非常简单的net

def synthetic_data(w,b,num_example):
  #用来生成一些噪音的函数
  x = torch.normal(0,1,(num_example,len(w))) 
  #在这里,我们实现了一个均值为0,方差为1的,样本个数为num_example,样本维数为len(w)的序列
  y = torch.matmul(x,w) + b
  #在这里,我们把x 与 w进行相乘 例子里是 1000*2的矩阵与 2*1的矩阵相乘
  y += torch.normal(0,0.01,y.shape)# 在这里我们加上均值为0,方差为0.1的白噪声
  return x , y.reshape((-1,1))
def data_iter(batch_size,features,labels):
  num_examples = len(features)#定义为样本的个数
  indices = list(range(num_examples))#这里我有一个序列,对应的序号为样本的序号
  random.shuffle(indices)#把这些样本的序号打乱
  for i in range(0,num_examples,batch_size):#在这里,循环是按照0-batchsize为Stride跳跃的
    batch_indices = torch.tensor(indices[i:min(i+batch_size,num_examples)])
    yield features[batch_indices] , labels[batch_indices]#相当于一次我随机选取batch_size的序列和laebl
def linreg(x,w,b):
  return torch.matmul(x,w) + b
  #这就是一个非常非常简单的线性层
def squared_loss(y_hat,y):
  return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
#这里定义了我们的损失函数
def sgd(params, lr, batch_size):
  with torch.no_grad():
      for param in params:
        param -= lr * param.grad / batch_size
        param.grad.zero_()
 # 一个简单的随机梯度下降算法送给大家
#main函数
lr = 0.03			#在这里定义了学习率
num_epochs = 3	#在这里定义了循环的次数,定义训练巡回	
net = linreg	#在这里我们定义了我们的网络层,但是我们的网络就是一个很简单的线性映射
loss = squared_loss	#在这里定义了我们的损失函数
batch_size = 10	#在这里定义了我们的批量的大小

true_w = torch.tensor([2, -3.4])	#初始化我们的w
true_b = 4.2			#初始化我们的bias
features, labels = synthetic_data(true_w, true_b, 1000)	#初始化一些数据
w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)	#这是我们想要训练的 w
b = torch.zeros(1, requires_grad=True)			#这里是我们想要训练的bias
for epoch in range(num_epochs):#在这里进行了三个轮回
    for X, y in data_iter(batch_size, features, labels):	#x表示特征,y表示label
        l = loss(net(X, w, b), y)  # `X`和`y`的小批量损失,在这里计算了损失
        # 因为`l`形状是(`batch_size`, 1),而不是一个标量。`l`中的所有元素被加到一起,
        # 并以此计算关于[`w`, `b`]的梯度
        l.sum().backward()	#backwoard()就是计算梯度的api
        sgd([w, b], lr, batch_size)  # 使用参数的梯度更新参数
    with torch.no_grad():
        train_l = loss(net(features, w, b), labels)
        print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')





如果使用了一些api事情又会变得如何呢

在此之前,我需要介绍一下
requires_grad这个参数
在tensor中,每一个tensor都可以记录自己的梯度,只要requires_grad=true
在后面对应的算术表达式中,使用backward()这个函数就可以了。就会对对应的tensor中的每一个
参数,计算对应与这个表达算式的梯度。

并且我还需要介绍一下

  • torch.utils.data.TensorDataset
    这其实是一个包装类,把 features 和 label包装秤TensorDataset

  • torch.utils.data.DataLoader(data,batch_size,shuffle)

    • data一定要是TensorDataset类型的,这是pytorch指定的
    • batch_size,指我们一次能从这个DataLoader中抽取多少个数据
    • shuffle:如果我们在训练的时候,用训练集的数据就必须是打乱的
  • net = torch.nn.Sequential() 这个相当于是一个容器,装载了我们的各个层

  • nn.Linear() 这个函数就是一个简单的线性层

  • net[0].weight.data.normal_(0,0.01)
    net[0].bias.data.fill_(0),从这里我们看出其实每一个层都有一个weight参数和一个bias参数,它代表了这个网络层的权重和偏移量,这个也是我们需要去训练的地方。

  • nn.MSELoss() 常用的误差函数在nn中也是有被定义的

  • torch.optim.SGD(net.parameters().lr=0.03)常用的优化函数,这个就是随机梯度下降法,传入参数和学习步长

import numpy as np
import torch
from torch.utils import data

true_w = torch.tensor([2,-3.4])

true_b = 4.2
feature,labels = synthetic_data(true_w,true_b,1000)


def load_array(data_arrays,batch_size,is_train=True):
  #构造一个pytorch的数据迭代器
  dataset = data.TensorDataset(*data_arrays)
  return data.DataLoader(dataset,batch_size,shuffle=is_train)


from torch import nn
net = nn.Sequential(nn.Linear(2,1))
net[0].weight.data.normal_(0,0.01)
net[0].bias.data.fill_(0) 

loss = nn.MSELoss() #常用的误差

trainer = torch.optim.SGD(net.parameters(),lr=0.03)

# main
num_epochs = 3
for epoch in range(num_epochs):
  for x,y in data_iter:
    l = loss(net(X),y)
    trainer.zero_grad()
    l.backward()#计算出 梯度后,用step()来更新参数
    trainer.setp()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值