PyTorch 深度学习 || PyTorch 编程基础

news2024/12/22 18:38:07

PyTorch 编程基础

文章目录

  • PyTorch 编程基础
    • 1. backword 求梯度
    • 2. 常用的激活函数
      • 2.1 Sigmoid 函数
      • 2.2 ReLu 激活函数
      • 2.3 Leakly ReLu 激活函数
    • 2. 常用损失函数
      • 2.1 均方误差损失函数
      • 2.2 L1范数误差损失函数
      • 2.3 交叉熵损失函数
    • 3. 优化器

1. backword 求梯度

import torch

w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(x, w) 
b = torch.add(w, 1)
y = torch.mul(a, b) # y=(x+w)(w+1)
y.backward() # 分别求出两个自变量的导数

print(w.grad) # (w+1)+ (x+w) = x+2w+1 = 5
print(x.grad) # w+1 = 2

tensor([5.])

import torch

w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
for i in range(3):
    a = torch.add(x, w)
    b = torch.add(w, 1)
    y = torch.mul(a, b) # y=(x+w)(w+1)
    y.backward() # (w+1)+(x+w) = x+2w+1 = 5
    print(w.grad) # 梯度在循环过程中进行了累加

tensor([5.])
tensor([10.])
tensor([15.])

2. 常用的激活函数

最常见的神经网络连接是全连接,这种连接是一种线性加权求和形式的线性运算。当没有激活函数的情况下,随着神经网络层数的增加,这种多层的线性运算和单层的线性运算在本质上没有任何差别。因此,激活函数无论从计算还是从生物解释上都非常重要。以下是几种常用的激活函数:

2.1 Sigmoid 函数

sigmoid是激活函数的一种,它会将样本值映射到0到1之间。sigmoid的公式如下:

y = 1 1 + e − input y=\frac{1}{1+e^{-\text{input}}} y=1+einput1

import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
    return 1. / (1. + np.exp(-x))
 
def plot_sigmoid():
    x = np.arange(-10, 10, 0.1)
    y = sigmoid(x)
    plt.plot(x, y)
    plt.show()
    
if __name__ == '__main__':
    plot_sigmoid()

在这里插入图片描述

可以直接使用 PyTorch 自带的 Sigmoid 函数

import torch.nn as nn
import torch

#取一组满足标准正态分布的随机数构成3*3的张量
t1 = torch.randn(3,3)
m = nn.Sigmoid()
t2 = m(t1)
print(t1)
print(t2)

tensor([[-1.1227, 0.8743, 0.7674],
[ 0.9877, 0.1209, 1.0413],
[ 0.2607, 0.6298, -0.1863]])
tensor([[0.2455, 0.7056, 0.6830],
[0.7286, 0.5302, 0.7391],
[0.5648, 0.6524, 0.4536]])

优点:

(1)便于求导的平滑函数

(2)能压缩数据,保证数据幅度不会有问题

(3)适合用于前向传播

缺点:

(1)容易出现梯度消失(gradient vanishing)的现象:当激活函数接近饱和区时,变化太缓慢,导数接近0,根据后向传递的数学依据是微积分求导的链式法则,当前导数需要之前各层导数的乘积,几个比较小的数相乘,导数结果很接近0,从而无法完成深层网络的训练。

(2)Sigmoid的输出不是0均值的:这会导致后层的神经元的输入是非0均值的信号,这会对梯度产生影响。以 f=sigmoid(wx+b)为例, 假设输入均为正数(或负数),那么对w的导数总是正数(或负数),这样在反向传播过程中要么都往正方向更新,要么都往负方向更新,导致有一种捆绑效果,使得收敛缓慢。

(3)幂运算相对耗时

2.2 ReLu 激活函数

卷积神经网络 CNN 中常用的激活函数是 ReLu,其数学表达式为:

ReLu ( x ) = max ⁡ { 0 , x } \text{ReLu}(x)=\max\{0,x\} ReLu(x)=max{0,x}

import numpy as np
import matplotlib.pyplot as plt

def relu(x):
    return np.maximum(0,x)
 
def plot_relu():
    x=np.arange(-10,10,0.1)
    y=relu(x)
    plt.plot(x,y)
    plt.show()
    
if __name__ == '__main__':
    plot_relu()  

在这里插入图片描述

调用 PyTorch 自带的函数

import torch.nn as nn

m = nn.ReLU()
input = torch.randn(2)
output = m(input)
print(input)
print(output)

tensor([-0.8167, 1.2363])
tensor([0.0000, 1.2363])

优点:

(1)收敛速度比 sigmoid 和 tanh 快;(梯度不会饱和,解决了梯度消失问题)

(2)计算复杂度低,不需要进行指数运算

缺点:

(1)ReLu的输出不是zero-centered;

(2)Dead ReLU Problem(神经元坏死现象):某些神经元可能永远不会被激活,导致相应参数不会被更新(在负数部分,梯度为0)。产生这种现象的两个原因:参数初始化问题;learning rate太高导致在训练过程中参数更新太大。解决办法:采用Xavier初始化方法;以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法。

(3)ReLu不会对数据做幅度压缩,所以数据的幅度会随着模型层数的增加不断扩张。

2.3 Leakly ReLu 激活函数

当 ReLu 输入值为负数的时候,输出值始终为 0 0 0,其一阶导数也始终为 0 0 0,这将会导致神经元不能更新参数,也就是神经元不学习了,这种现象叫“神经元坏死”,

为了解决 ReLu 函数的这个缺点,在 ReLu 函数的负半区间引入一个泄漏(leakly)值,称为 Leakly ReLu 函数,其数学表达式为:

ReLu ( x ) = max ⁡ { α x , x } \text{ReLu}(x)=\max\{\alpha x,x\} ReLu(x)=max{αx,x}

import numpy as np
import matplotlib.pyplot as plt

def leakly_relu(x):
   return np.array([i if i > 0 else 0.05*i for i in x ])

def lea_relu_diff(x):
    return np.where(x > 0, 1, 0.01)

x = np.arange(-10, 10, step=0.01)
y_sigma = leakly_relu(x)
y_sigma_diff = lea_relu_diff(x)
axes = plt.subplot(111)
axes.plot(x, y_sigma, label='leakly_relu')
axes.legend()
plt.show()

在这里插入图片描述

import torch.nn as nn
import torch

LeakyReLU = nn.LeakyReLU(negative_slope=5e-2)
x = torch.randn(10)
value = LeakyReLU(x)
print(x)
print(value)

tensor([ 1.3149, 0.0643, 0.5569, -0.4575, 1.6295, -0.2836, -0.8015, 1.0364,
0.3108, 0.8266])
tensor([ 1.3149, 0.0643, 0.5569, -0.0229, 1.6295, -0.0142, -0.0401, 1.0364,
0.3108, 0.8266])

Leaky ReLU函数的特点:

  • Leaky ReLU函数通过把 x x x的非常小的线性分量给予负输入 0.01 x 0.01x 0.01x来调整负值的零梯度问题。
  • Leaky有助于扩大ReLU函数的范围,通常 α \alpha α的值为0.01左右。
  • Leaky ReLU的函数范围是负无穷到正无穷。

2. 常用损失函数

2.1 均方误差损失函数

loss ( x , y ) = 1 n ∥ x − y ∥ 2 2 = 1 n ∑ i = 1 n ( x i − y i ) 2 \text{loss}(\boldsymbol{x},\boldsymbol{y})=\frac{1}{n}\Vert\boldsymbol{x}-\boldsymbol{y}\Vert_2^2=\frac{1}{n}\sum_{i=1}^n(x_i-y_i)^2 loss(x,y)=n1xy22=n1i=1n(xiyi)2

import torch

input = torch.tensor([1.0, 2.0, 3.0, 4.0])
target = torch.tensor([4.0, 5.0, 6.0, 7.0])

loss_fn = torch.nn.MSELoss(reduction='mean')
loss = loss_fn(input, target)
print(loss)

tensor(9.)

2.2 L1范数误差损失函数

loss ( x , y ) = 1 n ∥ x − y ∥ 1 = 1 n ∑ i = 1 n ∣ x i − y i ∣ \text{loss}(\boldsymbol{x},\boldsymbol{y})=\frac{1}{n}\Vert\boldsymbol{x}-\boldsymbol{y}\Vert_1=\frac{1}{n}\sum_{i=1}^n\vert x_i-y_i\vert loss(x,y)=n1xy1=n1i=1nxiyi

import torch

loss = torch.nn.L1Loss(reduction='mean')
input = torch.tensor([1.0, 2.0, 3.0, 4.0])
target = torch.tensor([4.0, 5.0, 6.0, 7.0])
output = loss(input, target)
print(output)

tensor(3.)

2.3 交叉熵损失函数

h ( p , q ) = − ∑ x n p ( x ) ∗ log ⁡ q ( x ) h(p,q)=-\sum_{x}^np( x)*\log q(x) h(p,q)=xnp(x)logq(x)

import torch

entroy = torch.nn.CrossEntropyLoss()
input = torch.Tensor([[-0.1181, -0.3682, -0.2209]])
target = torch.tensor([0])

output = entroy(input, target)
print(output)

tensor(0.9862)

3. 优化器

import torch
import torch.nn
import torch.utils.data as Data
import matplotlib
import matplotlib.pyplot as plt
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"

matplotlib.rcParams['font.sans-serif'] = ['SimHei']

#准备建模数据
x = torch.unsqueeze(torch.linspace(-1, 1, 500), dim=1)
y = x.pow(3)

#设置超参数
LR = 0.01
batch_size = 15
epoches = 5
torch.manual_seed(10)

#设置数据加载器
dataset = Data.TensorDataset(x, y)
loader = Data.DataLoader(
    dataset=dataset,
    batch_size=batch_size,
    shuffle=True,
    num_workers=2)

#搭建神经网络
class Net(torch.nn.Module):
    def __init__(self, n_input, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden_layer = torch.nn.Linear(n_input, n_hidden)
        self.output_layer = torch.nn.Linear(n_hidden, n_output)

    def forward(self, input):
        x = torch.relu(self.hidden_layer(input))
        output = self.output_layer(x)
        return output

#训练模型并输出折线图
def train():
    net_SGD = Net(1, 10, 1)
    net_Momentum = Net(1, 10, 1)
    net_AdaGrad = Net(1, 10, 1)
    net_RMSprop = Net(1, 10, 1)
    net_Adam = Net(1, 10, 1)
    nets = [net_SGD, net_Momentum, net_AdaGrad, net_RMSprop, net_Adam]

    #定义优化器
    optimizer_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
    optimizer_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.6)
    optimizer_AdaGrad = torch.optim.Adagrad(net_AdaGrad.parameters(), lr=LR, lr_decay=0)
    optimizer_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
    optimizer_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
    optimizers = [optimizer_SGD, optimizer_Momentum, optimizer_AdaGrad, optimizer_RMSprop, optimizer_Adam]

    #定义损失函数
    loss_function = torch.nn.MSELoss()
    losses = [[], [], [], [], []]

    for epoch in range(epoches):
        for step, (batch_x, batch_y) in enumerate(loader):
            for net, optimizer, loss_list in zip(nets, optimizers, losses):
                pred_y = net(batch_x)
                loss = loss_function(pred_y, batch_y)
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
                loss_list.append(loss.data.numpy())

    plt.figure(figsize=(12,7))
    labels = ['SGD', 'Momentum', 'AdaGrad', 'RMSprop', 'Adam']
    for i, loss in enumerate(losses):
        plt.plot(loss, label=labels[i])
    plt.legend(loc='upper right',fontsize=15)
    plt.tick_params(labelsize=13)
    plt.xlabel('Train Step',size=15)
    plt.ylabel('Loss',size=15)
    plt.ylim((0, 0.3))
    plt.show()

if __name__ == "__main__":
    train()

在这里插入图片描述

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

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

相关文章

(十)服务器K8S集群部署SpringBoot项目实战

1.准备springboot项目 可以在 https://start.spring.io/网站准备一个项目,这里作为k8s的学习所以springboot项目中准备一个简单的访问接口即可。 2.服务器环境准备 安装Jdk 1.更新系统软件包: sudo yum update2.安装 OpenJDK 11: sudo…

陶瓷板视觉检测系统和运动控制有什么联系?

陶瓷板视觉检测系统是一种利用现代计算机视觉技术对陶瓷板进行缺陷检测的设备,而运动控制则是一种控制运动的技术,两者之间存在着密切的联系。下面我们将详细介绍陶瓷板视觉检测系统和运动控制之间的联系。 一、陶瓷板视觉检测系统 陶瓷板视觉检测系统…

Redis面试核心技术点和缓存相关问题

目录 Redis的数据结构和原理 Redis持久化:RDB和AOF Redis的集群设计 缓存雪崩、击穿、穿透 高并发场景下缓存和数据库更新策略 Redis的大key和热key和大value 本地缓存 磁盘IO和网络开销 相比于 请求内存IO 要高上千倍,如果某个数据从数据库磁盘读…

第17章:存储引擎

一、查看存储引擎 1.什么是存储引擎 MySQL的存储引擎就是表的类型 2.查看mysql存储引擎 show engines; 二、设置系统默认的存储引擎 1.查看默认的存储引擎 select default_storage_engine; 2.修改默认存储引擎 set default_storage_engineMyISAM; 三、设置表的存储引擎 …

微信小程序开发之云函数本地调试

环境 微信开发者工具 Stable 1.06.2303220云开发控制台 v1.5.47 简介 微信云开发提供了云函数本地调试功能,在本地提供了一套与线上一致的 Node.js 云函数运行环境,让开发者可以在本地对云函数调试: 在本地调试时,可以设置断点…

【MD5知识详解】【面试知识】

MD5概述: MD5消息摘要算法,属Hash算法一类。MD5算法对输入任意长度的消息进行运行,产生一个128位的消息摘要(32位的数字字母混合码)。 MD5主要特点: 不可逆,相同数据的MD5值肯定一样,不同数据的MD5值不一样 (一个MD5理…

微信小程序nodejs+vue个人身体健康管理系统56b65

开发语言 node.js 框架:Express 前端:Vue.js 数据库:mysql 数据库工具:Navicat 开发软件:VScode 。配置文件 (自动编号、配置参数值、配置参数名称); 论坛交流 (自动编号、用户id、状态、父节点id、帖子标题、用户名…

ndoejs基于Vue.js二手书交易网站系统x3oh4

开发语言 node.js 框架:Express 前端:Vue.js 数据库:mysql 数据库工具:Navicat 开发软件:VScode 本毕业设计的内容是设计并且实现一个基于vue框架的二手书交易系统。它是在Windows下,以MYSQL为数据库开发平台&#xf…

chatgpt赋能python:Python取消warning指南:如何避免和处理警告

Python取消warning指南:如何避免和处理警告 如果您已经在使用Python编程,那么您一定会遇到过警告(warning)这个问题。虽然警告有时可能很有用,但在特定情况下,它们可能会引起程序错误或产生意想不到的行为…

Depcheck 检查前端项目中未使用的依赖包

前言 随着前端项目的迭代,项目中一部分的依赖包可能没被项目所使用的,手动查找这些依赖包耗时又繁琐,有没有根据能够快速的帮助我们识别和清理项目中未使用的依赖包呢? Depcheck 简介 Depcheck 是一款用于分析项目中依赖关系的…

windows下的SVN客户端访问ubuntu下的SVN服务器

目录 第一部分 windows创建本地版本库、连接ubuntu的SVN服务器 步骤0: 步骤一:创建windows本地版本库 步骤二:checkout检测 步骤三:输入之前配置的用户名和密码 第二部分 windows上传文件至SVN服务器 步骤一:添加…

Python数据攻略-DataFrame的创建与基础特性

大家好,我是Mr数据杨,今天我带来的是一本既实用又有趣的Python教程笔记,主角是Pandas DataFrame。它就像《三国演义》中的诸葛亮,机智、实用,可以帮助我们轻松处理各种数据问题。 我们来看如何创建诸葛亮——这个Data…

实现UDP通信(socket接口函数扩展)

一、write/read到send/recv 函数原型: ussize_t send(int sockfd, const void *buf, size_t len, int flags);//发送 ussize_t recv(int sockfd, void *buf, size_t len, int flags);//接收 前三个参数同read/write一样; ussize_t read(int fd, voi…

2023CCPC河南省赛 VP记录

感觉现在的xcpc,风格越来越像CF,不是很喜欢,还是更喜欢多点算法题的比赛 VP银了,VP银也是银 感觉省赛都是思维题,几乎没有算法题,感觉像打了场大型的CF B题很简单没开出来,一直搞到最后&…

Android crash 流程详解(二):NE

源码基于:Android R 接上一篇博文:《Android crash 流程详解(一):JE》 0. 前言 在上一篇博文剖析了java layer exception 的处理流程,本文将继续剖析 Android crash 的另一部分,即 native 端的 crash,又称…

【JavaEE】网络编程之UDP套接字

目录 1、网络编程基础 2、UDP数据报套接字编程 2.1.DatagramSocket API(方法) 2.2、DatagramPacket API(方法) 2.3、InetSocketAddress API 3、基于UDP socket写一个回显服务器 3.1、服务器端 3.2 、客户端 3.3、完…

机器学习常识 21: 卷积神经网络

摘要: 卷积操作保留体现了空间相关性. 1. 卷积操作 图 1. 卷积操作 Valid 方式. 图 1 下平面标定的 3 3 3 \times 3 33 区域, 对应于个 3 3 3 \times 3 33 卷积, 这 9 9 9 个数对应着相乘, 然后相加, 获得了上平面标定的 1 1 1 个小区域的值. 注意这里不是矩阵的乘法. 卷…

《大数据技术与应用》课程实验报告|week12|实验8|Pig——高级编程环境 验证评估函数

目录 一、实验内容 二、实验目的 三、实验设备 四、实验步骤 步骤一 步骤二 步骤三 步骤四 步骤五 步骤六 步骤七 步骤八 步骤九 步骤十 步骤十一 步骤十二 步骤十三 步骤十四 步骤十五 步骤十六 五、实验结果 六、实验小结 一、实验内容 验证19.5节中的…

Apache网页的日志分割与优化

Apache网页的日志分割与优化 一、日志分割的作用二、rotatelogs 分割1.修改apache服务的主配置文件2.创建分割日志保存目录3.浏览器访问 三、AWStats 分析系统1.将安装AWStats 所需软件包传到/opt目录下2.安装 AWStats 软件包3.为要统计的站点建立配置文件4.修改自动生成的 aws…

电表的698通信协议

原文连接:https://blog.csdn.net/ss86655/article/details/109997891 该协议规定了用电信息的数据交换过程,一般用于主站与电能表之间、终端与电能表之间的数据交换,主站与终端一般用不同的客户机地址来区分。1、通信架构 有两种方向的数据…