深度学习 | Pytorch深度学习实践 (Chapter 1~9)

一、overview

 基于pytorch的深度学习的四个步骤基本如下:

        



二、线性模型 - Linear Model

基本概念

  • 数据集分为测试集和训练集(训练集、开发集)
  • 训练集(x,y)测试集只给(x)
  • 过拟合:模型学得太多导致性能不好
  • 开发集:测验模型泛化能力
  • zip:从数据集中,按数据对儿取出自变量x_val和真实值y_val


         

  • 本例中进行人工training,穷举法
  • 定义前向传播函数forward
  • 定义损失函数loss
  • MSE:平均平方误差
  • zip:从数据集中,按数据对儿取出自变量x_val和真实值y_val
import numpy as np
import matplotlib.pyplot as pltx_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]def forward(x):#定义模型return x * wdef loss(x,y):#定义损失函数y_pred = forward(x)return (y_pred - y) * (y_pred - y)w_list=[]#权重
mse_list=[]
for w in np.arange(0.0,4.1,0.1):print('w=',w)l_sum = 0for x_val,y_val in zip(x_data,y_data):y_pred_val = forward(x_val)loss_val = loss(x_val,y_val)l_sum += loss_valprint('\t',x_val,y_val,y_pred_val,loss_val)print('MSE=',l_sum / 3)w_list.append(w)mse_list.append(l_sum / 3)plt.plot(w_list,mse_list)
plt.ylabel('Loss')
plt.xlabel('w')
plt.show()

         


注:模型训练可视化

wisdom:可视化工具包



三、梯度下降 - Gradient Descent

 3.1、梯度下降

(基于cost function 即所有样本):

如我们想要找到w的最优值

        

  • 贪心思想:每一次迭代得到局部最优,往梯度的负方向走
  • 梯度下降算法很难找到全局最优,但是在深度学习中损失函数中,全局最优最有很少出现,但会出现鞍点(梯度 = 0)

        

import numpy as np
import matplotlib.pyplot as pltw = 1.0
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]def forward(x):return x * wdef cost(xs,ys):cost = 0for x,y in zip(xs,ys):y_pred = forward(x)cost += (y_pred-y)**2return cost / len(xs)def gradient(xs,ys):grad = 0for x,y in zip(xs,ys):grad += 2 * x * ( x * w - y)return grad / len(xs)epoch_list=[]
cost_list=[]
print('Predict (before training)',4,forward(4))
for epoch in range(100):cost_val = cost(x_data,y_data)grad_val = gradient(x_data,y_data)w -= 0.01 * grad_valprint('Epoch',epoch,'w=',w,'loss=',cost_val)epoch_list.append(epoch)cost_list.append(cost_val)
print('Predict (after training)',4,forward(4))print('Predict (after training)',4,forward(4))
plt.plot(epoch_list,cost_list)
plt.ylabel('Loss')
plt.xlabel('epoch')
plt.show()

         

  • 注:训练过程会趋近收敛
  • 若生成图像局部震荡很大,可以进行指数平滑
  • 若图像发散,则训练失败,通常原因是因为学习率过大


3.2、随机梯度下降 Stochastic Gradient Descent

(基于单个样本的损失函数):

 —— 因为函数可能存在鞍点,使用一个样本就引入了随机性

此时梯度更新公式为:

         

与之前的区别:

  • cost改为loss
  • 梯度求和变为单个样本
  • 训练过程中要对每一个样本求梯度进行更新
  • 由于两个样本的梯度下降不能并行化,时间复杂度太高
  • 所以折中的方式:使用 Mini-Batch 批量随机梯度下降
  • 若干个一组,后续将会涉及
import numpy as np
import matplotlib.pyplot as pltw = 1.0
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]def forward(x):return x * wdef loss(x,y):y_pred = forward(x)return (y_pred-y)**2def gradient(x,y):return 2 * x * (x * w - y)loss_list=[]
epoch_list=[]
print('Predict (before training)',4,forward(4))for epoch in range(100):for x,y in zip(x_data,y_data):grad = gradient(x,y)w = w - 0.01 * gradprint('\tgrad',x,y,grad)l = loss(x,y)loss_list.append(l)epoch_list.append(epoch)print("progress",epoch,'w=',w,'loss=',l)print('Predict (after training)',4,forward(4))
plt.plot(epoch_list,loss_list)
plt.ylabel('Loss')
plt.xlabel('epoch')
plt.show()

         

         



四 、反向传播 - BackPropagation

对于复杂的网络:

举例来讲两层神经网络

        

若进行线性变换,不管多少层,最终都可以统一成一种形式,但为了让你不能在化简(即提高模型复杂程度),所以我们要对每一层最终的输出

加一个非线性的变化函数(比如sigmiod)

        

则层层叠加若需要求梯度的话就要用到  —— 链式求导:

  • 1、构建计算图 —— 前馈计算(Forward)先计算最终的loss

        

  • 2、反馈(Backward)

         

 来看一下最简单的线性模型中的计算图的计算过程:

        


        

在pytorch中,使用tensor类型的数据

        

import torch
import matplotlib.pyplot as pltx_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]w = torch.Tensor([1.0]) #注意这里一定要加[] 权重初始值
w.requires_grad = Truedef forward(x):return x * w #因为w是Tensor,这里的运算符已经被重载了,x会进行自动转换,即构造了计算图def loss(x,y):y_pred = forward(x)return (y_pred - y) ** 2epoch_list = []
loss_list = []
print('Predict (before training)',4,forward(4))for epoch in range(100):#sum=0for x,y in zip(x_data,y_data):l = loss(x,y) #只要一做backward计算图会释放,会准备下一次的图l.backward()print('\tgrad:',x,y,w.grad.item()) #item将梯度数值直接拿出来为标量w.data = w.data - 0.01 * w.grad.data #grad必须要取到data#sum += l 但l为张量,计算图,进行加法计算会构造计算图,将会发生溢出w.grad.data.zero_() #!!!权重里面梯度的数据必须显式清零print("progress",epoch,l.item())epoch_list.append(epoch)loss_list.append(l.item())print('Predict (after training)',4,forward(4))
plt.plot(epoch_list,loss_list)
plt.ylabel('Loss')
plt.xlabel('epoch')
plt.show()

         



五、利用PyTorch实现线性回归模型 - Linear Regression With PyTorch

pytorch神经网络四步走

  • 1、构建数据集
  • 2、设计模型(用来计算y_hat)
  • 3、构建损失函数和优化器(我们使用pytorch封装的API)
  • 4、训练周期(前馈 反馈 更新)

本例将使用 Mini-Batch,numpy有广播机制矩阵相加会自动扩充。

         

 使用pytorch的关键就不在于求梯度了,而是构建计算图,这里使用仿射模型,也叫线性单元。

代码实现:

import torch
import matplotlib.pyplot as plt# 1、准备数据
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[2.0],[4.0],[6.0]])# 2、构建模型
class LinearModel(torch.nn.Module):def __init__(self): #构造函数super(LinearModel,self).__init__()self.linear = torch.nn.Linear(1,1) #构造一个对象def forward(self,x):y_pred = self.linear(x) #实现可调用对象return y_predmodel = LinearModel()# 3、构造损失函数和优化器
criterion = torch.nn.MSELoss(size_average=False) #继承nn.Module,是否求平均
optimizer = torch.optim.SGD(model.parameters(),lr=0.01) #是一个类,不继承nn.Module,不会构建计算图,lr学习率epoch_list = []
loss_list = []for epoch in range(100):# 前馈 计算 y_haty_pred = model(x_data)# 前馈 计算损失loss = criterion(y_pred,y_data) #loss标量print(epoch,loss) # loss是一个对象,打印将会自动调用__str__()optimizer.zero_grad() # 所有权重梯度归零# 反馈 反向传播loss.backward()# 自动更新,权重进行更新optimizer.step()epoch_list.append(epoch)loss_list.append(loss.item())# Output weight and bias
print('w = ',model.linear.weight.item())
print('b = ',model.linear.bias.item())# Test Model
x_test = torch.Tensor([4.0])
y_test = model(x_test)
print('y_pred = ',y_test.data)
plt.plot(epoch_list,loss_list)plt.ylabel('Loss')
plt.xlabel('epoch')
plt.show()

         

       

         

        



六、逻辑斯蒂回归 - Logistics Regression 逻辑斯蒂回归

  • —— 虽然叫回归模型,但既可解决分类模型,也可解决回归模型
  • 本节是讲的二分类,背景是:学习多少小时能够考试通过;
  • 训练好模型以后,直接用来预测,4小时的学习,能够通过的概率是多大?

  • torchvision提供相应的数据集,可以指定需要的数据集,train表示需要训练集还是测试集。
  • 分类问题我们的输出为概率,将线性模型输出的实数空间映射到[0,1]之间,logist函数即可完成这个映射。
  • logist函数为饱和函数,是sigmoid中最典型的。

        

  •  其他的sigmoid函数:

        

所以现在我们的模型:

        

对应的loss也要发生改变,现在输出的是一个分布,不再是一个数值,

所以现在相比较的是两个分布之间的差异:可以选择用KL散度或者cross-entropy(交叉熵)

交叉熵举例:交叉熵越大越好

        

在本例中我们采用二分类的交叉熵,因为加了负号,所以这里的loss越小越好,称为BCE损失

         

         

  •  criterion = torch.nn.BCELoss(size_average=False) #继承nn.Module,是否给每个批量求均值,设置与否关键会影响学习率的设置,因为如果损失变小了,将来求出来的导数也会乘上这个常数

import torchvision
import torch.nn.functional as F
import torch
import matplotlib.pyplot as plt# 1、准备数据
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[0],[0],[1]])# 2、构建模型
class LogisticRegressionModel(torch.nn.Module):def __init__(self):super(LogisticRegressionModel,self).__init__()self.linear = torch.nn.Linear(1,1)def forward(self,x):y_pred = F.sigmoid(self.linear(x))return y_predmodel = LogisticRegressionModel()# 3、构造损失函数和优化器
criterion = torch.nn.BCELoss(size_average=False) #继承nn.Module,是否给每个批量求均值
optimizer = torch.optim.SGD(model.parameters(),lr=0.01) #是一个类,不继承nn.Module,不会构建计算图,lr学习率epoch_list = []
loss_list = []for epoch in range(1000):# 前馈 计算 y_haty_pred = model(x_data)# 前馈 计算损失loss = criterion(y_pred,y_data) #loss标量print(epoch,loss) # loss是一个对象,打印将会自动调用__str__()optimizer.zero_grad() # 所有权重梯度归零# 反馈 反向传播loss.backward()# 自动更新,权重进行更新optimizer.step()epoch_list.append(epoch)loss_list.append(loss.item())# Output weight and bias
print('w = ',model.linear.weight.item())
print('b = ',model.linear.bias.item())# Test Model
x_test = torch.Tensor([4.0])
y_test = model(x_test)
print('y_pred = ',y_test.data)
plt.plot(epoch_list,loss_list)plt.ylabel('Loss')
plt.xlabel('epoch')
plt.show()

         

        



七、处理多维特征的输入 - Multiple Dimension lnput

引例:糖尿病数据集分类任务

行称为:样本(Sample)      数据库中称为:记录(record)

列称为:特征                   数据库中称为:字段

注:sklearn中提供一个关于糖尿病的数据集可作为回归任务的数据集


Mlultiple Dimension Loqistic Regression Model

  • x可以看成一个向量,每一个x都要和w进行相乘,我们就可以写成图中上面的红色部分,因为标量的转置还是他自身,为了方便演示我们可以写成转置的形式。

                

即:

        

再来看下Mini-Batch(N samples)的情况

        

为什么这里要将方程运算转换成矩阵运算 即 向量形式呢?

———— 我们可以利用并行运算的能力,提高运行速度。

则只需将上一节的代码中数据准备和构建模型进行修改即可:

        


Logistics回归只有一层神经网络,若我们构造一个多层神经网络

        


         

将矩阵看成一种空间变换的函数,这里的(8,2)是指将一个任意八维空间的向量映射到一个二维空间上,注意是线性的,而我们所做的空间变换不一定是线性的,

所以我们想要多个线性变换层通过找到最优的权重,把他们组合起来,来模拟一个非线性变换,

注意绿色框中我们引入的 \sigma 即激活函数 ,在神经网络中我们通过引入激活函数给线性变换加入非线性操作,这样就使得我们可以去拟合相应的非线性变换。


对于本例 我们使用 Example: Artificial Neural Network

        

1、建立数据集

import numpy as np
import torchxy = np.loadtxt('./dataset/diabetes.csv.gz', delimiter=',', dtype=np.float32)
x_data = torch.from_numpy(xy[:, :-1])
y_data = torch.from_numpy(xy[:, [-1]])
  • 分隔符为,
  • 为什么用float32,因为常用游戏显卡只支持32位浮点数,只有特别贵的显卡才支持64位
  • 由于课程中导入的数据是anaconda安装工具包中的自带的压缩文本数据,所以直接采用numpy中的loadtxt读取,这个函数可以直接读取Linux下压缩的格式,此处是.gz
  • 因为我们的x和y是放在一起的所以 :-1表示不要最后一列 → 拿出来前八列
  • 注意y,所有行,拿出来需要加中括号,拿出来矩阵 → 拿出最后一列

2、模型建立

class Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()self.linear1 = torch.nn.Linear(8, 6)self.linear2 = torch.nn.Linear(6, 4)self.linear3 = torch.nn.Linear(4, 1)self.sigmoid = torch.nn.Sigmoid()def forward(self, x):x = self.sigmoid(self.linear1(x))x = self.sigmoid(self.linear2(x))x = self.sigmoid(self.linear3(x))return xmodel = Model()
  •  注意上次调用的是nn.Function下的sigmoid,但是这里调用的是nn下的一个模块
  • forward函数中,如果是一串,就用一个x,上面的输出是下面的输入

 3、构造损失函数和优化器

criterion = torch.nn.BCELoss(size_average=True)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

 4、模型训练(虽然是mini-batch的风格 但这里还是全部数据,下一节会涉及)

for epoch in range(100):# forwardy_pred = model(x_data)loss = criterion(y_pred, y_data)print(epoch, loss.item())# backwordoptimizer.zero_grad()loss.backward()# updateoptimizer.step()

         


可以尝试不同的激活函数对结果的影响

torch.nn — PyTorch 2.1 documentation

Visualising Activation Functions in Neural Networks - dashee87.github.io

注意:Relu函数取值是0到1,如果最后的输入是小于0的,那么最后输出会是0,但我们可能会算In0,所以一般来说会将最后一层的激活函数改成sigmoid。

        



 八、加载数据集 - Dataset and DataLoader

  • Dataset:加载数据集,支持我们以索引方式拿出样本
  • Dataloader:拿出一组Mini-Batch快速使用


三个概念:Epoch,Batch-size,Iterations

  • 若使用Mini-Batch,我们的训练循环要写成嵌套循环
      • 外层循环:每一寸循环是一次epoch(训练周期)
      • 内层循环:每一次循环执行一个batch(对batch进行迭代)
  • Epoch:所有的样本都进行了一次训练
  • Batch-Size:每一次训练的样本数量
  • Iteration:Batch分了多少个,即内层迭代了多少次


Dataloader: 分组,并做成可迭代的batch

         


  •  dataset抽象类 不可实例化,dataloader可以实例化
  • 数据集类里面有三个函数,这三个函数较为固定,分别自己的作用;
    • 继承Dataset后我们必须实现三个函数:
      • __len__()帮助我们返回数据集大小
      • getitem__()帮助我们通过索引找到某个样本
      • __init__()是初始化函数,之后我们可以提供数据集路径进行数据的加载
  •  Dataset的 init 中如果数据量较少可以导入所有的数据,若数据较大(图像、语音)无结构数据
import numpy as np
import torch
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
import matplotlib.pyplot as pltepoch_list = []
loss_list = []class DiabetesDataset(Dataset):def __init__(self,filepath):xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32)self.len = xy.shape[0] #(n,9)self.x_data = torch.from_numpy(xy[:, :-1])self.y_data = torch.from_numpy(xy[:, [-1]])def __getitem__(self, index):return self.x_data[index],self.y_data[index]def __len__(self):return self.lendataset = DiabetesDataset('D:\python_project\diabetes.csv.gz')
train_loader = DataLoader(dataset=dataset,batch_size=32,shuffle=True,num_workers=1)class Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()self.linear1 = torch.nn.Linear(8, 6)self.linear2 = torch.nn.Linear(6, 4)self.linear3 = torch.nn.Linear(4, 1)self.sigmoid = torch.nn.Sigmoid()def forward(self, x):x = self.sigmoid(self.linear1(x))x = self.sigmoid(self.linear2(x))x = self.sigmoid(self.linear3(x))return xmodel = Model()criterion = torch.nn.BCELoss(reduction='mean')
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)if __name__ == '__main__':for epoch in range(100):for i,data in enumerate(train_loader,0):print(1)# 1、准备数据inputs, labels = data# 2、前馈y_pred = model(inputs)loss = criterion(y_pred,labels)print(epoch,i,loss.item())# 3、反馈optimizer.zero_grad()loss.backward()# 4、更新optimizer.step()epoch_list.append(epoch)loss_list.append(loss.item())plt.plot(epoch_list,loss_list)plt.ylabel('Loss')plt.xlabel('epoch')plt.show()

不是我结果怎这样?

         


更多数据集:

       

         



九、多分类问题 - Softmax分类器

         

  • Sigmoid函数主要用于解决二分类问题,它的特性在于将输入值映射到0和1之间的概率值。然而,在多类别问题中,我们需要将输入值映射到多个不同的类别上,而不仅仅是0和1。
  • 如果我们尝试使用sigmoid函数来解决多类别问题,我们需要将其进行扩展以支持多个类别。一种常见的方法是使用一对多(One-vs-Rest)策略,其中针对每个类别训练一个独立的二分类模型。然后,我们可以使用sigmoid函数将每个模型的输出转换为概率值。
  • 然而,这种方法存在一些问题。首先,由于每个模型都是独立训练的,可能会导致类别之间存在冲突或重叠。其次,sigmoid函数在处理极端情况时(接近0或1)容易饱和,这可能会导致梯度消失或梯度爆炸问题,对模型的训练造成困难。
  • 因此,为了解决多类别问题,通常会使用其他适合的函数,如Softmax函数。Softmax函数可以将输入值映射到多个类别的概率分布,同时保持概率之和为1。这样,我们可以更好地处理多类别问题,并避免sigmoid函数的限制。

        

 Softmax层:

                

因为只有一项结果会为0,所以在算Loss时只算一项即可。

        

在pytorch中:

        

 具体例子:

        


反看之前的题目:

lmplementation of classifier to MNIST dataset

        

  • ToTenser:神经网络想要的输入比较小,所以原始图像需要转变成一个图像张量        
  • Normalize:标准化 切换到 0,1 分布 ,参数为 均值 标准差,类似四六级成绩
  • 因为我们选用小批量,所以这里的N表示每个批量N个样本,每个样本都是一维28x28的图像
  • 则输入为四阶张量,但在全连接神经网络中,要求输入必须是矩阵,
  • 所以需要将1x28x28这个三阶张量 变为 一阶的向量
  • 则只要将图像的每一行拼起来即可,一行即为784个元素,所以可以使用view函数,将输入变为二阶张量,第一个参数为-1,将来会自动算出对应值
  • 最后得到 Nx784 的矩阵
  • 注意:最后一层不做激活

        

 


 

为什么每一层Linear层后都要加一层激活函数?

在神经网络中,每一层后加入激活函数有几个主要原因:

  1. 引入非线性:线性层只是对输入进行线性变换,无法处理复杂的非线性关系。通过添加激活函数,可以引入非线性,使得神经网络能够学习更加复杂的特征和模式。

  2. 增强模型表达能力:激活函数可以增加模型的表达能力,使其能够适应更广泛的数据分布和任务。通过非线性变换,激活函数可以将输入映射到更高维度的特征空间,从而提取更多的有用信息。

  3. 解决梯度消失问题:线性层的堆叠容易导致梯度逐渐消失的问题。激活函数的使用可以帮助传播梯度,避免梯度在深层网络中过早地衰减。这对于训练深层神经网络至关重要。

  4. 使输出范围有限:某些激活函数(例如sigmoid函数、tanh函数)可以将输出值限制在特定的范围内(例如[0,1]或[-1,1]),这有助于解决回归或分类问题中的数值稳定性和收敛性问题。

需要注意的是,并非所有层都需要添加激活函数。例如,在输出层进行回归任务时,可以选择不使用激活函数或者使用恒等函数作为激活函数。在某些特定的网络架构中,也可能会采用其他类型的层(如BatchNormalization层、MaxPooling层)来替代激活函数的作用。

 


 

 代码实现:

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim# 1、数据准备
batch_size = 64
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081,))
])train_dataset = datasets.MNIST(root='../dataset/mnist',train=True,download=True,transform=transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)test_dataset = datasets.MNIST(root='../dataset/mnist',train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)# 2、构建模型
class Net(torch.nn.Module):def __init__(self):super(Net,self).__init__()self.l1 = torch.nn.Linear(784,512)self.l2 = torch.nn.Linear(512,256)self.l3 = torch.nn.Linear(256,128)self.l4 = torch.nn.Linear(128,64)self.l5 = torch.nn.Linear(64,10)def forward(self,x):x = x.view(-1,784)x = F.relu(self.l1(x))x = F.relu(self.l2(x))x = F.relu(self.l3(x))x = F.relu(self.l4(x))return self.l5(x)model = Net()# 3、损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr=0.01,momentum=0.5)# 4、训练和测试
def train(epoch):running_loss = 0.0for batch_idx,data in enumerate(train_loader,0):inputs,target = dataoptimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs,target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % 300 == 299: # 每三百次迭代输出一次print('[%d , %5d] loss: %.3f' % (epoch + 1 ,batch_idx + 1,running_loss / 300))running_loss = 0.0def test():correct = 0total = 0with torch.no_grad():for data in test_loader:images,labels = dataoutputs = model(images) # 输出为一个矩阵,下面要求每一行最大值(即分类)的下标_,predicted = torch.max(outputs.data,dim=1)total += labels.size(0)correct += (predicted == labels).sum().item()print('Accuracy on test set: %d %%' % (100 * correct / total))if __name__ == '__main__':for epoch in range(10):train(epoch)test()

实验结果:

        

为什么最后准确率上不去了?

因为做图像时忽略了对局部信息的利用,本例中使用的是全连接神经网络,所有的元素都和其他元素都要产生联系,所以首先我们的权重不够多,其次我们在处理图像时更关系一些高抽象级别的特征,我们现在用的是非常原始的特征,

改进:我们可以先对图像进行人工特征提取:如傅里叶变换变换成频率的表示、小波

自动特征提取:CNN


 

• Reading the document:
• https://pytorch.org/docs/stable/nn.html#crossentropyloss
• https://pytorch.org/docs/stable/nn.html#nllloss
• Try to know why:
• CrossEntropyLoss <==> LogSoftmax + NLLLoss



部分文字参考于

【Pytorch深度学习实践】B站up刘二大人之SoftmaxClassifier-代码理解与实现(8/9)_softmax分类器代码-CSDN博客

视频及图片来源于

09.多分类问题_哔哩哔哩_bilibili

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

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

相关文章

解读 | 快速精确的体素GICP三维点云配准算法

原创 | 文 BFT机器人 01 摘要 本文提出了体素化广义迭代最近点&#xff08;VGICP&#xff09;算法&#xff0c;用于快速准确的三维点云配准。所提出的方法通过体素化扩展了广义迭代最近点&#xff08;GICP&#xff09;方法&#xff0c;以避免昂贵的最近邻搜索&#xff0c;同时…

Microsoft Edge浏览器中使用免费的ChatGPT

一、双击打开浏览器 找到&#xff1a;扩展&#xff0c;打开 二、打开Microsoft Edge加载项 三、Move tab新标签 获取免费ChatGPT 四、启用Move tab。启用ChatGPT。 扩展 管理扩展 启用 五、新建标签页&#xff0c;使用GPT 六、使用举例 提问 GPT回复

酷开科技 | 酷开系统,为居家生活打开更精彩的窗口

电视在我们的日常生活中扮演着重要的角色。虽然&#xff0c;作为客厅C位的扛把子——电视的娱乐作用深入人心&#xff0c;但是&#xff0c;它的涵义和影响力却因我们每个人的具体生活环境而存在着种种差异&#xff0c;而我们的生活环境又受到我们所处的社会及文化环境的影响。 …

Gartner发布2024 年十大战略技术趋势

10月17日&#xff0c;Gartner 发布2024年企业机构需要探索的****十大战略技术趋势。Gartner研究副总裁Bart Willemsen表示&#xff1a;“由于技术变革以及社会经济方面的不确定性&#xff0c;我们必须大胆采取行动并从战略上提高弹性&#xff0c;而不是采取临时措施。IT领导者的…

页面查询多项数据组合的线程池设计 | 京东云技术团队

背景 我们应对并发场景时一般会采用下面方式去预估线程池的线程数量&#xff0c;比如QPS需求是1000&#xff0c;平均每个任务需要执行的时间是t秒&#xff0c;那么我们需要的线程数是t * 1000。 但是在一些情况下&#xff0c;这个t是不好估算的&#xff0c;即便是估算出来了&…

VS Code C# 开发工具包正式发布

前言 微软于本月正式发布Visual Studio Code C#开发工具包&#xff0c;此前该开发套件已经以预览版的形式在6月份问世。经过4个月的测试和调整&#xff0c;微软修复了350多个问题&#xff0c;其中大部分是用户反馈导致的问题。此外&#xff0c;微软还对产品进行了300多项有针对…

1024 CSDN 程序员节-知存科技-基于存内计算芯片开发板验证语音识别

前言 在今年的 CSDN 程序员节上&#xff0c;我参与了这次知存科技举办的一个 AI Workshop 小活动——“基于存内计算芯片开发板验证语音识别”&#xff0c;并且有幸成为完成任务的学习者之一XD。上一次参与类似的活动是算能公司举办的“千校万里行”AIGC 大模型编译部署活动&a…

【Django 04】Serialization 序列化的高级使用

序列化器 serializers 序列化器的作用 序列化将 queryset 和 instance 转换为 json/xml/yaml 返回给前端 反序列化与序列化则相反 定义序列化器 定义类&#xff0c;继承自 Serializer 通常新建一个 serializers.py 文件 撰写序列化内容 suah as 目前只支持 read_only 只…

设计模式:外观模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

大家好&#xff01;本节主要介绍设计模式中的外观模式。 简介&#xff1a; 外观模式&#xff0c;它是一种设计模式&#xff0c;它为子系统中的一组接口提供一个统一的、简单的接口。这种模式主张按照描述和判断资料来评价课程&#xff0c;关键活动是在课程实施的全过程中进行…

科学计算语言Julia编程初步

文章目录 安装基本类型和计算函数初步条件和判断循环向量计算 Julia号称有着比肩C的速度&#xff0c;同时又像Python一样便捷的编程语言&#xff0c;非常适合科研狗使用。之前写了很多博客介绍Julia在数值分析中的应用&#xff0c;这次写一个适合初学者学习的Julia教程系列。 …

中科芯与IAR共建生态合作,IAR集成开发环境全面支持CKS32系列MCU

中国上海–2023年10月18日–嵌入式开发软件和服务的全球领导者IAR今日宣布&#xff0c;与中科芯集成电路有限公司&#xff08;以下简称中科芯&#xff09;达成生态合作&#xff0c;IAR已全面支持CKS32系列MCU的应用开发。这一合作将进一步推动嵌入式系统的发展&#xff0c;并为…

【吞噬星空】战神宫全体投票,为罗峰脱罪,徐欣补办婚礼,洪成功恢复脑电波

【侵权联系删除】【文/郑尔巴金】 吞噬星空动画第90集即将更新&#xff0c;官方相当给力&#xff0c;提前曝光了图文情报与先行预告。虽然罗峰与巴巴塔尚未正式开始闯荡宇宙&#xff0c;但却是斩杀阿特金三大巨头的平稳生活。不但有战神宫为罗峰脱罪&#xff0c;而且还给徐欣补…

Linux安装Redis(这里使用Redis6,其它版本类似)

目录 一、选择需要安装的Redis版本二、下载并解压Redis三、编译安装Redis四、启动Redis4.1、修改配置文件4.2、启动 五、测试连接5.1、本地连接使用自带客户端redis-cli连接操作redis5.2、外部连接使用RedisDesktopManager操作redis 六、关闭Redis七、删除Redis 一、选择需要安…

【Chrome】使用k8s、docker部署无头浏览器Headless,Java调用示例

什么是无头浏览器&#xff1f; 无头浏览器是一种没有图形用户界面的浏览器。无头浏览器不通过其图形用户界面(GUI)控制浏览器的操作&#xff0c;而是使用命令行。 为什么要用Chrome无头&#xff1f; Chrome Headless用于抓取(谷歌)、测试(开发者)和黑客(黑客)。搜索引擎&…

倾斜摄影三维模型根节点合并技术方法探讨

倾斜摄影三维模型根节点合并技术方法探讨 倾斜摄影技术是一种通过无人机或其他航空器采集大量高分辨率照片&#xff0c;并使用特殊软件将这些照片拼接成三维模型的方法。在这个过程中&#xff0c;摄影机以倾斜角度拍摄照片&#xff0c;从而捕捉到目标物体的多个视角&#xff0c…

特殊类设计

文章目录 特殊类设计1. 请设计一个类&#xff0c;不能被拷贝2. 请设计一个类&#xff0c;只能在堆上创建对象3. 请设计一个类&#xff0c;只能在栈上创建对象4. 请设计一个类&#xff0c;不能被继承5. 单例模式5.1 设计模式5.2 单例模式(1) 饿汉模式(2) 懒汉模式 特殊类设计 1…

python如何创建自己的对冲交易算法

在这篇文章中&#xff0c;我解释了如何创建一个人工智能来每天为我进行自动交易。 随着机器学习的现代进步和在线数据的轻松访问&#xff0c;参与量化交易变得前所未有的容易。为了让事情变得更好&#xff0c;AWS 等云工具可以轻松地将交易想法转化为真正的、功能齐全的交易机器…

UDP网络通信反复发收

package UDP2;import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner;/* * 完成UDP 通信快速入门 实现发1收1*/ public class Client {public static void main(String[] args) throws Exception{// …

k8s的coreDNS添加自定义hosts

1.ack的hosts不会继承宿主机的hosts&#xff0c;而工作中有一个域名默认是走内网解析&#xff0c;内网被限制访问了&#xff0c;只能在coreDNS中加一个hosts解析域名 2.编辑configmap (coredns) kubectl edit configmap -n kube-system coredns 增加hosts节点 Corefile: |.:53…

VMware Workstation安装ESXi和vCenter(8.0)

一、环境准备 虚拟机&#xff1a;VMware Workstation 17 Pro ESXi&#xff1a;ESXi-8.0U2-22380479-standard vCenter&#xff1a;VMware-VCSA-all-8.0.2-22385739.iso 主要是内存设置&#xff0c;因为vCenter需要14Gb内存&#xff0c;所以这个至少16Gb。 硬盘需要2块&…