神经网络-pytorch版本

pytorch神经网络基础

torch简介

torch和numpy

import torch
import numpy as np
np_data=np.arange(6).reshape((2,3))
torch_data=torch.from_numpy(np_data)
tensor2array=torch_data.numpy()
print(np_data,"\n",torch_data,"\n",tensor2array)

在这里插入图片描述

torch的数学运算

data=[-1,-2,1,2]
tensor=torch.FloatTensor(data)
# 绝对值abs
print(np.abs(data),"\n",torch.abs(tensor))
#三角函数sin
print(np.sin(data),"\n",torch.sin(tensor))
#mean均值
print(np.mean(data),"\n",torch.mean(tensor))# np.dot (x,y)是用于计算两个数组的点积,即对应元素相乘再相加,
# 而np.matmul (x,y)则是用于计算两个数组的矩阵乘积
data=[[1,2],[3,4]]
tensor=torch.FloatTensor(data)
print(np.matmul(data,data),"\n",torch.mm(tensor,tensor))

在这里插入图片描述

变量(variable)

在PyTorch中,Variable在早期版本中用于自动求导(autograd)的功能,但从PyTorch 0.4.0版本开始,Variable已经被弃用,取而代之的是Tensor的功能。因此,如果你使用的是PyTorch 0.4.0或更新版本,你不再需要使用Variable

以下是Variable和普通的变量(如Tensor)之间的一些区别,以及在新版本中的情况:

  1. 自动求导(Autograd):

    • Variable在早期版本中主要用于自动求导。你可以使用Variable包装一个Tensor,并在其上进行操作,PyTorch会跟踪这些操作以计算梯度。但在新版本中,Tensor自身具有自动求导功能,无需Variable
  2. In-Place操作:

    • 在早期版本中,Variable支持in-place操作(如var.data += 1),但这不是推荐的做法。在新版本中,in-place操作被明确禁止,以避免梯度计算中的错误。你应该使用.data属性来访问Tensor的数据,并避免in-place操作。
  3. 性能:

    • Variable的引入会增加一些额外的开销,因为它需要跟踪操作以进行自动求导。在新版本中,Tensor的性能更高,因为它不再需要这些额外的开销。

所以,总的来说,在PyTorch的新版本中,你应该使用Tensor而不是Variable来处理数据,因为Tensor包括了Variable的所有功能,而且性能更好。如果你在早期版本中使用Variable,你可能需要考虑升级你的代码以适应新的PyTorch版本。

什么是激励函数(activation function)

其实就是另外一个非线性函数. 比如说relu, sigmoid, tanh. 使得输出结果 y 也有了非线性的特征.

激励函数(activation)

一句话概括 Activation: 就是让神经网络可以描述非线性问题的步骤, 是神经网络变得更强大.

import torch
import torch.nn.functional as F  # 激励函数都在这里# 做一些假数据来观看图像
x=torch.linspace(-5,5,100)  # x data (tensor), shape=(100, 1)
print(x)
x_np=x.numpy()  # 换成 numpy array, 出图时用# 几种常用的激励函数
y_relu=F.relu(x).numpy()
y_sigmoid=torch.sigmoid(x).numpy()
y_sigmoid=F.sigmoid(x).numpy()
y_tanh=torch.tanh(x).numpy()
y_softplus=F.softplus(x).numpy()# 画图部分还没看matplotlib,后续再补充
import matplotlib.pyplot as plt  # python 的可视化模块, 我有教程 (https://mofanpy.com/tutorials/data-manipulation/plt/)plt.figure(1, figsize=(8, 6))
plt.subplot(221)
plt.plot(x_np, y_relu, c='red', label='relu')
plt.ylim((-1, 5))
plt.legend(loc='best')plt.subplot(222)
plt.plot(x_np, y_sigmoid, c='red', label='sigmoid')
plt.ylim((-0.2, 1.2))
plt.legend(loc='best')plt.subplot(223)
plt.plot(x_np, y_tanh, c='red', label='tanh')
plt.ylim((-1.2, 1.2))
plt.legend(loc='best')plt.subplot(224)
plt.plot(x_np, y_softplus, c='red', label='softplus')
plt.ylim((-0.2, 6))
plt.legend(loc='best')plt.show()

在这里插入图片描述
在这里插入图片描述

torch.sigmoid(x)F.sigmoid(x) 都是计算输入张量 x 上的 sigmoid 函数,它们的输出结果是一样的。在最新版本的PyTorch中,通常建议使用 torch.sigmoid(x),而不再需要导入torch.nn.functional中的F.sigmoid(x),因为PyTorch的最新版本中已经将这些激活函数作为张量的方法进行了实现。

所以,以下两行代码是等价的:

y_sigmoid = torch.sigmoid(x).numpy()
y_sigmoid = F.sigmoid(x).numpy()  # 在最新版本的PyTorch中也是有效的,但不推荐

通常情况下,建议使用 torch.sigmoid(x),因为它更符合PyTorch的现代风格。

建造第一个神经网络

关系拟合(回归)

要点

看神经网络是如何通过简单的形式将一群数据用一条线条来表示。

或者说, 是如何在数据当中找到他们的关系, 然后用神经网络模型来建立一个可以代表他们关系的线条。
在这里插入图片描述

建立数据集

import torch
import matplotlib.pyplot as pltx=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)
y=x.pow(2)+0.2*torch.rand_like(x)plt.scatter(x.numpy(),y.numpy())
plt.show()

在这里插入图片描述

x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)

这行代码使用了PyTorch库来创建一个包含100个元素的张量(tensor),该张量的值是从-1到1均匀分布的。

让我们一步一步来解释这行代码:

  1. torch.linspace(-1, 1, 100):这部分代码使用torch.linspace函数创建一个从-1到1的等间距数列,其中包含100个数值。torch.linspace函数的第一个参数是起始值(-1),第二个参数是结束值(1),第三个参数是要生成的数值的数量(100)。这将生成一个张量,其中包含了从-1到1之间的100个均匀分布的数值。

  2. torch.unsqueeze(..., dim=1):接下来,torch.unsqueeze函数被用来在张量中添加一个维度(dimension)。dim=1参数指定了要在哪个位置添加维度。在这里,我们将在第1维(即列维度)上添加一个维度。这将把原始的一维张量(形状为(100,))变成一个二维张量(形状为(100, 1)),其中有100行和1列。

最终的结果是一个形状为(100, 1)的二维张量,其中包含了从-1到1均匀分布的100个数值,每个数值都位于独立的行中。这种形式的张量通常在机器学习和深度学习中用于输入数据的处理,特别是当处理单个特征的数据时,常常需要将其转换为二维张量。

y=x.pow(2)+0.2*torch.rand_like(x)

这一行首先计算了 x 的平方,然后加上了一些噪声。让我们逐步解释:

  • x.pow(2):这部分代码计算了 x 中每个元素的平方。因为 x 是一个 PyTorch 张量,所以这个操作会对 x 中的每个元素都进行平方操作,生成一个新的张量,形状与 x 相同,但每个元素都是原来的元素的平方。

  • 0.2*torch.rand_like(x):这部分代码生成了一个与 x 具有相同形状的张量,但其中的每个元素都是从均匀分布 [0, 1) 中随机采样的数值,并且每个数值都乘以0.2。这个操作引入了一些噪声,将其与平方项相加,以创建一个新的张量 y

最终,y 包含了与 x 对应的平方项加上一些随机噪声,因此它是一个形状相同的二维张量,其中包含了与 x 相关的数值。这种操作常见于机器学习中的回归任务,其中 x 可能表示输入特征,而 y 表示对应的目标值(或标签),噪声用于模拟现实世界中的不确定性和随机性。这种情况下,模型的任务是拟合从 xy 的映射关系。

建立神经网络

# 建立神经网络
import torch
import torch.nn as nn
class Net(nn.Module):# 搭建我们的层数时要用到的信息def __init__(self,n_feature,n_hidden,n_output):super(Net,self).__init__()   #可以暂时理解为初始化,这块要弄清楚是有难度的self.hidden=nn.Linear(n_feature,n_hidden)#隐藏层,关心有多少个输入,有多少个神经元个数self.predict=nn.Linear(n_hidden,n_output)#输出层,关心有多少个输入(从隐藏层而来的神经元),有多少个输出# 神经网络前向传递的过程,真正开始搭建神经网络def forward(self,x):x=torch.relu(self.hidden(x))#我们的x过了一个hidden层,输出了n_hidden个神经元的个数x=self.predict(x) #输出层接受x并输出结果# 为什么我们的预测不用激励函数呢。因为在大多数的情况下回归问题的取值可以从负无穷到正无穷,#而用了激励函数,会把取值范围截断一部分return x
net=Net(n_feature=1,n_hidden=10,n_output=1)
print(net)

在这里插入图片描述

在这段代码中,self.hiddenself.predict 是神经网络模型 Net 类的成员变量(或属性),它们分别用来表示神经网络的隐藏层和输出层。这些成员变量的值来自于PyTorch中的 nn.Linear 类,它是PyTorch中用于创建线性层的类。

让我更详细地解释这些成员变量的来源:

  1. self.hidden = nn.Linear(n_feature, n_hidden)

    • 这一行代码创建了一个名为 hidden 的成员变量,并将其初始化为一个 nn.Linear 对象。
    • nn.Linear 类表示一个线性层,通常用于神经网络的前向传播。这个线性层将具有 n_feature 个输入特征和 n_hidden 个神经元。
    • 在神经网络的前向传播过程中,输入数据将通过 self.hidden 这个线性层,并且在传递时会经过线性变换,然后传递给激活函数(在你的代码中是ReLU),最终产生隐藏层的输出。
  2. self.predict = nn.Linear(n_hidden, n_output)

    • 类似地,这一行代码创建了一个名为 predict 的成员变量,并将其初始化为另一个 nn.Linear 对象。
    • 这个 nn.Linear 对象表示输出层,它接受来自隐藏层的输出(n_hidden 个输入特征)并生成模型的最终输出,通常在回归任务中,输出层只有一个神经元。

这些 nn.Linear 层是PyTorch中提供的模块,它们封装了神经网络中的线性变换操作,可以自动进行权重初始化以及在模型的反向传播中计算梯度。这简化了神经网络的构建和训练过程,因为你只需要定义网络的结构,而不必手动管理权重和梯度。这些操作都由PyTorch的自动微分系统自动处理。

训练网络

# 训练网路
import torch
import torch.nn as nn
import torch.optim as optim
# 创建优化器和损失函数
optimizer=optim.SGD(net.parameters(),lr=0.2)
loss_func=nn.MSELoss()
for t in range(100):prediction=net(x)               # 喂给net训练数据x,输出预测值loss=loss_func(prediction,y)    # 计算两者的误差optimizer.zero_grad()           # 清空上一步的残余更新参数值loss.backward()                 # 误差反向传播,计算参数更新值optimizer.step()                # 将参数更新值施加到net的parameters上print(loss)

在这里插入图片描述

可视化训练过程


后面学了matplotlib再放

区分类型(分类)

要点

我们来看看神经网络是怎么进行事物的分类
在这里插入图片描述

建立数据集

import torch
import matplotlib.pyplot as plt# 生成随机数据
n_data = torch.ones(100, 2)
print(n_data[:5])
x0 = torch.normal(2 * n_data, 1)
print(x0[:5])
y0 = torch.zeros(100, dtype=torch.long)
print(y0[:5])
x1 = torch.normal(-2 * n_data, 1)
print(x1[:5])
y1 = torch.ones(100, dtype=torch.long)
print(y1[:5])# 合并数据
x = torch.cat((x0, x1), 0)
print(x[:5])
y = torch.cat((y0, y1))
print(y)
# 绘制散点图
plt.scatter(x[:, 0], x[:, 1], c=y, s=100, lw=0, cmap='RdYlGn')
plt.show()

在这里插入图片描述
在这里插入图片描述
在PyTorch中,数据类型(dtype)是一个非常重要的概念,它指定了张量中元素的数据类型。在代码中,y0 = torch.zeros(100, dtype=torch.long) 将创建一个包含100个零的张量,并将其数据类型设置为 torch.long

加入 dtype=torch.long 的原因是,通常在深度学习中,torch.long 数据类型被用来表示整数类型的标签或类别。在分类任务中,标签通常是整数,每个整数代表一个不同的类别。例如,如果你正在处理一个图像分类任务,每个图像的类别标签可以是从0到(类别总数-1)的整数,这些整数用来表示不同的类别。

设置数据类型为 torch.long 有两个主要作用:

  1. 确保整数类型的存储torch.long 数据类型确保了张量中的元素都是整数。这是因为默认情况下,PyTorch 创建的张量可能具有 torch.float32(32位浮点数)数据类型,但类别标签应该是整数,因此需要显式设置数据类型为 torch.long 以确保它们被解释为整数。

  2. 与损失函数兼容:许多损失函数(例如交叉熵损失)要求标签是整数类型,因此将标签的数据类型设置为 torch.long 可以确保它们与损失函数兼容,而不会引发数据类型不匹配的错误。

总之,dtype=torch.long 的设置是为了明确指定标签张量的数据类型为整数类型,以确保与深度学习任务中的标签和损失函数兼容。如果标签是整数,通常都应该使用这种设置。

torch.cat() 是PyTorch中的一个张量拼接函数,用于将多个张量沿指定的维度进行拼接(连接)操作。这个函数的目的是将多个张量合并成一个更大的张量。让我们详细解释一下 torch.cat() 函数的用法和参数:

torch.cat(tensors, dim=0, out=None) -> Tensor

参数说明:

  • tensors:一个包含要拼接的张量(可以是一个张量列表或元组)。
  • dim:指定拼接的维度。默认是0,表示在第一个维度上进行拼接,即按行拼接。
  • out:可选参数,用于指定输出张量,如果不提供将会创建一个新的张量来保存拼接后的结果。

示例:

import torch# 创建两个张量
x = torch.tensor([[1, 2], [3, 4]])
y = torch.tensor([[5, 6]])# 在第一个维度上拼接(按行拼接)
result = torch.cat((x, y), dim=0)
print(result)

在这个示例中,我们创建了两个张量 xy,然后使用 torch.cat() 函数将它们在第一个维度(按行)上进行拼接。结果是一个新的张量 result,其中包含了两个原始张量的内容:

tensor([[1, 2],[3, 4],[5, 6]])

torch.cat() 可以用于在任何维度上进行拼接操作,你可以根据需要选择合适的维度。这在深度学习中经常用于连接不同批次的数据、连接不同特征的数据等各种情况。

plt.scatter(x[:, 0], x[:, 1], c=y, s=100, lw=0, cmap='RdYlGn')

这行代码使用了Matplotlib库的 scatter 函数来创建一个散点图,以可视化数据点。让我们逐个参数来解释这行代码:

  1. x[:, 0]x[:, 1]:这部分代码使用索引操作从 x 中选择特定的列。假设 x 是一个二维张量,这里 x[:, 0] 表示选择所有行的第一个特征,而 x[:, 1] 表示选择所有行的第二个特征。这将分别用作散点图的 x 和 y 坐标。

  2. c=y:这是 c 参数,用于设置散点的颜色。通常,c 接受一个数组,表示每个数据点的颜色。在这里,y 可能是一个数组,其中包含与 x 对应的类别或标签。这将根据标签值决定每个数据点的颜色,以区分不同的数据类别。

  3. s=100:这是 s 参数,用于设置散点的大小。在这里,所有的散点都设置为相同的大小,大小为100。

  4. lw=0:这是 lw 参数,用于设置散点的边界线宽度(linewidth)。在这里,将边界线的宽度设置为0,表示没有边界线。

  5. cmap='RdYlGn':这是 cmap 参数,用于设置颜色映射。它指定了用于将不同的标签值映射到不同颜色的颜色映射表。在这里,使用了名为 ‘RdYlGn’ 的颜色映射,它代表了一种从红色到黄色再到绿色的颜色渐变。

综合起来,这行代码创建了一个散点图,其中每个数据点的 x 和 y 坐标由 x 的两个特征决定,颜色由 y 的值决定,散点的大小相同,没有边界线,并且使用 ‘RdYlGn’ 的颜色映射表来表示不同的标签值。这种可视化方式有助于可视化数据的分布和类别信息,特别是在二维空间中。

建立神经网络

# 建立神经网络
import torch
import torch.nn as nn
class Net(nn.Module):def __init__(self,n_feature,n_hidden,n_output):super(Net,self).__init__()self.hidden=nn.Linear(n_feature,n_hidden)self.out=nn.Linear(n_hidden,n_output)def forward(self,x):x=torch.relu(self.hidden(x))x=self.out(x)return x
net=Net(n_feature=2,n_hidden=10,n_output=2)
print(net)

在这里插入图片描述

训练网络

# 训练网络import torch.optim as optim# 创建优化器和损失函数
optimizer=optim.SGD(net.parameters(),lr=0.02)
loss_func=nn.CrossEntropyLoss()for t in range(100):out=net(x)#喂给net训练数据x,输出分析值loss=loss_func(out,y)#计算两者的误差optimizer.zero_grad()#清空上一步的残余更新参数值loss.backward()#误差反向传播,计算参数更新值optimizer.step()#将参数更新值施加到net的parameters上print(loss)

在这里插入图片描述

可视化训练过程


后续再补充

快速搭建法

要点

Torch 中提供了很多方便的途径, 同样是神经网络, 能快则快, 我们看看如何用更简单的方式搭建同样的回归神经网络.

快速搭建

我们之前是这样子搭建神经网络

import torch
import torch.nn as nn
class Net(nn.Module):# 搭建我们的层数时要用到的信息def __init__(self,n_feature,n_hidden,n_output):super(Net,self).__init__()   #可以暂时理解为初始化,这块要弄清楚是有难度的self.hidden=nn.Linear(n_feature,n_hidden)#隐藏层,关心有多少个输入,有多少个神经元个数self.predict=nn.Linear(n_hidden,n_output)#输出层,关心有多少个输入(从隐藏层而来的神经元),有多少个输出# 神经网络前向传递的过程,真正开始搭建神经网络def forward(self,x):x=torch.relu(self.hidden(x))#我们的x过了一个hidden层,输出了n_hidden个神经元的个数x=self.predict(x) #输出层接受x并输出结果# 为什么我们的预测不用激励函数呢。因为在大多数的情况下回归问题的取值可以从负无穷到正无穷,#而用了激励函数,会把取值范围截断一部分return x
net=Net(n_feature=1,n_hidden=10,n_output=1)
print(net)

在这里插入图片描述
上面我们用 class 继承了一个 torch 中的神经网络结构, 然后对其进行了修改, 不过还有更快的方法

import torch.nn as nn
net=nn.Sequential(nn.Linear(1,10),nn.ReLU(),nn.Linear(10,1)
)
print(net)

在这里插入图片描述
两种方法都可以用于构建神经网络,每种方法有其优点和适用场景。让我解释一下它们的优缺点以及何时使用哪种方法:

1. 自定义类方法(第一个示例):

  • 优点:

    • 更灵活:你可以定义自己的前向传播逻辑,可以实现非常复杂的模型结构。
    • 易于理解和调试:因为你可以明确地看到每个层的定义和前向传播的计算过程,更容易理解和调试。
  • 缺点:

    • 代码量较多:相对来说,需要编写更多的代码来定义每个层和前向传播的逻辑。
    • 可读性较差:对于简单的模型,可能会感到冗长,不够紧凑。

2. Sequential 方法(第二个示例):

  • 优点:

    • 简洁:使用 nn.Sequential 可以更紧凑地定义模型结构,特别适合简单的线性模型。
    • 减少代码量:避免了手动定义每个层的繁琐过程。
  • 缺点:

    • 有限灵活性:nn.Sequential 适用于线性堆叠的模型结构,对于复杂的模型结构和非线性连接不够灵活。
    • 难以定制:如果需要在不同层之间添加自定义操作或者非线性激活函数,使用 nn.Sequential 可能会不方便。

何时使用哪种方法取决于你的需求:

  • 自定义类方法 更适合需要灵活性的情况,例如:

    • 当你需要定义复杂的非线性模型结构时。
    • 当你想要添加自定义操作或层之间的复杂连接时。
    • 当你需要更详细的控制权和可调试性。
  • Sequential 方法 更适合简单的线性模型或者需要紧凑表示的情况,例如:

    • 当你构建简单的线性堆叠模型时(例如,多层感知器)。
    • 当你只需要一系列简单的层按顺序连接,不需要复杂的结构。

通常,如果你的模型足够简单,可以使用 nn.Sequential 来简化代码。但如果你需要更高级的功能、更复杂的模型结构或者更多的控制权,那么自定义类方法会更有优势。在实践中,你可能会在不同的情况下使用这两种方法,根据任务的复杂性和要求来选择合适的方式。

保存提取

要点

训练好了一个模型, 我们当然想要保存它, 留到下次要用的时候直接提取直接用, 这就是这节的内容啦. 我们用回归的神经网络举例实现保存提取.

保存

我们先快速建造数据,搭建网络

import torch
import torch.nn as nn
import torch.optim as optim# 设置随机种子以确保可重复性
torch.manual_seed(1)#生成假数据
x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)
y=x.pow(2)+0.2*torch.rand(x.size())def save():# 建立网络net1=nn.Sequential(nn.Linear(1,10),nn.ReLU(),nn.Linear(10,1))# 定义优化器和损失函数optimizer=optim.SGD(net1.parameters(),lr=0.5)loss_func=nn.MSELoss()# 训练for t in range(100):prediction=net1(x)loss=loss_func(prediction,y)optimizer.zero_grad()loss.backward()optimizer.step()

代码解释:

  1. x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)

    • torch.linspace(-1, 1, 100) 创建了一个包含100个均匀分布在-1到1之间的数值的张量。这些值将作为输入特征 x
    • torch.unsqueeze() 函数将这个一维张量转换为一个二维张量。具体来说,dim=1 参数表示在第1维上添加一个维度,从而将原始的一维张量转换为形状为 (100, 1) 的二维张量,这样可以作为神经网络的输入。
  2. y = x.pow(2) + 0.2 * torch.rand(x.size())

    • x.pow(2) 对输入特征 x 中的每个元素进行平方操作,从而得到一个张量,其中包含了100个元素,每个元素都是输入特征的平方。
    • torch.rand(x.size()) 创建一个与 x 相同大小的随机张量,其中的值是在0到1之间均匀分布的随机数。这个随机张量表示添加到目标 y 中的噪声。
    • 最后,通过将 x.pow(2) 和随机噪声相加,得到最终的目标张量 y。这个操作在原始函数 x^2 的基础上引入了一些随机变化,模拟了真实世界中的数据噪声。

总之,这段代码用于生成一个带有噪声的数据集,其中 x 是输入特征,表示在-1到1之间均匀分布的值,y 是与 x 之间的二次函数关系,并添加了一些随机噪声,以模拟实际数据集。这种数据集常用于回归任务的训练和测试。

接下来我们有两种途径来保存(下面的代码是写在save()里的)

# 保存整个网络:
torch.save(net1,'net1.pkl')
# 仅保存网络中的参数(推荐的方式,因为速度更快且占用内存更少):
torch.save(net1.state_dict(),'net1_params.pkl')

在这里插入图片描述

提取网络

# 读取模型
def restore_net():net2=torch.load('net1.pkl')print(net2)

只提取网络参数

def restore_params():# 新建net3,确保与之前的模型架构一致net3=torch.nn.Sequential(torch.nn.Linear(1,10),torch.nn.ReLU(),torch.nn.Linear(10,1))# 将保存的参数复制到net3net3.load_state_dict(torch.load('net1_params.pkl'))print(net3)

显示结果

# 保存 net1 (1. 整个网络, 2. 只有参数)
save()# 提取整个网络
restore_net()# 提取网络参数, 复制到新网络
restore_params()

在这里插入图片描述

批训练

要点

Torch 中提供了一种帮你整理你的数据结构的东西,,叫做 DataLoader, 我们能用它来包装自己的数据,进行批训练。

DataLoader

DataLoader 是 torch 给你用来包装你的数据的工具. 所以你要讲自己的 (numpy array 或其他) 数据形式装换成 Tensor, 然后再放进这个包装器中. 使用 DataLoader 有什么好处呢? 就是他们帮你有效地迭代数据,


加速神经网络训练

优化器

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

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

相关文章

2023年已过大半,光通信领域有哪些值得关注的技术趋势?

引言:上个星期,小枣君去深圳参加了CIOE中国光博会,获得了一些光通信领域的最新技术动态进展。今天,我来和大家做一个分享。 这次光博会,整个行业的参与热情很高。据主办方统计,为期三天的展会,现…

球谐函数实现环境光照漫反射实践

该文章以及代码主要来自 图形学论文解析与复现:【论文复现】An Efficient Representation for Irradiance Environment Maps 作者:Monica的小甜甜 与原文的不同: 对一些有问题的地方进行了修改添加了注释对有疑问的地方添加了疑问点引入了其…

基于python解决鸡兔同笼问题

一、什么是鸡兔同笼问题? 鸡兔同笼问题是一个经典的数学问题。问题描述:鸡和兔子共有头数a和脚数b,求鸡和兔子的数量。 解析:设鸡的数量为x,兔子的数量为y,那么可以得到以下两个方程: 1. x y…

对抗生成网络总结

对一些基本的对抗生成网络的总结。部分内容整理自Teeyohuang’s blog 文章目录 GAN (NeurIPS, 2014)CGANDCGANStackGANPix2Pix (CVPR, 2017)CycleGAN (ICCV, 2017)SRGAN (CVPR, 2017)StyleGAN (CVPR, 2019) GAN (NeurIPS, 2014) Generative adversarial nets m i n G m a x D …

Tokenview X-ray功能:深入探索EVM系列浏览器的全新视角

Tokenview作为一家领先的多链区块浏览器,为了进一步优化区块链用户的使用体验,我们推出了X-ray(余额透视)功能。该功能将帮助您深入了解EVM系列浏览器上每个地址的交易过程,以一种直观、简洁的方式呈现地址的进出账情况…

002 Linux 权限

前言 本文将会向您介绍关于linux权限方面的内容,包括文件类型,如何切换用户、基本权限、粘滞位等等 Linux具体的用户 超级用户:可以再linux系统下做任何事情,不受限制 普通用户:在linux下做有限的事情。 超级用户的…

SSM - Springboot - MyBatis-Plus 全栈体系(八)

第二章 SpringFramework 四、SpringIoC 实践和应用 4. 基于 配置类 方式管理 Bean 4.4 实验三:高级特性:Bean 注解细节 4.4.1 Bean 生成 BeanName 问题 Bean 注解源码: public interface Bean {//前两个注解可以指定Bean的标识AliasFor…

思科的简易配置

vlan 划分配置 1. 拓扑连接 2. 终端设备配置,vlan(v2, v3)配置,模式设置 然后设置交换机 fa 0/5 口为 trunk 模式,使得不同交换机同一 vlan 下 PC 可以互连 3.测试配置结果 用 ip 地址为 192.168.1.1 的主机(PC0)向同一 vlan(v2)下的 192.…

如何统计iOS产品不同渠道的下载量?

一、前言 在开发过程中,Android可能会打出来很多的包,用于标识不同的商店下载量。原来觉得苹果只有一个商店:AppStore,如何做出不同来源的统计呢?本篇文章就是告诉大家如何做不同渠道来源统计。 二、正文 先看一下苹…

算法——快乐数

202. 快乐数 - 力扣(LeetCode) 由图可知,其实这也是一个判断循环的过程,要用到快慢指针,且相遇后,若在全为1的循环里,那么就是快乐数,若相遇后不为1,说明这不是快乐数。 …

备份数据重删

重复数据删除: 在计算中,重复数据删除是一种消除重复数据重复副本的技术。此技术用于提高存储利用率,还可以应用于网络数据传输以减少必须发送的字节数。在重复数据删除过程中,将在分析过程中识别并存储唯一的数据块或字节模式。…

HAlcon例子

气泡思想 * This example shows the use of the operator dyn_threshold for * the segmentation of the raised dots of braille chharacters. * The operator dyn_threshold is especially usefull if the * background is inhomogeneously illuminated. In this example, *…

vue3的生命周期

1.vue3生命周期官方流程图 2.vue3中的选项式生命周期 vue3中的选项式生命周期钩子基本与vue2中的大体相同,它们都是定义在 vue实例的对象参数中的函数,它们在vue中实例的生命周期的不同阶段被调用。生命周期函数钩子会在我们的实例挂载,更新…

竞赛 基于机器视觉的火车票识别系统

文章目录 0 前言1 课题意义课题难点: 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于机器视觉的火车票识别系统 该项目较为新颖,适合作为竞赛…

23下半年学习计划

大二上学期计划 现在已经是大二了,java只学了些皮毛,要学的知识还有很多,新的学期要找准方向,把要学的知识罗列,按部就班地完成计划,合理安排时间,按时完成学习任务。 学习node.js&#xff0c…

运维学习之部署Grafana

sudo nohup wget https://dl.grafana.com/oss/release/grafana-10.1.1.linux-amd64.tar.gz &后台下载压缩包,然后按一下回车键。 ps -aux | grep 15358发现有两条记录,就是还在下载中。 ps -aux | grep 15358发现有一条记录,并且tail …

一百七十八、ClickHouse——海豚调度执行ClickHouse的.sql文件

一、目的 由于数仓的ADS层是在ClickHouse中,即把Hive中DWS层的结果数据同步到ClickHouse中,因此需要在ClickHouse中建表,于是需要海豚调度执行ClickHouse的.sql文件 二、实施步骤 (一)第一步,海豚建立Cl…

Python in Visual Studio Code 2023年9月更新

作者:Courtney Webster - Program Manager, Python Extension in Visual Studio Code 排版:Alan Wang 我们很高兴地宣布 Visual Studio Code 的 Python 和 Jupyter 扩展将于 2023 年 9 月发布! 此版本包括以下内容: • 将 Python …

使用 Nginx 实现企业微信域名配置中的校验文件跳转

背景 在企业微信中配置业务域名时,通常需要在该域名的根路径下放置一个校验文件,以验证域名的所有权。然而,如果该域名是第三方的,你可能无法直接在根路径下放置文件。在这种情况下,你可以使用 Nginx 来实现校验文件的…

2023 Google 开发者大会|Mobile开发专题追踪

文章目录 前言大会介绍涉及内容MobileWebAICloud Mobile开发专题多终端应用的开发适配大屏视频流可穿戴设备电视新的设计中心 构建高质量的应用高级相机和媒体功能用户的安全和隐私更精细的视觉体验 小结 前言 哈喽大家好,我是阿Q。近期,【2023 Google …