Pytorch入门学习——快速搭建神经网络、优化器、梯度计算

news2024/9/20 0:49:42

在这里插入图片描述
我的代码可以在我的Github找到
GIthub地址
https://github.com/QinghongShao-sqh/Pytorch_Study

因为最近有同学问我如何Nerf入门,这里就简单给出一些我的建议:
(1)基本的pytorch,机器学习,深度学习知识,本文介绍的pytorch知识掌握也差不多. 机器学习、深度学习零基础的话B站​吴恩达、李飞飞老师的课都可以看一看。

(2)上面这些掌握后,你就可以直接开始看Nerf论文了,就是2020最早介绍Nerf算法那篇,尝试努力去读吧,包括每个数学公式(大部分公式现在都可以在中文搜索引擎找到其解释),然后通过PaperCode Or Github找到社区同学开源的复现代码,获取(Git or 下载)下来,自己读代码,可以由总到分(先看代码框架,有哪些.py文件,再看哪些类,哪些函数以及各自的功能),然后代码再和论文里面的数学公式、表示​去联合理解。到这里你就大概知道Nerf的代码​的一个实现流程了。
(3)你在流程2之后,如果你对某一个具体的点不理解的,比如论文不会对模型的方方面面都介绍地很详细(这是不可能的),并且你十分感兴趣这个点or十分倔强一定要搞懂,你就可以针对这个不理解的点,去谷歌等地方多搜索一些资料。 比如NDC空间坐标转换(我前面有篇文章就介绍了,其坐标矩阵是如何转换转换,以及编程的)​,等等。

(4)在流程3之后,你会有自己更加深刻的理解,包括你在寻找知识过程中,这个探索过程的收获​。流程2之后当然也可以,你可以在Papercode上多看几篇nerf相关论文,个人建议20篇(代码都开源的,可以参考star比较多,方便你复现的),这20篇你就可以简单看,看看他们的摘要,介绍,工作结果,图片,以及他们的ProjectWebsite,以及Github代码中对某个模块是如何构造等等​。你知道大概Nerf方向有什么工作​是在进行,并且进行到哪一步。

(5)最近ICCV2023 CVPR2023应该都出来了,有能力的话也可以在上面找找Nerf相关的,也可以关注一些图形学顶会,然后自己做做总结​。后面具体如何基于Nerf展开研究,就是每个实验室的​工作了。
(6)最后,现在已经是2023年8月份了,从Nerf2020年出来后到今天,Nerf应该算比较流行并且基本的一个模型了,类似CNN,ResNet等等,对研究生甚至本科生来说,应该不会是比较难学的一个算法模型,因为很多资料(视频、文章)、Github代码块都有其相关的工作​,入门介绍等等。所以看到这里,新手不应该畏难,应该感到有幸运(谁知道当时csdn关于他的介绍都是一些第三方机构的付费课,还不是nerf相关的),如果你掌握了Nerf,也不用太骄傲,最近几年的Nerf相关论文工作也是真的爆炸增长,(论文投稿某顶会多次被拒( Ĭ ^ Ĭ )) 看到这里,祝大家学习之路加油!

本文将回答下面的几个问题:

(1)不构建计算图、手动实现梯度计算、手动SGD更新参数

(2)数据张量和参数张量不分离、自动计算梯度、手动SGD更新参数

(3)数据张量和参数张量不分离、自动计算梯度、手动SGD更新参数

(4)数据张量和参数张量不分离、自动计算梯度、使用Adam优化算法自动更新参数

(5)自定义操作(需手动实现前向传播、反向传播)

(6)自定义Module

(7)control flow + weight sharing

参考地址:Pytorch官方教程,强烈推荐
https://link.zhihu.com/?target=https%3A//pytorch.org/tutorials/beginner/pytorch_with_examples.html

(1)使用Numpy来编写神经网络

# Define the dimensions and sizes of the data. N represents the batch size, H represents the dimension of the hidden layer, D_in represents the input dimension, and D_out represents the output dimension
N, H, D_in, D_out= 64, 100, 1000, 10
#Generate random input data with N rows and D_in columns.
x = np.random.randn(N,D_in)
#Generate random input data with N rows and D_out columns.
y = np.random.randn(N,D_out)
#Randomly initialize the weights of the first layer, setting its dimensions to D_in rows and H columns.
w1 = np.random.randn(D_in,H)
#Randomly initialize the weights of the second layer, setting its dimensions to H rows and D_out columns.
w2 = np.random.randn(H,D_out)
# Set the learning rate
learning_rate =1e-6
# Start the iterative training process for 500 iterations.
for t in range(500):
    # Compute the output of the first layer by multiplying the input data x with the weights w1 using matrix multiplication.
    # 计算第一层的输出,使用矩阵乘法将输入数据x与第一层权重w1相乘
    h =x.dot(w1)
    # Apply the ReLU activation function, setting negative values to zero.
    h_relu = np.maximum(h,0)
    # Compute the predictions of the output layer by multiplying the output of the first layer, h_relu, with the weights of the second layer, w2.
    y_pred = h_relu.dot(w2)

    #Calculate the loss function using the sum of squared differences between the predictions and the true values.
    loss = np.square(y_pred - y).sum()
    print(t,loss)
    # Compute the gradients of the loss function with respect to the predictions, multiplied by 2 for convenience.
    grad_y_pred = 2.0 * (y_pred - y)
    # Compute the gradients of the loss function with respect to the weights of the second layer using transposed matrix multiplication
    grad_w2 = h_relu.T.dot(grad_y_pred)
    # Compute the gradients of the loss function with respect to the output of the first layer using transposed matrix multiplication.
    grad_h_relu = grad_y_pred.dot(w2.T)
    # Make a copy of the gradients of the output of this first layer
    grad_h = grad_h_relu.copy()
    #Set the gradients of the output of the first layer to zero where the output is less than zero, effectively applying the derivative of the ReLU function
    grad_h[h < 0] = 0
    #Compute the gradients of the loss function with respect to the weights of the first layer using transposed matrix multiplication.
    grad_w1 = x.T.dot(grad_h)
    #Update the weights of the first layer using gradient descent
    w1 -= learning_rate * grad_w1
    #Update the weights of the second layer using gradient descent.
    w2 -= learning_rate * grad_w2

''' Chinese explaination
import numpy as np:导入NumPy库,用于进行数值计算。

N, H, D_in, D_out = 64, 100, 1000, 10:定义了数据的维度和大小。N表示批处理的大小,H表示隐藏层的维度,D_in表示输入的维度,D_out表示输出的维度。

x = np.random.randn(N, D_in):生成一个N行D_in列的随机输入数据。

y = np.random.randn(N, D_out):生成一个N行D_out列的随机输出数据。

w1 = np.random.randn(D_in, H):随机初始化第一层权重,将其维度设置为D_in行H列。

w2 = np.random.randn(H, D_out):随机初始化第二层权重,将其维度设置为H行D_out列。

learning_rate = 1e-6:设置学习率。

for t in range(500)::开始进行迭代训练,共进行500次。

h = x.dot(w1):计算第一层的输出,使用矩阵乘法将输入数据x与第一层权重w1相乘。

h_relu = np.maximum(h, 0):激活函数ReLU,将负值变为0。

y_pred = h_relu.dot(w2):计算输出层的预测结果,将第一层的输出h_relu与第二层的权重w2相乘。

loss = np.square(y_pred - y).sum():计算损失函数,使用均方差来度量预测结果与真实结果之间的差异。

grad_y_pred = 2.0 * (y_pred - y):计算损失函数对预测结果的梯度,乘以2是为了方便后续计算。

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:将第一层输出小于0的梯度置为0,相当于ReLU的导数。

grad_w1 = x.T.dot(grad_h):计算损失函数对第一层权重的梯度,使用转置矩阵乘法。

w1 -= learning_rate * grad_w1:更新第一层权重,使用梯度下降法进行更新。

w2 -= learning_rate * grad_w2:更新第二层权重,同样使用梯度下降法进行更新。

(2)用Pytorch实现神经网络

import torch
#Sets the data type to float.
dtype = torch.float
#Sets the computation device to CPU
device = torch.device("cpu")
#Defines the dimensions and sizes of the data. N represents the batch size, H represents the dimension of the hidden layer, D_in represents the input dimension, and D_out represents the output dimension.
N, H, D_in, D_out= 64, 100, 1000, 10
#Generates a random input tensor of size N rows and D_in columns
x = torch.randn(N,D_in,device =device,dtype=dtype)
#Generates a random output tensor of size N rows and D_out columns
y = torch.randn(N,D_out,device=device,dtype=dtype)
#Randomly initializes the weights tensor of the first layer with dimensions D_in rows and H columns.
w1 = torch.randn(D_in,H,device=device,dtype=dtype)
#Randomly initializes the weights tensor of the first layer with dimensions D_in rows and H columns.
w2 = torch.randn(N,D_out,device=device,dtype=dtype)
#Sets the learning rate.
learning_rate = 1e-6
#Starts the training iteration for 500 iterations.
for t in range(500):
    #Performs matrix multiplication between the input tensor x and the weights tensor w1 to compute the output tensor h of the first layer.
    h =x.mm(w1)
    #Applies the clamp function to set all elements in tensor h that are less than 0 to 0, implementing the ReLU activation function.
    h_relu = h.clamp(min = 0)
    #Performs matrix multiplication between the output tensor h_relu of the first layer and the weights tensor w2 to compute the predicted output tensor y_pred
    y_pred = h_relu.mm(w2)
    #Computes the loss function using mean squared error to measure the difference between the predicted output and the true output.
    loss = (y_pred - y).pow(2).sum().item()
    #Prints the current iteration number and loss value every 100 iterations.
    if t % 100 == 99:
        print(t , loss)
    #Computes the gradient of the loss function with respect to the predicted output tensor. Multiplying by 2.0 is for convenience in the subsequent calculations
    grad_y_pred = 2.0* (y_pred -y)
    #Computes the gradient of the loss function with respect to the weights tensor w2 of the second layer using transpose matrix multiplication
    grad_w2 = h_relu.t().mm(grad_y_pred)
    #Computes the gradient of the loss function with respect to the output tensor h_relu of the first layer using transpose matrix multiplication.
    grad_h_relu = grad_y_pred.mm(w2.t())
    #Creates a copy of the gradient of the output tensor of the first layer
    grad_h = grad_h_relu.clone()
    #Sets the gradients in the output tensor of the first layer that are less than 0 to 0, implementing the derivative of the ReLU function
    grad_h[h<0] = 0
    #Computes the gradient of the loss function with respect to the weights tensor w1 of the first layer using transpose matrix multiplication
    grad_w1 = x.t().mm(grad_h)
    #Updates the weights tensor of the first layer using gradient descent.
    w1 -= learning_rate * grad_w1
    #Updates the weights tensor of the second layer using gradient descent
    w2 -=learning_rate *grad_w2


'''
import torch:导入PyTorch库。

dtype = torch.float:设置数据类型为浮点型。

device = torch.device("cpu"):将计算设备设置为CPU。

N, H, D_in, D_out = 64, 100, 1000, 10:定义了数据的维度和大小。N表示批处理的大小,H表示隐藏层的维度,D_in表示输入的维度,D_out表示输出的维度。

x = torch.randn(N, D_in, device=device, dtype=dtype):生成一个N行D_in列的随机输入张量。

y = torch.randn(N, D_out, device=device, dtype=dtype):生成一个N行D_out列的随机输出张量。

w1 = torch.randn(D_in, H, device=device, dtype=dtype):随机初始化第一层权重张量,将其维度设置为D_in行H列。

w2 = torch.randn(H, D_out, device=device, dtype=dtype):随机初始化第二层权重张量,将其维度设置为H行D_out列。

learning_rate = 1e-6:设置学习率。

for t in range(500)::开始进行迭代训练,共进行500次。

h = x.mm(w1):使用矩阵乘法将输入张量x与第一层权重张量w1相乘,计算第一层的输出张量h。

h_relu = h.clamp(min=0):使用clamp函数将张量h中小于0的元素设置为0,实现ReLU激活函数。

y_pred = h_relu.mm(w2):使用矩阵乘法将第一层的输出张量h_relu与第二层权重张量w2相乘,计算输出层的预测结果张量y_pred。

loss = (y_pred - y).pow(2).sum().item():计算损失函数,使用均方差来度量预测结果与真实结果之间的差异。

if t % 100 == 99::每100个迭代打印一次当前迭代的编号和损失值。

grad_y_pred = 2.0 * (y_pred - y):计算损失函数对预测结果张量的梯度,乘以2是为了方便后续计算。

grad_w2 = h_relu.t().mm(grad_y_pred):计算损失函数对第二层权重张量的梯度,使用转置矩阵乘法。

grad_h_relu = grad_y_pred.mm(w2.t()):计算损失函数对第一层输出张量的梯度,使用转置矩阵乘法。

grad_h = grad_h_relu.clone():复制第一层输出张量的梯度。

grad_h[h < 0] = 0:将第一层输出张量中小于0的梯度置为0,实现ReLU函数的导数。

grad_w1 = x.t().mm(grad_h):计算损失函数对第一层权重张量的梯度,使用转置矩阵乘法。

w1 -= learning_rate * grad_w1:使用梯度下降法更新第一层权重张量。

w2 -= learning_rate * grad_w2:使用梯度下降法更新第二层权重张量。

在每次迭代中,计算前向传播,计算损失函数,然后进行反向传播来更新权重,以此来训练神经网络模型。
'''

(3)AutoGrad 自动求导

这段代码实现了一个简单的两层全连接神经网络的训练过程,包括前向传播、计算损失、反向传播更新权重

import  torch

dtype = torch.float
device = torch.device("cpu")

N, D_in, H, D_out = 64, 1000, 100, 10

x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

learning_rate = 1e-6

for t in range(500):
    #Perform the forward pass calculation. First, multiply the input tensor x with the weight tensor w1 using matrix multiplication. Then, use the clamp function to set any values less than 0 to 0. Finally, perform matrix multiplication with the weight tensor w2 to obtain the predicted output tensor y_pred.
    y_pred = x.mm(w1).clamp(min=0).mm(w2)
    #Calculate the loss function, using mean square error to measure the difference between the predicted output and the true output.
    loss = (y_pred - y).pow(2).sum()
    #Print the current iteration number and the loss value every 100 iterations
    if t % 100 == 99:
        print(t, loss.item())
    #Enter the context of no gradient calculation to update the weights without calculating gradients.
    with torch.no_grad():
        #Update the weight tensor for the first layer using gradient descent
        w1 -= learning_rate * w1.grad
        #Update the weight tensor for the second layer using gradient descent.
        w2 -= learning_rate * w2.grad
        #Reset the gradient tensor for the weights of the first layer to zero.
        w1.grad.zero_()
        #Reset the gradient tensor for the weights of the second layer to zero.
        w2.grad.zero_()


'''
import torch:导入PyTorch库。

dtype = torch.float:将数据类型设置为float。

device = torch.device("cpu"):将计算设备设置为CPU。

N, D_in, H, D_out = 64, 1000, 100, 10:定义数据的维度和大小。N表示批量大小,D_in表示输入维度,H表示隐藏层维度,D_out表示输出维度。

x = torch.randn(N, D_in, device=device, dtype=dtype):生成一个大小为N行D_in列的随机输入张量。

y = torch.randn(N, D_out, device=device, dtype=dtype):生成一个大小为N行D_out列的随机输出张量。

w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True):随机初始化第一层的权重张量,大小为D_in行H列,并设置requires_grad=True以便计算梯度。

w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True):随机初始化第二层的权重张量,大小为H行D_out列,并设置requires_grad=True以便计算梯度。

learning_rate = 1e-6:设置学习率。

for t in range(500)::开始进行500次训练迭代。

y_pred = x.mm(w1).clamp(min=0).mm(w2):进行前向传播计算。首先,通过矩阵乘法将输入张量x与第一层的权重张量w1相乘,然后使用clamp函数将结果中小于0的元素设置为0,最后再与第二层的权重张量w2进行矩阵乘法运算,得到预测的输出张量y_pred。

loss = (y_pred - y).pow(2).sum():计算损失函数,使用均方差衡量预测输出与真实输出之间的差异。

if t % 100 == 99::每100次迭代打印当前迭代次数和损失值。

with torch.no_grad()::进入无梯度计算的上下文,以便更新权重时不计算梯度。

w1 -= learning_rate * w1.grad:使用梯度下降法更新第一层的权重张量。

w2 -= learning_rate * w2.grad:使用梯度下降法更新第二层的权重张量。

w1.grad.zero_():将第一层的权重梯度张量重置为零。

w2.grad.zero_():将第二层的权重梯度张量重置为零。

这段代码实现了一个简单的两层全连接神经网络的训练过程,包括前向传播、计算损失、反向传播更新权重。
'''

(4)定义自动求导的AutoGrad函数

以下代码自定义了autograd操作ReLU非线性层,并使用它实现我们的2层神经网络:

#以下代码自定义了autograd操作ReLU非线性层,并使用它实现我们的2层神经网络:

import  torch

class MyReLU(torch.autograd.Function):
    #Indicates that the following function is a static method, which can be called without creating an instance.
    @staticmethod
    #Forward propagation function that takes input and returns the output.
    def forward(ctx,input):
        #Saves the input tensor in the context for later use in backward propagation.
        ctx.save_for_backward(input)
        #Applies the ReLU operation to the input tensor, setting values less than 0 to 0, and returns the result.
        return input.clamp(min=0)

    @staticmethod
    # Backward propagation function that takes the gradient output and returns the gradient input.
    def backward(ctx,grad_output):
        #Retrieves the input tensor from the saved context.
        input, = ctx.saved_tensors
        #Clones the gradient output to modify it.
        grad_input = grad_output.clone()
        #Sets the gradient to 0 for positions where the input is less than 0.
        grad_input[input < 0] = 0
        #Returns the modified gradient input.
        return grad_input

dtype = torch.float
device = torch.device("cpu")

N, D_in, H, D_out = 64, 1000, 100, 10

x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

learning_rate = 1e-6
for t in range(500):
    #Creates an instance of the ReLU function.
    relu = MyReLU.apply
    #Performs forward propagation. First, it performs matrix multiplication between the input tensor x and the first layer weight tensor w1, and passes the result through the ReLU function. Then, it performs matrix multiplication between the output of the ReLU function and the second layer weight tensor w2, resulting in the predicted output tensor y_pred.
    y_pred = relu(x.mm(w1)).mm(w2)
    #Calculates the loss function, which measures the squared difference between the predicted output and the true output.
    loss = (y_pred).pow(2).sum()
    if  t % 100 == 99:
        print(t, loss.item())
    #Performs backward propagation to calculate gradients.
    loss.backward()
    #Enters a context where gradients are not computed, allowing for updating the weights without gradient calculations.
    with torch.no_grad():
        #Updates the first layer weight tensor using gradient descent.
        w1 -= learning_rate* w1.grad
        #Updates the second layer weight tensor using gradient descent.
        w2 -= learning_rate * w2.requires_grad
        #Sets the gradient of the first layer weight tensor to zero.
        w1.grad.zero_()
        #Sets the gradient of the second layer weight tensor to zero
        w1.grad.zero_()


'''
class MyReLU(torch.autograd.Function): 声明一个自定义的ReLU函数类,继承自torch.autograd.Function。

@staticmethod: 表示下面的函数是静态方法,可以在没有创建实例的情况下调用。

def forward(ctx, input): 前向传播函数,接受输入并返回结果。

ctx.save_for_backward(input): 在上下文中保存输入张量,以便在反向传播时使用。

return input.clamp(min=0): 对输入张量进行ReLU操作,将小于0的值设为0,返回结果。

def backward(ctx, grad_output): 反向传播函数,接受梯度输出并返回梯度输入。

input, = ctx.saved_tensors: 从保存的上下文中提取输入张量。

grad_input = grad_output.clone(): 克隆梯度输出,以便对其进行修改。

grad_input[input < 0] = 0: 将小于0的输入位置的梯度设为0。

return grad_input: 返回修改后的梯度输入。

dtype = torch.float: 设置张量的数据类型为浮点型。

device = torch.device("cpu"): 设置计算设备为CPU。

N, D_in, H, D_out = 64, 1000, 100, 10: 定义数据的维度和大小。

x = torch.randn(N, D_in, device=device, dtype=dtype): 生成一个随机输入张量。

y = torch.randn(N, D_out, device=device, dtype=dtype): 生成一个随机输出张量。

w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True): 随机初始化第一层权重张量,并设置requires_grad=True以便计算梯度。

w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True): 随机初始化第二层权重张量,并设置requires_grad=True以便计算梯度。

learning_rate = 1e-6: 设置学习率。

for t in range(500):: 开始训练循环,执行500次迭代。

relu = MyReLU.apply: 创建一个ReLU函数的实例。

y_pred = relu(x.mm(w1)).mm(w2): 执行前向传播计算。首先,使用输入张量x和第一层权重张量w1进行矩阵乘法,并将结果传递给ReLU函数。然后,将ReLU函数的输出和第二层权重张量w2进行矩阵乘法,得到预测的输出张量y_pred。

loss = (y_pred).pow(2).sum(): 计算损失函数,使用平方差来衡量预测输出和真实输出之间的差异。

if t % 100 == 99:: 每100次迭代打印当前迭代次数和损失值。

loss.backward(): 执行反向传播,计算梯度。

with torch.no_grad():: 进入上下文,不计算梯度,以便在更新权重时不进行梯度计算。

w1 -= learning_rate * w1.grad: 使用梯度下降更新第一层权重张量。

w2 -= learning_rate * w2.requires_grad: 使用梯度下降更新第二层权重张量。

w1.grad.zero_(): 将第一层权重张量的梯度设为零。

w1.grad.zero_(): 将第二层权重张量的梯度设为零。
'''

(5)Pytorch.nn 构建神经网络

import torch

N, D_in, H, D_out = 64, 1000, 100, 10

x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
#Create a Sequential model that sequentially contains a linear layer, ReLU activation function, and another linear layer.
model = torch.nn.Sequential(
    #Define a linear layer that maps the input dimension D_in to the hidden layer dimension H.
    torch.nn.Linear(D_in,H),
    #Define a ReLU activation function.
    torch.nn.ReLU(),
    #Define a linear layer that maps the hidden layer dimension H to the output dimension D_out.
    torch.nn.Linear(H,D_out),
)
#Define a mean squared error loss function to compute the difference between predicted output and true output.
loss_fn = torch.nn.MSELoss(reduction='sum')

learning_rate = 1e-4
for t in range(500):
    #Perform forward propagation by passing the input tensor x to the model to get the predicted output tensor y_pred.
    y_pred = model(x)
    #Compute the loss function using mean squared error to measure the difference between predicted output and true output.
    loss = loss_fn(y_pred,y)
    if t%100 == 99:
        print(t,loss.item)
    # Clear all gradients of the model.
    model.zero_grad()
    #Perform backward propagation to compute gradients.
    loss.backward()
    #Perform backward propagation to compute gradients.
    with torch.no_grad():
        #Iterate over each parameter of the model.
        for param in model.parameters():
            # Update the parameters using gradient descent.
            param -= learning_rate * param.grad



'''
import torch: 导入PyTorch库。

N, D_in, H, D_out = 64, 1000, 100, 10: 定义数据的维度和大小。

x = torch.randn(N, D_in): 生成一个随机输入张量x。

y = torch.randn(N, D_out): 生成一个随机输出张量y。

model = torch.nn.Sequential(...): 创建一个Sequential模型,按顺序包含线性层、ReLU激活函数和线性层。

torch.nn.Linear(D_in,H): 定义一个线性层,将输入维度D_in映射到隐藏层维度H。

torch.nn.ReLU(): 定义一个ReLU激活函数。

torch.nn.Linear(H,D_out): 定义一个线性层,将隐藏层维度H映射到输出维度D_out。

loss_fn = torch.nn.MSELoss(reduction='sum'): 定义一个均方误差损失函数,用于计算预测输出和真实输出之间的差异。

learning_rate = 1e-4: 设置学习率。

for t in range(500):: 开始训练循环,执行500次迭代。

y_pred = model(x): 执行前向传播计算,将输入张量x传递给模型,得到预测输出张量y_pred。

loss = loss_fn(y_pred,y): 计算损失函数,使用均方误差来衡量预测输出和真实输出之间的差异。

if t%100 == 99:: 每100次迭代打印当前迭代次数和损失值。

model.zero_grad(): 清空模型的所有梯度。

loss.backward(): 执行反向传播,计算梯度。

with torch.no_grad():: 进入上下文,不计算梯度,以便在更新参数时不进行梯度计算。

for param in model.parameters():: 对模型的每个参数进行迭代。

param -= learning_rate * param.grad: 使用梯度下降更新参数。
'''

(6)优化器,Optim

这段代码使用了PyTorch的神经网络库(torch.nn)和损失函数库(torch.nn.functional),以及优化器(torch.optim)来自动更新模型参数。新加入的部分是优化器的定义和在训练循环中使用优化器的zero_grad()、backward()和step()函数来执行梯度清零、反向传播和参数更新的步骤

import torch

N, D_in, H, D_out = 64, 1000, 100, 10

x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

model = torch.nn.Sequential(
    torch.nn.Linear(D_in, H),
    torch.nn.ReLU(),
    torch.nn.Linear(H, D_out),
)
loss_fn = torch.nn.MSELoss(reduction='sum')

learning_rate = 1e-4
#Define an Adam optimizer to update the model parameters.
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

'''
with torch.no_grad():
        for param in model.parameters():
            param -= learning_rate * param.grad'''

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

    # Compute and print loss.
    loss = loss_fn(y_pred, y)
    if t % 100 == 99:
        print(t, loss.item())

    optimizer.zero_grad()

    loss.backward()

    optimizer.step()

'''
import torch: 导入PyTorch库。

N, D_in, H, D_out = 64, 1000, 100, 10: 定义数据的维度和大小。

x = torch.randn(N, D_in): 生成一个随机输入张量x。

y = torch.randn(N, D_out): 生成一个随机输出张量y。

model = torch.nn.Sequential(...): 创建一个Sequential模型,按顺序包含线性层、ReLU激活函数和线性层。

torch.nn.Linear(D_in, H): 定义一个线性层,将输入维度D_in映射到隐藏层维度H。

torch.nn.ReLU(): 定义一个ReLU激活函数。

torch.nn.Linear(H, D_out): 定义一个线性层,将隐藏层维度H映射到输出维度D_out。

loss_fn = torch.nn.MSELoss(reduction='sum'): 定义一个均方误差损失函数,用于计算预测输出和真实输出之间的差异。

learning_rate = 1e-4: 设置学习率。

optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate): 定义一个Adam优化器,用于更新模型参数。

for t in range(500):: 开始训练循环,执行500次迭代。

y_pred = model(x): 执行前向传播计算,将输入张量x传递给模型,得到预测输出张量y_pred。

loss = loss_fn(y_pred, y): 计算损失函数,使用均方误差来衡量预测输出和真实输出之间的差异。

if t % 100 == 99:: 每100次迭代打印当前迭代次数和损失值。

optimizer.zero_grad(): 清空优化器的梯度。

loss.backward(): 执行反向传播,计算梯度。

optimizer.step(): 使用优化器来更新模型参数。

这段代码使用了PyTorch的神经网络库(torch.nn)和损失函数库(torch.nn.functional),以及优化器(torch.optim)来自动更新模型参数。新加入的部分是优化器的定义和在训练循环中使用优化器的zero_grad()、backward()和step()函数来执行梯度清零、反向传播和参数更新的步骤。
'''

(7)PyTorch: Custom nn Modules

这段代码定义了一个简单的两层神经网络模型,使用自定义的TwoLayerNet类继承了torch.nn.Module类,并通过重写forward函数实现了前向传播逻辑。训练循环中的步骤与前面的代码相似,包括前向传播、计算损失、梯度清零、反向传播和参数更新。不同之处在于使用的模型、损失函数和优化器

import torch

class TwoLayerNet(torch.nn.Module):
    #Defines the initialization function of the TwoLayerNet class, which takes input dimension D_in, hidden layer dimension H, and output dimension D_out as parameters.
    def __init__(self, D_in, H, D_out):
        #Calls the initialization function of the parent class (torch.nn.Module).
        super(TwoLayerNet, self).__init__()
        #Creates a linear layer within the TwoLayerNet class that maps the input dimension D_in to the hidden layer dimension H.
        self.linear1 = torch.nn.Linear(D_in, H)
        # Creates another linear layer within the TwoLayerNet class that maps the hidden layer dimension H to the output dimension D_out.
        self.linear2 = torch.nn.Linear(H, D_out)
    #Defines the forward propagation function of the TwoLayerNet class, which takes input tensor x as a parameter.
    def forward(self, x):
        #Performs forward propagation of the first linear layer and then applies the clamp function to clip its output to non-negative values
        h_relu = self.linear1(x).clamp(min=0)
        #Performs forward propagation of the second linear layer, taking the output of the first linear layer as input.
        y_pred = self.linear2(h_relu)
        #Returns the predicted output tensor y_pred.
        return y_pred

N, D_in, H, D_out = 64, 1000, 100, 10

x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
#Creates an instance of the TwoLayerNet class, i.e., a model object.
model = TwoLayerNet(D_in, H, D_out)
#Defines a mean squared error loss function to compute the difference between the predicted output and the true output.
criterion = torch.nn.MSELoss(reduction='sum')
#Defines a stochastic gradient descent (SGD) optimizer to update the model parameters.
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)
for t in range(500):

    y_pred = model(x)
#Computes the loss function, using mean squared error to measure the difference between the predicted output and the true output.
    loss = criterion(y_pred, y)
    if t % 100 == 99:
        print(t, loss.item())

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

'''
class TwoLayerNet(torch.nn.Module):: 定义一个名为TwoLayerNet的自定义神经网络类,继承自torch.nn.Module。

def __init__(self, D_in, H, D_out):: 定义TwoLayerNet类的初始化函数,接收输入维度D_in、隐藏层维度H和输出维度D_out作为参数。

super(TwoLayerNet, self).__init__(): 调用父类(torch.nn.Module)的初始化函数。

self.linear1 = torch.nn.Linear(D_in, H): 在TwoLayerNet类中创建一个线性层,将输入维度D_in映射到隐藏层维度H。

self.linear2 = torch.nn.Linear(H, D_out): 在TwoLayerNet类中创建另一个线性层,将隐藏层维度H映射到输出维度D_out。

def forward(self, x):: 定义TwoLayerNet类的前向传播函数,接收输入张量x作为参数。

h_relu = self.linear1(x).clamp(min=0): 执行第一个线性层的前向传播,然后使用clamp函数将其结果裁剪为非负值。

y_pred = self.linear2(h_relu): 执行第二个线性层的前向传播,将第一个线性层的输出作为输入。

return y_pred: 返回预测输出张量y_pred。

N, D_in, H, D_out = 64, 1000, 100, 10: 定义数据的维度和大小。

x = torch.randn(N, D_in): 生成一个随机输入张量x。

y = torch.randn(N, D_out): 生成一个随机输出张量y。

model = TwoLayerNet(D_in, H, D_out): 创建一个TwoLayerNet类的实例,即一个模型对象。

criterion = torch.nn.MSELoss(reduction='sum'): 定义一个均方误差损失函数,用于计算预测输出和真实输出之间的差异。

optimizer = torch.optim.SGD(model.parameters(), lr=1e-4): 定义一个随机梯度下降(SGD)优化器,用于更新模型参数。

for t in range(500):: 开始训练循环,执行500次迭代。

y_pred = model(x): 执行模型的前向传播计算,将输入张量x传递给模型,得到预测输出张量y_pred。

loss = criterion(y_pred, y): 计算损失函数,使用均方误差来衡量预测输出和真实输出之间的差异。

if t % 100 == 99:: 每100次迭代打印当前迭代次数和损失值。

optimizer.zero_grad(): 清空优化器的梯度。

loss.backward(): 执行反向传播,计算梯度。

optimizer.step(): 使用优化器来更新模型参数。

这段代码定义了一个简单的两层神经网络模型,使用自定义的TwoLayerNet类继承了torch.nn.Module类,并通过重写forward函数实现了前向传播逻辑。训练循环中的步骤与前面的代码相似,包括前向传播、计算损失、梯度清零、反向传播和参数更新。不同之处在于使用的模型、损失函数和优化器'''

(8)一个动态的神经网络模型,

使用自定义的DynamicNet类继承了torch.nn.Module类,并通过重写forward函数实现了前向传播逻辑。训练循环中的步骤与前面的代码相似,包括前向传播、计算损失、梯度清零、反向传播和参数更新。不同之处在于使用的模型、损失函数、优化器以及引入了随机循环的隐藏层。

import random
import torch

'''
一个全连接ReLU网络,每次前向传播都选取一个1-4之间的随机数n,
我们将hidden layers的数量设置为n,也就是重复调用一个中间层n次,复用它的参数。'''
"""
       For the forward pass of the model, we randomly choose either 0, 1, 2, or 3
       and reuse the middle_linear Module that many times to compute hidden layer
       representations.

       Since each forward pass builds a dynamic computation graph, we can use normal
       Python control-flow operators like loops or conditional statements when
       defining the forward pass of the model.

       Here we also see that it is perfectly safe to reuse the same Module many
       times when defining a computational graph. This is a big improvement from Lua
       Torch, where each Module could be used only once.
       """

class DynamicNet(torch.nn.Module):
    #Defines the initialization function of the DynamicNet class, which takes input dimension D_in, hidden dimension H, and output dimension D_out as parameters.
    def __init__(self, D_in, H, D_out):
        #Calls the initialization function of the parent class (torch.nn.Module).
        super(DynamicNet, self).__init__()
        #creates a linear layer within the DynamicNet class that maps the input dimension D_in to the hidden dimension H.
        self.input_linear = torch.nn.Linear(D_in, H)
        #ates a linear layer within the DynamicNet class that maps the input dimension D_in to the hidden dimension H.
        self.middle_linear = torch.nn.Linear(H, H)
        #Creates another linear layer within the DynamicNet class that maps the hidden dimension H to the output dimension D_out.
        self.output_linear = torch.nn.Linear(H, D_out)
    #Creates another linear layer within the DynamicNet class that maps the hidden dimension H to the output dimension D_out.
    def forward(self, x):
        #Creates another linear layer within the DynamicNet class that maps the hidden dimension H to the output dimension D_out.
        h_relu = self.input_linear(x).clamp(min=0)
        #Performs a random number of iterations between hidden layers, where each iteration performs a forward propagation of a hidden layer.
        for _ in range(random.randint(0, 3)):
            #Performs the forward propagation of the hidden layer linear layer and then applies the clamp function to clip its result to non-negative values.
            h_relu = self.middle_linear(h_relu).clamp(min=0)
        y_pred = self.output_linear(h_relu)
        #Performs the forward propagation of the output linear layer, taking the output of the last hidden layer as input.
        return y_pred

N, D_in, H, D_out = 64, 1000, 100, 10

x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

model = DynamicNet(D_in, H, D_out)
#Defines a mean squared error loss function to compute the difference between the predicted output and the true output.
criterion = torch.nn.MSELoss(reduction='sum')
#Defines a stochastic gradient descent (SGD) optimizer with momentum to update the model parameters.
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4, momentum=0.9)
for t in range(500):
    y_pred = model(x)
    #Computes the loss function, using mean squared error to measure the difference between the predicted output and the true output
    loss = criterion(y_pred, y)
    if t % 100 == 99:
        print(t, loss.item())
    #Clears the gradients of the optimizer.
    optimizer.zero_grad()
    #Performs the backward propagation to compute the gradients.
    loss.backward()
    #Updates the model parameters using the optimizer.
    optimizer.step()

'''
class DynamicNet(torch.nn.Module):: 定义一个名为DynamicNet的自定义神经网络类,继承自torch.nn.Module。

def __init__(self, D_in, H, D_out):: 定义DynamicNet类的初始化函数,接收输入维度D_in、隐藏层维度H和输出维度D_out作为参数。

super(DynamicNet, self).__init__(): 调用父类(torch.nn.Module)的初始化函数。

self.input_linear = torch.nn.Linear(D_in, H): 在DynamicNet类中创建一个线性层,将输入维度D_in映射到隐藏层维度H。

self.middle_linear = torch.nn.Linear(H, H): 在DynamicNet类中创建另一个线性层,将隐藏层维度H映射到隐藏层维度H。

self.output_linear = torch.nn.Linear(H, D_out): 在DynamicNet类中创建另一个线性层,将隐藏层维度H映射到输出维度D_out。

def forward(self, x):: 定义DynamicNet类的前向传播函数,接收输入张量x作为参数。

h_relu = self.input_linear(x).clamp(min=0): 执行输入线性层的前向传播,然后使用clamp函数将其结果裁剪为非负值。

for _ in range(random.randint(0, 3)):: 在隐藏层之间进行随机次数的循环,每次循环执行一个隐藏层的前向传播。

h_relu = self.middle_linear(h_relu).clamp(min=0): 执行隐藏层线性层的前向传播,然后使用clamp函数将其结果裁剪为非负值。

y_pred = self.output_linear(h_relu): 执行输出线性层的前向传播,将最后一个隐藏层的输出作为输入。

return y_pred: 返回预测输出张量y_pred。

N, D_in, H, D_out = 64, 1000, 100, 10: 定义数据的维度和大小。

x = torch.randn(N, D_in): 生成一个随机输入张量x。

y = torch.randn(N, D_out): 生成一个随机输出张量y。

model = DynamicNet(D_in, H, D_out): 创建一个DynamicNet类的实例,即一个模型对象。

criterion = torch.nn.MSELoss(reduction='sum'): 定义一个均方误差损失函数,用于计算预测输出和真实输出之间的差异。

optimizer = torch.optim.SGD(model.parameters(), lr=1e-4, momentum=0.9): 定义一个具有动量的随机梯度下降(SGD)优化器,用于更新模型参数。

for t in range(500):: 开始训练循环,执行500次迭代。

y_pred = model(x): 执行模型的前向传播计算,将输入张量x传递给模型,得到预测输出张量y_pred。

loss = criterion(y_pred, y): 计算损失函数,使用均方误差来衡量预测输出和真实输出之间的差异。

if t % 100 == 99:: 每100次迭代打印当前迭代次数和损失值。

optimizer.zero_grad(): 清空优化器的梯度。

loss.backward(): 执行反向传播,计算梯度。

optimizer.step(): 使用优化器来更新模型参数。

这段代码定义了一个动态的神经网络模型,使用自定义的DynamicNet类继承了torch.nn.Module类,并通过重写forward函数实现了前向传播逻辑。训练循环中的步骤与前面的代码相似,包括前向传播、计算损失、梯度清零、反向传播和参数更新。不同之处在于使用的模型、损失函数、优化器以及引入了随机循环的隐藏层。
'''

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/822173.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解 Java Bean 的生命周期及各个阶段解析

目录 引言&#xff1a;一、什么是Java Bean二、Bean的生命周期概述三、Bean的创建阶段四、属性设置阶段初始化阶段六、使用阶段七、销毁阶段 引言&#xff1a; Java Bean是Java编程中经常使用的重要概念&#xff0c;它是可重用、可移植、可序列化的组件。在Java开发中&#xf…

绝杀 GETPOST 嵌套的 JSON 参数

JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;常用于Web应用程序中的数据传输。在HTTP数据包信息传递时&#xff0c;JSON扮演着非常正常的角色&#xff0c;因为它是一种通用的数据格式&#xff0c;可以被多种编程语言和应用程…

Linux远程连接mysql 出错plugin caching_sha2_password could not be loaded:

问题描述&#xff1a; 今天使用SQLyog远程连接mysql时出错plugin caching_sha2_password could not be loaded问题。 但在本地cmd 进入命令行窗口&#xff1a;输入命令连接远程连接mysql&#xff0c;发现可以顺利连接。 主要问题是 MySQL可视化工具&#xff08;如&#xff1a…

Excel技巧 - 管理规则设置一行变色

如何设置某一列单元格的值大于一个值时&#xff0c;该单元格所在的一整行都变色呢&#xff1f; 1、先框选内容区域&#xff0c;点击开始&#xff0c;条件格式&#xff0c;新建规则 2、如果销量大于20&#xff0c;则该行都变为绿色 编辑格式选择&#xff1a;使用公式确定要设置…

Centos7 如何用命令直接更改配置文件里面内容

环境&#xff1a; Centos7.7 问题描述&#xff1a; Centos7 如何用命令直接更改配置文件里面内容 ifcfg-bond1文件里面DNS想替换改成114 解决方案&#xff1a; 1.使用sed命令 sed -i -e "s:匹配参数.*:匹配参数替换后的内容:g" 对应的文件路径本案例命令 se…

2022年全国硕士研究生入学统一考试管理类专业学位联考写作试题——解析版

四、写作&#xff1a;第56&#xff5e;57小题&#xff0c;共65分。其中论证有效性分析30分&#xff0c;论说文35分。 56.论证有效性分析&#xff1a;分析下述论证中存在的缺陷和漏洞&#xff0c;选择若干要点&#xff0c;写一篇600字左右的文章&#xff0c;对该论证的有效性进…

【iOS】多线程 锁问题总结

文章目录 前言1. 你理解的多线程优点缺点 2. atomic 和 nonatomic 的区别及其作用3. GCD的队列类型 - 三种队列类型4. GCD的死锁问题5. 多线程之间的区别和联系6. 进程和线程&#xff1f;进程间的通信方式线程间的通信方式 6. iOS的线程安全手段如何保证 前言 iOS 锁和多线程的…

【python小知识】python同一个函数并行计算

在Python中&#xff0c;我们可以使用多种方式来实现并行计算&#xff0c;例如使用多进程、多线程和协程等。在本文中&#xff0c;我们将重点介绍如何使用Python内置模块multiprocessing来实现同一个函数的并行计算&#xff0c;带有详细的代码和讲解。 multiprocessing模块是Pyt…

python与深度学习(十三):CNN和IKUN模型

目录 1. 说明2. IKUN模型2.1 导入相关库2.2 建立模型2.3 模型编译2.4 数据生成器2.5 模型训练2.6 模型保存2.7 模型训练结果的可视化 3. IKUN的CNN模型可视化结果图4. 完整代码 1. 说明 本篇文章是CNN的另外一个例子&#xff0c;IKUN模型&#xff0c;是自制数据集的例子。之前…

网络基础-认识每层的设备和每层的特点用途

目录 网络层次常见设备各层介绍数据链路层网络层传输层应用层 网络层次 常见设备 各层介绍 数据链路层 有了MAC地址。数据链路层工作在局域网中的&#xff0c;以帧为单位进行传输和处理数据。 网络层 网络层有了IP。不同的网络通过路由器连接成为互联网 路由器的功能:   …

element-ui中Notification 通知自定义样式、按钮及点击事件

Notification 通知用于悬浮出现在页面角落&#xff0c;显示全局的通知提醒消息。 一、自定义html页面 element-ui官方文档中说明Notification 通知组件的message 属性支持传入 HTML 片段&#xff0c;但是示例只展示了简单的html片段&#xff0c;通常不能满足开发中的更深入需要…

企业如何做好供应商管理?

在现代商业竞争激烈的环境下&#xff0c;供应商管理成为企业取得成功的重要因素之一。十年的供应商管理经验告诉我&#xff0c;建立稳固的合作关系并且持续改进供应链是企业蓬勃发展的关键。 阅读本文您将可以了解&#xff1a;1、供应商管理的重要性&#xff1b;2、管理供应商…

基于多线程实现服务器并发

看大丙老师的B站视频总结的笔记19-基于多线程实现服务器并发分析_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1F64y1U7A2/?p19&spm_id_frompageDriver&vd_sourcea934d7fc6f47698a29dac90a922ba5a3 思路&#xff1a;首先accept是有一个线程的&#xff0c;另外…

apple pencil一代的平替有哪些品牌?好用的苹果平替笔

现在几乎每个人都有一台平板iPad&#xff0c;这可以帮助他们解决很多工作和学习上的问题&#xff0c;比如在工作中处理文件&#xff0c;做一些简单的PPT&#xff0c;如果只用一根手指在iPad上触控的话&#xff0c;就会出现一些点触不准确的地方。所以&#xff0c;为iPad配备一支…

MySQL下载安装与配置以及卸载(最简单最详细的步骤)

目录 引言 一&#xff0c;下载8.0数据库 二&#xff0c;下载5.6系列数据库 三&#xff0c;启动数据库 四&#xff0c;MySQL卸载 引言 The worlds most popular open source database&#xff1a;世界上最流行的开源数据库&#xff01; 一&#xff0c;下载8.0数据库 目前MySQ…

Spark-SortShuffle原理

总结: 每个Task会先把数据发送到缓冲区中&#xff0c;缓冲区满了会排序溢写到临时文件&#xff0c;等到Task计算完成之后&#xff0c;会把这些临时文件合并成一个大文件&#xff0c;和一个index文件&#xff0c;文件内容是有序的&#xff0c;等到所有的Task计算完成之后&#…

华为数通HCIA-华为VRP系统基础

什么是VRP? VRP是华为公司数据通信产品的通用操作系统平台&#xff0c;作为华为公司从低端到核心的全系列路由器、以太网交换机、业务网关等产品的软件核心引擎。 VRP提供以下功能&#xff1a; 实现统一的用户界面和管理界面 实现控制平面功能&#xff0c;并定义转发平面接口…

fork函数 创建子进程

fork&#xff1a; fork函数调用一次&#xff0c;返回两次&#xff1b;对于子进程&#xff0c;返回值0&#xff1b; 对于父进程&#xff0c;返回的是子进程的进程ID。 #include<iostream> #include<string.h> #include<sys/unistd.h> #include<syscall.h&…

MongDB文档--基本概念

阿丹&#xff1a; 不断拓展自己的技术栈&#xff0c;不断学习新技术。 基本概念 MongoDB中文手册|官方文档中文版 - MongoDB-CN-Manual mongdb是文档数据库 MongoDB中的记录是一个文档&#xff0c;它是由字段和值对组成的数据结构。MongoDB文档类似于JSON对象。字段的值可以包…

解读北鼎股份2023上半年财报:稳营收,高品质才是重点?

从上半年大部分公司的财报来看&#xff0c;降本增效仍是主旋律。这其中北鼎股份走出了自己的风格&#xff0c;在小红书等电商平台上推出了热度颇高的话题活动&#xff0c;借用户之力完成产品推广&#xff0c;北鼎股份将消费者的价值发挥到了最大。 从2023年7月19日北鼎股份披露…