dl学习笔记:(4)简单神经网络

(1)单层正向回归网络

bx1x2z
100-0.2
110-0.05
101-0.05
1110.1

接下来我们用代码实现这组线性回归数据

import torch
x = torch.tensor([[1,0,0],[1,1,0],[1,0,1],[1,1,1]], dtype = torch.float32)
z = torch.tensor([-0.2, -0.05, -0.05, 0.1])
w = torch.tensor([-0.2,0.15,0.15])
def LinearR(x,w):zhat = torch.mv(x,w)return zhat
zhat = LinearR(x,w)
zhat

下面对这段代码做一个详细说明:

(1)tensor的定义

这里我们需要定义成浮点数的原因,是因为torch中有很多函数不接受两个类型不同的参数传入,例如这里的mv函数,如果我们省略浮点的定义,就会出现报错如下:

这种静态的编程可以说既是pytorch的优点也是缺点,优点在于如果省略了对传入参数的检查处理,就会在运行速度上快很多,尤其是传入数据量大的时候,对每一个数据进行检查是一个很慢的过程。缺点在于你需要人为记住哪些函数是可以不同类型哪些不可以,pytorch没有一个统一的标准,唯一的办法就只有自己多试几次,所以建议大家在定义tensor的时候就默认定义成为float32

另外由于很多pytorch函数不接受一维张量,所以这里我们在定义的时候也养成两个[[的二维张量的习惯

(2)精度问题

如果我们想要查看运行结果是否和答案一致的时候,我们运行下面代码会发现奇怪的现象:

那就是为什么后面三个会是false,这其实就是精度的问题了。

所以当我们人为把精度调高到30位的时候就可以发现问题了:

当数据量大的时候,会因为精度问题产生较大的误差,如果想要控制误差大小,可以使用64位浮点数,唯一的缺点就是会比较占用内存。如果我们想要忽略较小的误差可以使用下面这个函数:

通过shift+tab快捷键来查看函数参数使用,我们也可以通过调整rtol和atol控制误差大小,可以看到这里的默认参数已经挺小的了

(2)torch.nn.Linear

在使用之前,我们先给出pytorch的架构图,包含了常用的类和库

我们先给出代码再进行解释:

import torch
X = torch.tensor([[0,0],[1,0],[0,1],[1,1]], dtype = torch.float32)
output = torch.nn.Linear(2,1)
zhat = output(X)
zhat

首先nn.Linear是一个类,在这里代表了输出层,所以使用output作为变量名,output的这一行相当于是类的实例化过程。里面输入的参数2和1分别指上一层的神经元个数和这一层的神经元个数。

由于nn.Module的子类会在实例化的同时自动生成随机的w和b,所以这里我们上一层就只有两个x,又由于这是回归类模型所以输出层只有一个。我们也可以调用查看随机生成的数:

如果我们不想要bias可以设置成false:output = torch.nn.Linear(2,1,bias = False)

如果我们不想都每次都随机生成不同的权重,可以设置随机数种子:torch.random.manual_seed(250)

(3)逻辑回归

我们学习过线性回归之后,都知道线性回归能够拟合直线的线性关系,但是现实生活中的数据关系往往不是线性的,所以为了更好的拟合曲线关系,统计学家就在线性回归的方程两边加上了联系函数,这种回归也被叫做广义线性回归。而在探索联系函数的过程中,就发现了sigmoid函数。

\sigma = sigmoid(z) = \frac{1}{1+e^{-z}}

我们可以运行下面代码来画出sigmoid图像:

import numpy as np
import matplotlib.pyplot as plt# 定义Sigmoid函数
def sigmoid(x):return 1 / (1 + np.exp(-x))# 生成x轴数据
x = np.linspace(-10, 10, 400)# 计算y轴数据
y = sigmoid(x)# 绘图
plt.figure(figsize=(8, 6))
plt.plot(x, y, label="Sigmoid Function", color='b')
plt.title("Sigmoid Function")
plt.xlabel("x")
plt.ylabel("sigmoid(x)")
plt.grid(True)
plt.axhline(0, color='black',linewidth=0.5)
plt.axvline(0, color='black',linewidth=0.5)
plt.legend()
plt.show()

首先,我们可以观察函数图像,这是一个将所有数映射到(0,1)之间的函数,x趋于负无穷时,函数值趋近于0,x趋近于正无穷时,函数值趋近于1。

运行下面代码,我们可以画出sigmoid的导数图像:

import numpy as np
import matplotlib.pyplot as plt# 定义Sigmoid函数
def sigmoid(x):return 1 / (1 + np.exp(-x))# 定义Sigmoid函数的导数
def sigmoid_derivative(x):s = sigmoid(x)return s * (1 - s)# 生成x轴数据
x = np.linspace(-10, 10, 400)# 计算Sigmoid函数的导数
y_derivative = sigmoid_derivative(x)# 绘图
plt.figure(figsize=(8, 6))
plt.plot(x, y_derivative, label="Sigmoid Derivative", color='r')
plt.title("Derivative of Sigmoid Function")
plt.xlabel("x")
plt.ylabel("sigmoid'(x)")
plt.grid(True)
plt.axhline(0, color='black',linewidth=0.5)
plt.axvline(0, color='black',linewidth=0.5)
plt.legend()
plt.show()

可以发现在0处取到的导数值最大,往边上走迅速减小,所以它可以快速将数据从0的附近排开。这样的性质,让sigmoid函数拥有将连续型变量转化为离散型变量的力量,这也让它拥有了化回归类问题为分类问题的能力。

当我们将该函数以对数几率的形式表达出来的时候,会发现另一个有趣的地方。

\ln \frac{\sigma }{1-\sigma } =\ln \frac{\frac{1}{1+e^{-xw}}}{1-\frac{1}{1+e^{-xw}}} = \ln \frac{\frac{1}{1+e^{-xw}}}{\frac{e^{-xw}}{1+e^{-xw}}} = \ln\frac{1}{e^{-xw}} = \ln e^{xw} = xw

我们神奇地发现,让取对数几率后所得到的值就是我们线性回归的z,因为这个性质,在等号两边加sigmoid 的算法被称为“对数几率回归”,在英文中就是Logistic Regression,就是逻辑回归。

此时 \sigma1-\sigma之和为1,因此它们可以被我们看作是一对正反例发生的概率,即\sigma是某样本i的标签被预测为1的概率,而1-\sigma是i的标签被预测为0的概率,相比的结果就是样本i的标签被预测为1的相对概率。基于这种理解,虽然可能不严谨,逻辑回归、即单层二分类神经网络返回的结果一般被当成是概率来看待和使用。

(1)与门的实现:

x0x1x2andgate
1000
1100
1010
1111
import torch
X = torch.tensor([[1,0,0],[1,1,0],[1,0,1],[1,1,1]], dtype = torch.float32)
andgate = torch.tensor([[0],[0],[0],[1]], dtype = torch.float32)
w = torch.tensor([-0.2,0.15,0.15], dtype = torch.float32)
def LogisticR(X,w):zhat = torch.mv(X,w)sigma = torch.sigmoid(zhat)#sigma = 1/(1+torch.exp(-zhat))andhat = torch.tensor([int(x) for x in sigma >= 0.5], dtype = torch.float32)return sigma, andhat
sigma, andhat = LogisticR(X,w)
andhat

这里我们求sigma的时候用的是库里面的函数,注释的是手动写的。

唯一需要额外解释的是andhat的列表推导式:

sigma >= 0.5 会对 sigma 中的每个元素进行比较,返回一个布尔型张量,并且形状与 sigma 相同举个例子,假设 sigma = torch.tensor([0.2, 0.7, 0.5, 0.3]),那么 sigma >= 0.5 的结果会是:tensor([False,  True,  True, False])
接下来是列表推导式部分,它会遍历 sigma >= 0.5 中的每个布尔值,并将每个布尔值转化为整数(True 转化为 1False 转化为 0)。也就是说,这个列表推导式的功能是将布尔值转换为二分类的预测值(0 或 1)。

上面的例子通过列表推导式 [int(x) for x in sigma >= 0.5],会得到:[0, 1, 1, 0]

当然除了sigmoid还有很多经典的函数,例如sign,ReLU,Tanh等函数,这里我们就不再一一列出来了,用到的时候再说。

(2)torch版本实现

import torch
from torch.nn import functional as F
X = torch.tensor([[0,0],[1,0],[0,1],[1,1]], dtype = torch.float32)
torch.random.manual_seed(250) #人为设置随机数种子
dense = torch.nn.Linear(2,1)
zhat = dense(X)
sigma = F.sigmoid(zhat)
y = [int(x) for x in sigma > 0.5]
y

(4)softmax

当我们遇到多分类问题的时候,往往使用softmax来解决

Softmax 是一种常用于多分类问题的激活函数,特别是在神经网络的输出层,它将一组实数转换为一个概率分布。Softmax 是“归一化指数函数”的一种形式,其主要功能是将任意实数向量转换成一个概率分布,使得每个元素的值介于0和1之间,且所有元素的和为1。这对于多分类问题来说非常重要,因为它可以帮助我们得到不同类别的概率,从而进行分类决策。

可是由于指数的缘故,经常会发生溢出的情况,如下:

所以一般我们不手动自己写softmax,一般会调用pytorch内置的函数

你可能会疑惑为什么这个函数不会出现溢出的问题,这是因为使用了一点小技巧。

为了避免溢出,我们可以将每个输入值z_{i}减去输入向量的最大值max(z),这样可以确保计算中的指数值不会太大,仍然可以保留同样结果的相对比例。通过以下变换,我们可以得到数值稳定的 Softmax:

另外还需要解释一点的是这里的0是什么,我们可以通过快捷键查看函数的参数发现,第二个参数是维度,也就是说该函数需要你指定沿着哪一个维度进行softmax操作。

这里由于是只有一行,所以就是沿着这一行做softmax,所以维度的索引值为0,下面举几个例子:

如果是二维张量dim=1就是对两个小的张量进行softmax

这意味着 Softmax 没有对每个样本独立处理,而是计算了每个类别在所有样本中的相对比例。

我们再举一个大一点的三维张量的例子:

import torch
import torch.nn.functional as F# 输入一个 3D 张量 (batch_size, channels, height)
z = torch.tensor([[[1.0, 2.0, 3.0, 4.0],   # 第一个样本的 4 个特征值[1.0, 2.0, 3.0, 4.0],   # 第二个样本的 4 个特征值[1.0, 2.0, 3.0, 4.0]],  # 第三个样本的 4 个特征值[[5.0, 6.0, 7.0, 8.0],   # 第一个样本的 4 个特征值[5.0, 6.0, 7.0, 8.0],   # 第二个样本的 4 个特征值[5.0, 6.0, 7.0, 8.0]]]  # 第三个样本的 4 个特征值# 打印输入张量
print("输入张量:")
print(z)
print("\n")# 沿着 dim=2 计算 Softmax(计算每个特征维度的概率)
softmax_dim2 = F.softmax(z, dim=2)
print("沿着 dim=2 计算 Softmax:")
print(softmax_dim2)
print("\n")# 沿着 dim=1 计算 Softmax(计算每个类别的概率)
softmax_dim1 = F.softmax(z, dim=1)
print("沿着 dim=1 计算 Softmax:")
print(softmax_dim1)
print("\n")# 沿着 dim=0 计算 Softmax(计算每个样本的概率)
softmax_dim0 = F.softmax(z, dim=0)
print("沿着 dim=0 计算 Softmax:")
print(softmax_dim0)

由于这是一个shape为(2,3,4)的张量,所以dim=2也就是最后一个维度4的求和,所以是四个元素加起来等于1;dim=1也就是中间维度3,按照列加起来等于1;dim=0第一个维度2,所以是第一个小张量里面的加第二个小张量里面的等于1.

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

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

相关文章

三、华为交换机 Hybrid

一、Hybrid功能 Hybrid口既可以连接普通终端的接入链路(类似于Access接口),又可以连接交换机间的干道链路(类似于Trunk接口)。它允许多个VLAN的帧通过,并可以在出接口方向将某些VLAN帧的标签剥掉&#xff0…

Tensor 基本操作1 | PyTorch 深度学习实战

目录 创建 Tensor常用操作unsqueezesqueezeSoftmax代码1代码2代码3 argmaxitem 创建 Tensor 使用 Torch 接口创建 Tensor import torch参考:https://pytorch.org/tutorials/beginner/basics/tensorqs_tutorial.html 常用操作 unsqueeze 将多维数组解套&#xf…

Grafana系列之面板接入Prometheus Alertmanager

关于Grafana的仪表板Dashboard,以及面板Panel,参考Grafana系列之Dashboard。可以直接在面板上创建Alert,即所谓的Grafana Alert,参考Grafana系列之Grafana Alert。除了Grafana Alert外,面板也可接入Prometheus Alertma…

Windows 上安装 MongoDB 的 zip 包

博主介绍: 大家好,我是想成为Super的Yuperman,互联网宇宙厂经验,17年医疗健康行业的码拉松奔跑者,曾担任技术专家、架构师、研发总监负责和主导多个应用架构。 近期专注: RPA应用研究,主流厂商产…

LeetCode 2266.统计打字方案数:排列组合

【LetMeFly】2266.统计打字方案数:排列组合 力扣题目链接:https://leetcode.cn/problems/count-number-of-texts/ Alice 在给 Bob 用手机打字。数字到字母的 对应 如下图所示。 为了 打出 一个字母,Alice 需要 按 对应字母 i 次&#xff0c…

PTA乙级1001~1005【c++】

首先讲解一下PTA乙级在哪里。PTA乙级题其实就是PAT (Basic Level) Practice &#xff08;中文&#xff09; 1001 害死人不偿命的(3n1)猜想 #include<iostream> using namespace std;int main() {int cnt 0;int n;cin >> n;while(n ! 1){cnt ;if (n & 1){n …

渗透笔记1

第一天 工具&#xff1a;cs cobalt strike 4.9 / msf kali &#xff08;自带 Ubuntu&#xff09; cs cobalt strike 4.9&#xff1a;server-client server部署在云服务器上&#xff0c;client分别在各地&#xff0c;与server相连接&#xff1b;连接上后就可以共享上线主机。…

用Python实现SVM搭建金融反诈模型(含调试运行)

1.概述 信用卡盗刷一般发生在持卡人信息被不法分子窃取后&#xff0c;复制卡片进行消费或信用卡被他人冒领后激活并消费等情况下。一旦发生信用卡盗刷&#xff0c;持卡人和银行都会遭受一定的经济损失。本节要运用支持向量机分类算法搭建一个金融反欺诈模型。 2.数据集 使用…

HunyuanVideo 文生视频模型实践

HunyuanVideo 文生视频模型实践 flyfish 运行 HunyuanVideo 模型使用文本生成视频的推荐配置&#xff08;batch size 1&#xff09;&#xff1a; 模型分辨率(height/width/frame)峰值显存HunyuanVideo720px1280px129f60GHunyuanVideo544px960px129f45G 本项目适用于使用 N…

第6章 ThreadGroup详细讲解(Java高并发编程详解:多线程与系统设计)

1.ThreadGroup 与 Thread 在Java程序中&#xff0c; 默认情况下&#xff0c; 新的线程都会被加入到main线程所在的group中&#xff0c; main线程的group名字同线程名。如同线程存在父子关系一样&#xff0c; Thread Group同样也存在父子关系。图6-1就很好地说明了父子thread、父…

nginx常用配置 (含负载均衡、反向代理、限流、Gzip压缩、图片防盗链 等示例)

nginx的配置文件通常在 /etc/nginx/nginx.conf , /etc/nginx/conf.d/*.conf 中&#xff0c; 一般直接 改 conf.d目录下的 default.conf文件&#xff0c; 然后 先检测配置文件是否有错误 nginx -t 再重新加载配置文件 或 重启nginx&#xff0c;命令如下 nginx -s reload 或…

Python编程与在线医疗平台数据挖掘与数据应用交互性研究

一、引言 1.1 研究背景与意义 在互联网技术飞速发展的当下,在线医疗平台如雨后春笋般涌现,为人们的就医方式带来了重大变革。这些平台打破了传统医疗服务在时间和空间上的限制,使患者能够更加便捷地获取医疗资源。据相关报告显示,中国基于互联网的医疗保健行业已进入新的…

Linux网络_套接字_UDP网络_TCP网络

一.UDP网络 1.socket()创建套接字 #include<sys/socket.h> int socket(int domain, int type, int protocol);domain (地址族): AF_INET网络 AF_UNIX本地 AF_INET&#xff1a;IPv4 地址族&#xff0c;适用于 IPv4 协议。用于网络通信AF_INET6&#xff1a;IPv6 地址族&a…

1 行命令引发的 Go 应用崩溃

一、前言 不久前&#xff0c;阿里云 ARMS 团队、编译器团队、MSE 团队携手合作&#xff0c;共同发布并开源了 Go 语言的编译时自动插桩技术。该技术以其零侵入的特性&#xff0c;为 Go 应用提供了与 Java 监控能力相媲美的解决方案。开发者只需将 go build 替换为新编译命令 o…

R语言的并发编程

R语言的并发编程 引言 在现代计算中&#xff0c;如何有效地利用计算资源进行数据处理和分析已成为一个重要的研究方向。尤其在大数据时代&#xff0c;数据量的急剧增加让单线程处理方式显得力不从心。为了解决这一问题&#xff0c;各种编程语言都开展了并发编程的研究和应用。…

Flink(十):DataStream API (七) 状态

1. 状态的定义 在 Apache Flink 中&#xff0c;状态&#xff08;State&#xff09; 是指在数据流处理过程中需要持久化和追踪的中间数据&#xff0c;它允许 Flink 在处理事件时保持上下文信息&#xff0c;从而支持复杂的流式计算任务&#xff0c;如聚合、窗口计算、联接等。状…

C#项目生成时提示缺少引用

问题描述 刚从git或svn拉取下来的C#项目&#xff0c;在VS生成时提示缺少引用 解决方案 1、从“管理NuGet程序包”中下载并安装缺少的引用&#xff0c;如果引用较多逐个下载安装会比较麻烦&#xff0c;建议采用下面第2种方案处理 2、通过命令对所有缺少引用进行安装 &#…

EAMM: 通过基于音频的情感感知运动模型实现的一次性情感对话人脸合成

EAMM: 通过基于音频的情感感知运动模型实现的一次性情感对话人脸合成 1所有的材料都可以在EAMM: One-Shot Emotional Talking Face via Audio-Based Emotion-Aware Motion Model网站上找到。 摘要 尽管音频驱动的对话人脸生成技术已取得显著进展&#xff0c;但现有方法要么忽…

BeanFactory 是什么?它与 ApplicationContext 有什么区别?

谈到Spring&#xff0c;那势必要讲讲容器 BeanFactory 和 ApplicationContext。 BeanFactory是什么&#xff1f; BeanFactory&#xff0c;其实就是 Spring 容器&#xff0c;用于管理和操作 Spring 容器中的 Bean。可能此时又有初学的小伙伴会问&#xff1a;Bean 是什么&#x…

【深度学习】Huber Loss详解

文章目录 1. Huber Loss 原理详解2. Pytorch 代码详解3.与 MSELoss、MAELoss 区别及各自优缺点3.1 MSELoss 均方误差损失3.2 MAELoss 平均绝对误差损失3.3 Huber Loss 4. 总结4.1 优化平滑4.2 梯度较好4.3 为什么说 MSE 是平滑的 1. Huber Loss 原理详解 Huber Loss 是一种结合…