首页 > 其他分享 >动手学深度学习_3 线性神经网络

动手学深度学习_3 线性神经网络

时间:2023-09-27 23:55:30浏览次数:33  
标签:labels features torch batch 动手 神经网络 线性 indices size

image

summer pocket_久岛鸥
我将会跨越七大洋,将我的爱意带到你的身边

线性回归基本概念

image
image

这里的price泛化后就是我们的y,即标签label
这里的area,age泛化后就是我们的X,即特征features

image
image

  • 当L(W,b)能够通过直接求导得到W与b,那么我们称之W与b有解析解(因为L(W,b)是一个凸函数,当求导后令导数为0,求出的W与b就是使得L(w,b)最小的参数)
    image

  • image
    这里公式上的n为学习率,他是代表在梯度方向上走的“步长”
    后面看起来比较复杂的导数其实是在说明
    image

梯度是指函数数值增长最大的方向
当梯度前面有负号,则是说明指向函数数值减少最大的方向
上面的操作都是让参数w与b向着让L(W,b)最大减少的方向变化的

线性回归的从零开始实现

  • 生成数据集
  • 读取数据集
  • 初始化模型参数
  • 定义模型
  • 定义损失函数
  • 定义优化算法
  • 训练

上述过程是一般的深度学习的一般过程
因为我们没有数据,需要用正则表达式函数创建数据所以有生成数据集这个步骤

生成数据集

%matplotlib inline
import random
import torch
from d2l import torch as d2l

#生成数据,这里模拟出来的是真实的y,x
def synthetic_data(w, b, num_examples):  #@save
    """生成y=Xw+b+噪声"""
    X = torch.normal(0, 1, (num_examples, len(w))) 
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))

true_w = torch.tensor([2, -3.4])
true_b = 4.2
#一共模拟出1000个点,得到X=features(特征),Y=labels(标签)
features, labels = synthetic_data(true_w, true_b, 1000)

# 画出上述生成的数据
d2l.set_figsize()
d2l.plt.scatter(features[:, 0].detach().numpy(), labels.detach().numpy(), 1);
d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1);

这一步中我们先设定出W与b,然后利用随机函数求出X,利用y=WX+b求出y
下面我们可以利用得出的数据X,y进行线性回归,用线性回归得出的W与b,和我们设置的W与b进行比较,差距越小,说明线性回归的效果越好


读取数据集

'''
训练模型时要对数据集进行遍历,每次抽取一小批量样本,并使用它们来更新我们的模型。 
由于这个过程是训练机器学习算法的基础,所以有必要定义一个函数, 该函数能打乱数据集中的样本并以小批量方式获取数据。
'''
# 读取数据
# 这个函数的作用就真是每一次从features和labels中随机取出batch_size个数据点出来
def data_iter(batch_size,features,labels):
    num_examples=len(features)
    print(f'len(features):{len(features)}\n')
    indices=list(range(num_examples))
    random.shuffle(indices)
    for i in range(0,num_examples,batch_size):
        batch_indices=torch.tensor(
            indices[i:min(i+batch_size,num_examples)])
        yield features[batch_indices],labels[batch_indices]

batch_size = 10        

  • range函数:range(start, stop[, step])
  • 令人震惊的是 features[batch_indices] , labels[batch_indices] 的用法,居然可以使用张量batch_indices作为下标一次取多个值
  • num_examples=len(features): features是个矩阵,len(features)得出的是其行数
  • batch_indices=torch.tensor(indices[i:min(i+batch_size,num_examples)]) 其中i:min(i+batch_size,num_examples)利用的是切片技术
  • yield:image
    就是可以简单地理解为yield是用来返回的,但是返回后函数中的状态不会销毁,下次使用next()或for再次执行时,可以接着原来的状态继续执行

如:

for X, y in data_iter(batch_size, features, labels):
    print(X, '\n', y)
    break

上述就是调用函数的一种方式

初始化模型参数

# 初始化模型参数
w=torch.normal(0,0.01,size=(2,1),requires_grad=True)
b=torch.zeros(1,requires_grad=True)

定义模型

#定义模型
def linreg(X,w,b): #@save
    return torch.matmul(X,w)+b

定义损失函数

# 定义损失函数
def squared_loss(y_hat,y):#@save
    return (y_hat-y.reshape(y_hat.shape))**2/2

定义优化算法

# 定义优化算法
#batch_size为样本个数
def sgd(params,lr,batch_size):#@save
    with torch.no_grad():
        for param in params:
            param -= lr*param.grad/batch_size
            param.grad.zero_()

训练

# 训练

# 先定义参数
lr=0.03 #学习率
num_epochs=3 #训练次数
net=linreg
loss=squared_loss

for epoch in range(num_epochs):
    for X,y in data_iter(batch_size,features,labels):
        l=loss(net(X,w,b),y)
        l.sum().backward()
        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}')

标签:labels,features,torch,batch,动手,神经网络,线性,indices,size
From: https://www.cnblogs.com/cilinmengye/p/17734676.html

相关文章

  • 2023/9/26 动手动脑
    自己构造函数传入参数,在用该类时用传入参数静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?classMyClass{privateintnumber;//实例字段publicstaticvoidmain(String[]args){MyClassmyOb......
  • 9.27日Java动手动脑练习
    1publicclassMain{2publicstaticvoidmain(String[]args){3Fooobj1=newFoo();4Fooobj2=newFoo();5System.out.println(obj1==obj2);6}7staticclassFoo{8Foo(){9}10int......
  • 水果识别系统Python+TensorFlow+卷积神经网络算法【图像识别】
    引言随着科技的发展,我们生活中的各种便利工具日益增加。例如,你有没有想过,当你在超市里看到一个陌生的水果,却不知道它是什么名字时,有一个工具可以帮你识别出来?今天,我要为大家介绍一种基于Python的水果识别系统。这个系统不仅识别准确,还具有友好的用户界面。下面,让我们一起探索这个......
  • HarmonyOS线性容器特性及使用场景
    线性容器实现能按顺序访问的数据结构,其底层主要通过数组实现,包括ArrayList、Vector、List、LinkedList、Deque、Queue、Stack七种。线性容器,充分考虑了数据访问的速度,运行时(Runtime)通过一条字节码指令就可以完成增、删、改、查等操作。ArrayListArrayList即动态数组,可用来构造全局......
  • Java动手动脑
    动手动脑Ⅰ程序为什么出错:因为构造函数仅有有参构造。如果类提供了一个自定义的构造方法,将导致系统不再提供默认构造方法。 试验publicclassMain{publicstaticvoidmain(String[]args){dn=newd();System.out.println(n.t);n=newd......
  • HarmonyOS线性容器特性及使用场景
     线性容器实现能按顺序访问的数据结构,其底层主要通过数组实现,包括ArrayList、Vector、List、LinkedList、Deque、Queue、Stack七种。线性容器,充分考虑了数据访问的速度,运行时(Runtime)通过一条字节码指令就可以完成增、删、改、查等操作。ArrayListArrayList即动态数组,可用来......
  • 动手动脑
    1.     2.  3. 把类叠加写了把Foo写在了Test里4.  publicInitializeBlockClass(){}说了算 我认为这个是看初始化的时候参数的个数和类型,调用相应的函数,在两者都没有的前提下才会调用{}模块;5.   总结:首先执行父类的静态块,然后执行子......
  • 对期望线性性的理解以及例题:洛谷P3239
    \(E(X+Y)\)中\(X+Y\)到底什么意思?我们不妨设\(X\)对应事件1,他有一个样本空间\(\Omega_{1}\),这个样本空间中的每一个事件对应一个取值同理我们对\(Y\)也搞一个\(\Omega_{2}\)。那么\(X+Y\)指的就是\(X\)和\(Y\)的笛卡尔积两个集合的笛卡尔积指的是从这两个集合分别各取一个元素......
  • 2023/09/26 动手动脑
    Java的类在构造时会提供一个无参的构造方法,如果已存在用户已经自定义的构造方法,则原有的无参构造方法将无法调用,只能调用自己定义的构造方法。静态初始化的执行顺序:classRoot{static{System.out.println("Root的静态初始化块");}{Syst......
  • 线性规划学习
    线性规划学习笔记\(1\)线性规划定义定义\(1.1\)\(\bullet\)已知一组实数\(a_1,a_2,\cdots,a_n\),以及一组变量\(x_1,x_2,\cdots,x_n\),在这些变量的一个线性函数定义为\(f(x_1,x_2,\cdots,x_n)=\sum_{i=1}\limits^na_ix_i\)。\(\bullet\)等式\(f(x_1,x_2,\cdots......