【深度学习】PyTorch的基本运算 与 构造简单神经网络模型

发布时间 2023-11-02 14:30:07作者: PythonNew_Mr.Wang

基本运算

import torch 


# 创建一个自定义的张量
t = torch.tensor([1.0, 2.0, 3.0]) 
# tensor([1., 2., 3.])

# 求平均值
t.mean()
# tensor(2.)

# 创建一个指定行列的张量
x = torch.empty(3,5)
# tensor([[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.]])

# 创建一个指定行列的张量,并且赋予随时值
y = torch.randn(3,5)
# tensor([[ 0.1658,  0.1054, -0.2066,  0.5237,  0.2796],
#        [-1.1675,  0.9865, -0.6033, -0.5623, -0.0291],
#        [ 0.5180, -1.0783,  1.2627,  2.4267, -0.7700]])

# 运算
torch.add(x,y)  +
torch.sub(x,y)  -
torch.mul(x,y)  *
torch.div(x,y)  /


# 张量指数
torch.exp(x)
# tensor([[1., 1., 1., 1., 1.],
#        [1., 1., 1., 1., 1.],
#        [1., 1., 1., 1., 1.]])

# 幂次方计算,所有元素*2
torch.pow(y,2)

# 绝对值
torch.abs(x)

# 对数
tourch.log(x)

# 正炫函数
torch.sin(t)

# 提取元素
x = torch.tensor([[1, 2, 3],[4, 5, 6]])
x[0, 1]  # tensor(2)
x[:, 1]  # 每个集合里面的第1个元素 全部取出  tensor([2, 5])
x[1, :]  # : 标识全部取出      tensor([4, 5, 6])

# 修改形状
views = x.view(-1,3)   # [[1, 2, 3],[4, 5, 6]](6个元素) / 3 = 2  (-1:自动分配集合)

# 提取 只有1个元素的
torch.tensor([2]).item()

# ones 创建的对象元素都是1   转成numpy 
a = torch.ones(5)
b = a.numpy()
a.add_(1)    # a 与 b 共享储存空间  所有俩个都会 + 1


import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)  # 将np对象转换成toroch对象
np.add(a,1,out=a)        # 将a全部+1,a 与 b 元素全部+1


# 判断GPU是否可用
torch.cuda.is_available()



# 指定使用CPU
device = torch.device("cpu")
# 在CPU上创建一个Tensor对象
y = torch.ones_like(x,device=device)
# 将CPU上创建的一个张量 移动到指定的服务上
x = x.to(device)
z = x + y
z.to('cpu',torch.double) # 将Z转移到指定的服务上进行运算

构造简单神经网络模型

class Net(nn.Module):
                
    def __init__(self):
        
        # 调用父类的__init__()方法,必要属性和方法被正确地初始化和继承到子类中
        super(Test,self).__init__()
        
        # 定义卷积神经网络
        """
            Conv2d:输入通道数、输出通道数、卷积核大小和步长
        """
        self.conv1 = nn.Conv2d(1,6,3)
        self.conv2 = nn.Conv2d(6,16,3)
        
        self.conv1.bias.requires_grad = True
        self.conv2.bias.requires_grad = True
        
        # 定义三层全连接网络
        """
            全连接层将卷积层的输出展平为一维向量,并通过线性变换将其映射到指定的输出大小。
        """
        # 全连接层将16x6x6(上一层输出的形状)个输入神经元 映射到120个输出神经元。
        self.fc1 = nn.Linear(16 * 6 * 6, 120) 
        # 120个输入神经元映射到84个输出神经元。
        self.fc2 = nn.Linear(120,84)
        # 将84个输入神经元映射到10个输出神经元,对应于最终的分类类别数。
        self.fc3 = nn.Linear(84,10)
        
        
    #  池化
    """
        最大池化会在每个区域中选择具有最大值的特征作为该区域的汇总值,这样可以保留最显著的特征信息,对于不重要的细节则进行了降采样。

        平均池化会在每个区域中计算特征的平均值作为该区域的汇总值,这样可以保留整体特征的平均值,对于整体特征的变化保持敏感。
        
    作用:
        减少特征图的尺寸:通过池化操作,可以减小特征图的尺寸,从而减少模型参数的数量和计算量,加快计算速度。
        提取重要特征:池化操作可以保留重要的特征信息,通过选择极值或平均值的方式,将特征进行汇总,从而提取出最显著的特征。
        实现平移不变性:对输入数据进行降采样,使得输入数据对于平移变化具有一定的不变性。对于图像处理任务中的物体识别和分类任务非常有用。
    """
    def forward(self,x):
        
        # 对第一层卷积神经操作
        # self.conv1(x)         # 卷积操作
        # F.relu()              # ReLU激活函数的非线性变换,将负值变为零。
        # 对经过ReLU激活的结果进行最大池化操作,max_pool2d(特征图,池化窗口的大小),在每个2x2的窗口中取最大值进行池化操作
        x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))   
        
        # 对第二层卷积神经操作
        x = F.max_pool2d(F.relu(self.conv2(x)),2)
        # 扁平化
        x = x.view(-1,self.num_flat_features(x))
        
        # 对于全连接的处理
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    # 计算总特征数 
    def num_flat_features(self,x):
        size = x.size()
        num_fuatures = 1
        for s in size:
            num_fuatures = num_fuatures * s
        return num_fuatures
    
net = Net()
net

损失函数

# 梯度清零
net.zero_grad()
# 反向传播
loss.backward()

优化模型

import torch.optim as optim

# 定义优化器(随机梯度下降)
optimizer = optim.SGD(net.parameters(), lr=0.01)
# SGD:这是随机梯度下降(Stochastic Gradient Descent)算法的实现。
# net.parameters():这是网络模型的参数,通过调用网络模型的.parameters()方法获得。
# lr=0.01:这是学习率(learning rate)的值。

# 清空梯度
optimizer.zero_grad()

input = torch.randn(1, 1, 32, 32)

# 向前传播
output = net(input)

# 计算损失  nn.MSELoss()      
loss = criterion(output, target)

# 反向传播
loss.backward()

# 更新数值
optimizer.step()