Pytorch-学习记录-1-Tensor

news2024/11/24 11:24:13

1. 张量 (Tensor):

数学中指的是多维数组;

torch.Tensor

data: 被封装的 Tensor
dtype: 张量的数据类型
shape: 张量的形状
device: 张量所在的设备,GPU/CPU
requires_grad: 指示是否需要计算梯度
grad: data 的梯度
grad_fn: 创建 Tensor 的 Function,是自动求导的关键
is_leaf: 指示是否是叶子结点 (叶子结点指的是用户创建的节点,比如 y=(x+w)*(w+1)中,x和w就是叶子结点【可以用计算图来清楚地表示该过程】)

2. 创建张量:

2.1 直接创建:

2.1.1 从 data 创建 tensor

data: 可以是 list, numpy
dtype: 数据类型,默认与data一致
device: 所在设备
requires_grad: 是否需要梯度
pin_memory: 是否存于锁页内存
# 创建方法
torch.tensor(
    data,
    dtype=None,
    device=None,
    requires_grad=False,
    pin_memory=False
)

2.1.2 从 numpy 创建 tensor

torch.from_numpy()创建的tensor与原始的ndarray共享内存,修改其中一个,另一个也会变。

# 创建方法
torch.from_numpy(ndarray)
# 举例
import torch
import numpy as np

# 直接创建
## torch.tensor()
arr = np.ones((3,3))
t = torch.tensor(arr, 
                 dtype=torch.float32, 
                 device="mps") # 把张量放到 GPU 上 (mac M1)

print(t.dtype)
print(t)


## torch.from_numpy()
arr = np.array([[1,2,3],[4,5,6]])
t = torch.from_numpy(arr)
print(t.dtype)
print(t)
torch.float32
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], device='mps:0')
torch.int64
tensor([[1, 2, 3],
        [4, 5, 6]])

2.2 根据数值进行创建:

2.2.1 torch.zeros()

创建全0张量

size: 张量的形状
out: 输出的张量 (暂时可以不考虑)
layout:内存中布局形式,有 strided (通常情况下使用), sparse_coo (读取稀疏矩阵会用到)
device: 所在设备
requires_grad: 是否需要梯度
# 创建方法
torch.zeros(
    *size,
    out=None,
    dtype=None,
    layout=torch.strided,
    device=False,
    requires_grad=False
)

2.2.2 torch.zeros_lisk()

根据 input 形状创建全0张量

input: 创建与 input 同形状的张量;
dtype: 数据类型;
layout: 内存中的布局形式;
# 创建方法
torch.zeros_like(
    input,
    dtype=None,
    layout=None,
    device=None,
    requires_grad=False
)

2.2.3 torch.ones()torch.ones_like()

创建全1张量

2.2.4 torch.full()torch.full_like()

创建自定义数值的张量

size: 张量形状
fill_value: 张量的值

2.2.5 torch.arange()

根据数列创建等差1维张量,[start, end)

start: 起始值
end: 结束值
step: 数列公差,默认为1

2.2.6torch.linspace()

创建均分的1维张量,[start, end]

start: 起始值
end: 结束值
step: 数列长度

2.2.7torch.logspace()

创建对数均分的1D张量

start: 起始值
end: 结束值
steps: 数列长度
base: 对数函数的底,默认为10
# 创建方法
torch.logspace(
    start,
    end,
    steps=100,
    base=10.0,
    out=None,
    dtype=None,
    layout=torch.strided,
    deivce=None,
    requires_grad=False
)

2.2.8 torch.eye()

创建单位对角矩阵 (2D张量)

n: 矩阵行数
m: 矩阵列数
# 创建方法
torch.eye(
    n,
    m=None,
    out=None,
    dtype=None,
    layout=torch.strided,
    device=None,
    requires_grad=False
)
# 举例
t = torch.zeros((3,3))
print(t.dtype)
print(t)

t = torch.full((3,3),2) # 创建3x3的全2张量
print(t)

t = torch.arange(2, 8, 2)
print(t)

t = torch.linspace(2, 10, 5)
print(t)
torch.float32
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])
tensor([[2, 2, 2],
        [2, 2, 2],
        [2, 2, 2]])
tensor([2, 4, 6])
tensor([ 2.,  4.,  6.,  8., 10.])

2.3 根据概率分布创建张量:

2.3.1 torch.normal()

生成正态分布(高斯分布)

四种模式:

mean标量std标量
mean标量std张量
mean张量std标量
mean张量std张量
# 张量
torch.normal(
    mean,
    std,
    out=None
)

# 标量
torch.normal(
    mean,
    std,
    size,
    out=None
)

2.3.2 torch.randn(), torch.randn_like()

生成标准正态分布

torch.randn(
    *size, ## 张量形状
    out=None,
    dtype=None,
    layout=torch.strided,
    device=None,
    requires_grad=False
)

2.3.3 torch.rand(), torch.rand_like()

在[0,1)区间上生成均匀分布

torch.rand(
    *size, ## 张量形状
    out=None,
    dtype=None,
    layout=torch.strided,
    device=None,
    requires_grad=False
)

2.3.4 torch.randint(), torch.randint_like()

在 [low, high) 区间上生成整数均匀分布

torch.randint(
    low,
    high,
    size,
    out=None,
    dtype=None,
    layout=torch.strided,
    device=None,
    requires_grad=False
)

2.3.5 torch.randperm()

生成0到n-1的随机排列

n: 张量长度
torch.randperm(
    n,
    out=None,
    dtype=torch.int64,
    layout=torch.strided,
    device=None,
    requires_grad=False
)

2.3.6torch.bernoulli()

以 input 为概率,生成伯努利分布(0-1分布,两点分布)

torch.bernoulli(
    input,
    *,
    generator=None,
    out=None
)

3. 张量的操作:

张量的操作:拼接、切分、索引和变换:

1. 拼接:

1.1 torch.cat()

将张量按维度 dim 进行拼接 (不回扩张张量维度)

torch.cat(
    tensors, ## 张量序列
    dim, ## 要拼接的维度
    out=None
)

1.2 torch.stack()

在新创建的维度 dim 上进行拼接 (会扩张张量的维度)

torch.stack(
    tensors, ## 张量序列
    dim=0, ## 要拼接的维度
    out=None
)
import torch

t = torch.ones((2,3))

# torch.cat()
t1 = torch.cat([t,t], dim=0) ## 按照 dim=0 对t进行拼接,得到(4,3)

# torch.stack()
t2 = torch.stack([t,t], dim=0) ## 按照 dim=0 对t进行拼接,得到(2,2,3),会在dim=0创建一个新维度

print("t1 shape: ", t1.shape)
print("t2 shape: ", t2.shape)
t1 shape:  torch.Size([4, 3])
t2 shape:  torch.Size([2, 2, 3])

2. 切分

2.1 torch.chunk()

将张量按照维度 dim 进行平均切分,返回张量列表 (如果不能整除,最后一份张量小于其他张量)

torch.chunk(
    input, ## 要切分的张量
    chunks, ## 要切分的份数
    dim=0 ## 要切分的维度
)

2.2 torch.split()

将张量按照维度 dim 进行切分,返回张量列表

torch.split(
    tensor, ## 要切分的张量
    split_size_of_sections, ## 为 int 时,表示每一份的长度;为 list 时,按 list 元素切分
    dim=0 ## 要切分的维度
)
t1 = torch.ones((2,5))

# torch.chunk()
list_of_tensors = torch.chunk(t1, dim=1, chunks=2) ## 5不能被2整除,所以最后一个张量形状小雨前面的张量
for idx, t in enumerate(list_of_tensors):
    print("order {}, shape is {}".format(idx+1, t.shape))

# torch.split()
list_of_tensors = torch.split(t1, [2,1,2], dim=1)
for idx, t in enumerate(list_of_tensors):
    print("order {}, shape is {}".format(idx+1, t.shape))
order 1, shape is torch.Size([2, 3])
order 2, shape is torch.Size([2, 2])
order 1, shape is torch.Size([2, 2])
order 2, shape is torch.Size([2, 1])
order 3, shape is torch.Size([2, 2])

3. 索引

3.1 torch.index_select()

在维度 dim 上,按照 index 索引数据,返回依index索引数据拼接的张量 (先索引,再拼接)

torch.index_select(
    input, ## 要索引的张量
    dim, ## 要索引的维度
    index, ## 要索引数据的序号,数据类型必须是 torch.long
    out=None
)

3.2 torch.masked_select()

按照 mask 中的 True 进行索引,返回一维张量

torch.masked_select(
    input,
    mask, ## 与 input 同形状的布尔类型张量
    out=None
)
# torch_index_select()
t = torch.randint(0,9,size=(3,3))
idx = torch.tensor([0,2],dtype=torch.long)
t_select = torch.index_select(t, dim=1, index=idx)
print(t)
print(t_select)

# torch.masked_select()
mask = t.ge(5) ## 表示张量中 >= 5的元素;ge()表示大于等于;gt()表示大于;le()表示小于等于;lt()表示小于
t_select = torch.masked_select(t, mask=mask)
print(t)
print(mask)
print(t_select)
tensor([[3, 8, 1],
        [6, 0, 0],
        [7, 6, 8]])
tensor([[3, 1],
        [6, 0],
        [7, 8]])
tensor([[3, 8, 1],
        [6, 0, 0],
        [7, 6, 8]])
tensor([[False,  True, False],
        [ True, False, False],
        [ True,  True,  True]])
tensor([8, 6, 7, 6, 8])

4. 变换

4.1 torch.reshape()

变换张量形状 (张量在内存中是连续时,新张量与input共享数据内存)

torch.reshape(
    input,
    shape ## 新张量的形状
)

4.2 torch.transpose()

交换张量的两个维度

torch.transpose(
    input,
    dim0,
    dim1
)

4.3 torch.t()

2维张量转置

torch.t(input)

4.4 torch.squeeze()

压缩长度为1的维度

torch.squeeze(
    input,
    dim=None, ## 若 dim=None,则移除所有长度为1的轴;若指定维度而且维度长度为1,则可以移除该维度
    out=None
)

4.5 torch.unsqueeze()

根据 dim 扩展维度

torch.unsqueeze(
    input,
    dim,
    out=None
)
## torch.reshape

t = torch.randperm(8)
t_reshape = torch.reshape(t, (2,4)) ## 如果是 (-1,2,2),那么-1表示的是:不需要关心-1处的维度是多少,根据后两个维度进行计算得到(比如:这里就是 8/2/2 = 2,即-1处的维度是2)

print(t.shape)
print(t_reshape.shape)


## torch.transpose()
t = torch.rand((2,3,4))
t_transpose = torch.transpose(t, dim0=1, dim1=2) ## 把第1维和第2维进行交换
print(t.shape)
print(t_transpose.shape)


## torch.squeeze()
t = torch.rand((1,2,3,1))
t_squeeze = torch.squeeze(t)
t_squeeze_0 = torch.squeeze(t,dim=0)
t_squeeze_1 = torch.squeeze(t,dim=1)
print(t_squeeze.shape)
print(t_squeeze_0.shape)
print(t_squeeze_1.shape)


## torch.unsqueeze()
t = torch.rand((2,3))
t_unsqueeze = torch.unsqueeze(t, dim=2)
print(t_unsqueeze.shape)
torch.Size([8])
torch.Size([2, 4])
torch.Size([2, 3, 4])
torch.Size([2, 4, 3])
torch.Size([2, 3])
torch.Size([2, 3, 1])
torch.Size([1, 2, 3, 1])
torch.Size([2, 3, 1])

3.2 张量的数学运算:

加减乘除

torch.add()
torch.addcdiv()
torch.addcmul()
torch.sub()
torch.div()
torch.mul()

重点: torch.add()torch.addcmul()

torch.add(): 逐元素计算 input + alpha x other

torch.add(
    input, ## 第一个张量
    alpha=1, ## 乘项因子 (alpha x other + input)
    other, ## 第二个张量
    out=None
)

torch.addcmul()

out = input + value x tensor1 x tensor2

torch.addcmul(
    input,
    value=1.
    tensor1,
    tensor2,
    out=None
)

对数、指数、幂函数

torch.log(input, out=None)
torch.log10(input, out=None)
torch.log2(input, out=None)
torch.exp(input, out=None)
torch.pow()

三角函数

torch.abs(input, out=None)
torch.acos(input, out=None)
torch.cosh(input, out=None)
torch.cos(input, out=None)
torch.asin(input, out=None)
torch.atan(input, out=None)
torch.atan2(input, other=None, out=None)

4. 计算图与动态图

1. 计算图

计算图是用来描述运算的有向无环图,包括两个主要元素:节点和边。节点表示数据(比如 向量、矩阵、张量);边表示运算(比如 加减乘除卷积等)。

叶子结点:指的是由用户创建的节点,其他非叶子结点都是由叶子结点通过直接或间接的运算得到的。(之所以会有叶子结点的概念,是因为梯度反向传播结束后,只有叶子结点的梯度会被保留,非叶子结点的梯度会被从内存中释放掉。可以通过.is_leaf()方法查看是否为叶子结点)。

如果想要使用非叶子结点的梯度,实现方法是 在计算梯度之后,用.retain_grad()方法保存非叶子结点的梯度。

grad_fn: 记录创建该张量(非叶子结点)时所用的方法,比如 y=a*b,那么 y.grad_fn = <MulBackward0>

2. 动态图

计算图可以根据搭建方式的不同,分为:动态图 (运算与搭建同时进行,灵活,易调节,比如 pytorch) 和静态图 (先搭建,后运算,高效,不灵活,比如 tensorflow)。

5. 自动求导系统 autograd

1. torch.autograd.backward

自动计算图中各个结点的梯度

torch.autograd.backward(
    tensors, ## 用于求导的张量(比如 loss)
    grad_tensors=None, ## 多梯度权重
    retain_grap=None, ## 保存计算图
    create_graph=False ## 创建导数的计算图,同于高阶求导
)

2. torch.autograd.grad

求取梯度

torch.autograd.grad(
    outputs, ## 用于求导的张量 (比如 loss)
    inputs, ## 需要梯度的张量
    grad_outputs=None, ## 多梯度权重 
    retain_graph=None, ## 保存计算图
    create_graph=False ## 创建导数计算图,用于高阶求导
)

3. Pytorch 自动求导系统中有3个需要注意的点:

  1. 梯度不自动清零 (手动清零 .grad.zero_());

  2. 依赖于叶子结点结点,requires_grad 默认为 True;

  3. 叶子结点不可执行 in-place,即叶子结点不能执行原位操作;

4. 机器学习模型的5个训练步骤:

数据, 模型, 损失函数, 优化器, 迭代训练

6. DataLoader 与 Dataset

数据
    数据收集

    数据划分

    数据读取
        DataLoader
            Sampler: 生成索引
            Dataset: 根据索引读取样本特征以及标签

    数据预处理

1. torch.utils.data.DataLoader

DataLoader(
    dataset, ## Dataset类,决定数据从哪里读取以及如何读取
    batch_size=1, ## 批量大小
    shuffle=False, ## 每个 epoch 是否打乱顺序
    sampler=None,
    batch_sampler=None,
    num_workers=0, ## 是否多进程读取数据
    collate_fn=None,
    pin_memory=False,
    drop_last=False, ## 当样本数不能被 batchsize 整除时,是否舍弃最后一批数据
    timeout=0,
    worker_init_fn=None,
    multiprocessing_context=None
)

2. torch.utils.data.Dataset

Dataset抽象类,所有自定义的Dataset都需要继承它,并且需要复写 __getitem__()方法;getitem:接收一个索引,返回一个样本。

class Dataset(object):
    def __getitem__(self, index):
        raise NotImplementedError

    def __add__(self, other):
        return ConcatDataset([self, other])

Example: 猫狗图片分类 (“./example_week1_Cat_Dog_classification/”)

1. 参考代码:https://github.com/JansonYuan/Pytorch-Camp/

2. 猫狗数据集下载:https://www.kaggle.com/datasets/samuelcortinhas/cats-and-dogs-image-classification,但是将其中Test随机分成相等的两份,一份作为验证集,一份作为测试集(尽管测试集没有用到)。

3. 代码在 “./example_week1_Cat_Dog_classification/” 目录下。

4. 结果讨论:

4.1 作者原来的代码的结果:

在这里插入图片描述

Training:Epoch[000/010] Iteration[010/010] Loss: 0.6204 Acc:60.62%
Valid:	 Epoch[000/010] Iteration[002/002] Loss: 0.4436 Acc:90.00%
Training:Epoch[001/010] Iteration[010/010] Loss: 0.3601 Acc:90.62%
Valid:	 Epoch[001/010] Iteration[002/002] Loss: 0.0461 Acc:100.00%
Training:Epoch[002/010] Iteration[010/010] Loss: 0.0788 Acc:98.12%
Valid:	 Epoch[002/010] Iteration[002/002] Loss: 0.0234 Acc:100.00%
Training:Epoch[003/010] Iteration[010/010] Loss: 0.0208 Acc:99.38%
Valid:	 Epoch[003/010] Iteration[002/002] Loss: 0.0022 Acc:100.00%
Training:Epoch[004/010] Iteration[010/010] Loss: 0.0042 Acc:100.00%
Valid:	 Epoch[004/010] Iteration[002/002] Loss: 0.0018 Acc:100.00%
Training:Epoch[005/010] Iteration[010/010] Loss: 0.0143 Acc:99.38%
Valid:	 Epoch[005/010] Iteration[002/002] Loss: 0.0002 Acc:100.00%
Training:Epoch[006/010] Iteration[010/010] Loss: 0.0220 Acc:98.75%
Valid:	 Epoch[006/010] Iteration[002/002] Loss: 0.0004 Acc:100.00%
Training:Epoch[007/010] Iteration[010/010] Loss: 0.0008 Acc:100.00%
Valid:	 Epoch[007/010] Iteration[002/002] Loss: 0.0013 Acc:100.00%
Training:Epoch[008/010] Iteration[010/010] Loss: 0.0083 Acc:99.38%
Valid:	 Epoch[008/010] Iteration[002/002] Loss: 0.0001 Acc:100.00%
Training:Epoch[009/010] Iteration[010/010] Loss: 0.0049 Acc:100.00%
Valid:	 Epoch[009/010] Iteration[002/002] Loss: 0.0000 Acc:100.00%

4.2 用 “./example_week1_Cat_Dog_classification/train_lenet.py” 代码处理 Pytorch-Camp 的结果和上面的是一致的(代码修改后,与 Pytorch-Camp 提供的代码可以对 RMB 实现同样的分类效果),如下所示:

在这里插入图片描述

Train:   Epoch[000/010] Iteration[010/010] Loss: 0.6204 Acc: 60.62%
Valid:   Epoch[000/010] Iteration[002/002] Loss: 0.4436 Acc: 90.00%
Train:   Epoch[001/010] Iteration[010/010] Loss: 0.3601 Acc: 90.62%
Valid:   Epoch[001/010] Iteration[002/002] Loss: 0.0461 Acc: 100.00%
Train:   Epoch[002/010] Iteration[010/010] Loss: 0.0788 Acc: 98.12%
Valid:   Epoch[002/010] Iteration[002/002] Loss: 0.0234 Acc: 100.00%
Train:   Epoch[003/010] Iteration[010/010] Loss: 0.0208 Acc: 99.38%
Valid:   Epoch[003/010] Iteration[002/002] Loss: 0.0022 Acc: 100.00%
Train:   Epoch[004/010] Iteration[010/010] Loss: 0.0042 Acc: 100.00%
Valid:   Epoch[004/010] Iteration[002/002] Loss: 0.0018 Acc: 100.00%
Train:   Epoch[005/010] Iteration[010/010] Loss: 0.0143 Acc: 99.38%
Valid:   Epoch[005/010] Iteration[002/002] Loss: 0.0002 Acc: 100.00%
Train:   Epoch[006/010] Iteration[010/010] Loss: 0.0220 Acc: 98.75%
Valid:   Epoch[006/010] Iteration[002/002] Loss: 0.0004 Acc: 100.00%
Train:   Epoch[007/010] Iteration[010/010] Loss: 0.0008 Acc: 100.00%
Valid:   Epoch[007/010] Iteration[002/002] Loss: 0.0013 Acc: 100.00%
Train:   Epoch[008/010] Iteration[010/010] Loss: 0.0083 Acc: 99.38%
Valid:   Epoch[008/010] Iteration[002/002] Loss: 0.0001 Acc: 100.00%
Train:   Epoch[009/010] Iteration[010/010] Loss: 0.0049 Acc: 100.00%
Valid:   Epoch[009/010] Iteration[002/002] Loss: 0.0000 Acc: 100.00%

4.3 将数据换成猫狗数据集之后,结果如下:

在这里插入图片描述

Train:   Epoch[000/010] Iteration[035/035] Loss: 0.7151 Acc: 53.50%
Valid:   Epoch[000/010] Iteration[005/005] Loss: 0.6898 Acc: 51.43%
Train:   Epoch[001/010] Iteration[035/035] Loss: 0.6954 Acc: 50.09%
Valid:   Epoch[001/010] Iteration[005/005] Loss: 0.7321 Acc: 41.43%
Train:   Epoch[002/010] Iteration[035/035] Loss: 0.6885 Acc: 53.86%
Valid:   Epoch[002/010] Iteration[005/005] Loss: 0.6954 Acc: 52.86%
Train:   Epoch[003/010] Iteration[035/035] Loss: 0.6813 Acc: 58.53%
Valid:   Epoch[003/010] Iteration[005/005] Loss: 0.6909 Acc: 55.71%
Train:   Epoch[004/010] Iteration[035/035] Loss: 0.6832 Acc: 57.99%
Valid:   Epoch[004/010] Iteration[005/005] Loss: 0.6749 Acc: 52.86%
Train:   Epoch[005/010] Iteration[035/035] Loss: 0.6838 Acc: 58.35%
Valid:   Epoch[005/010] Iteration[005/005] Loss: 0.6865 Acc: 50.00%
Train:   Epoch[006/010] Iteration[035/035] Loss: 0.6729 Acc: 58.89%
Valid:   Epoch[006/010] Iteration[005/005] Loss: 0.7097 Acc: 57.14%
Train:   Epoch[007/010] Iteration[035/035] Loss: 0.6700 Acc: 61.58%
Valid:   Epoch[007/010] Iteration[005/005] Loss: 0.7361 Acc: 47.14%
Train:   Epoch[008/010] Iteration[035/035] Loss: 0.6721 Acc: 59.07%
Valid:   Epoch[008/010] Iteration[005/005] Loss: 0.7180 Acc: 52.86%
Train:   Epoch[009/010] Iteration[035/035] Loss: 0.6476 Acc: 63.91%
Valid:   Epoch[009/010] Iteration[005/005] Loss: 0.7193 Acc: 57.14%

结论:

1.直接将 Pytorch-Camp 处理 RMB 分类问题时用到的 LeNet模型用于猫狗数据集分类,从结果来看是不合适的,可能需要对 LeNet进行调整(我猜后面可能会学到该如何调整网络结构)。

2.从这个例子中进一步理解了训练一个神经网络的过程:数据、模型、损失函数、优化器、训练,同时也了解了每个过程中所涉及到的一些细节的处理。

3.目前存在的问题就是:和第1点中提到的一样,对于不同的实际问题,该如何构建合理的深度学习网络(有哪些需要微调的地方?为什么在这个地方进行微调、有什么依据?)。

Pytorch 数据预处理模块 —— transforms

因为不搞计算机视觉,所以 transforms 这部分的内容暂时不学习…

torchvision: 计算机视觉工具包;

torchvision.transforms: 常用的图像预处理方法;
torchvision.datasets: 常用数据集的dataset实现,比如 MNIST, CIFAR-10, ImageNet等;
torchvision.model: 常用的模型预训练,比如 AlexNet, VGG, ResNet, GoogLeNet等;

torchvision.transforms

数据中心化,标准化,缩放,裁剪,旋转,填充,翻转,噪声添加,灰度变换,线性变换,仿射变换,亮度、饱和度及对比对变换。

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

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

相关文章

要多搞笑才能上B站热门?

自从B站开放竖屏模式之后&#xff0c;越来越多站外的优秀创作者加入B站。这其中搞笑UP主的数量大大增加&#xff0c;有很多竖屏UP主、短视频UP主在B站发光发热。 飞瓜数据&#xff08;B站版&#xff09;热门视频显示&#xff0c;近期热度最高的是来自UP主七颗猩猩QKXX发布的竖…

three.js点击模型实现模型边缘高亮选中效果

three.jsreact实现点击模型实现高亮选中效果 1、创建一个场景 let scene, camera, renderer, controls; let stats null; // 检测动画运行时的帧数 let clock new THREE.Clock(); // getDelta()方法获得两帧的时间间隔 let FPS 30; let renderT 1 / FPS; let timeS 0;con…

机器学习基础-数据分析:房价预测

mac设置中文字体 #要设置下面两行才能显示中文 Arial Unicode MS 为字体 plt.rcParams[font.sans-serif] [Arial Unicode MS] #设置图片大小 plt.figure(figsize(20, 11), dpi200)pie官方文档 总体代码 python import pandas as pd import numpy as np import matplotlib.…

Qt/C++原创推流工具/支持多种流媒体服务/ZLMediaKit/srs/mediamtx等

一、前言 1.1 功能特点 支持各种本地视频文件和网络视频文件。支持各种网络视频流&#xff0c;网络摄像头&#xff0c;协议包括rtsp、rtmp、http。支持将本地摄像头设备推流&#xff0c;可指定分辨率和帧率等。支持将本地桌面推流&#xff0c;可指定屏幕区域和帧率等。自动启…

【大数据 | 综合实践】大数据技术基础综合项目 - 基于GitHub API的数据采集与分析平台

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

在供应链管理中,如何做好库存分析?库存分析有哪些监控指标?

在供应链管理中&#xff0c;库存分析是其重要的一环。库存分析的方法繁杂且广泛&#xff0c;选择正确的方法才能更好的进行库存分析&#xff0c;下面就为大家盘点一些常用的库存分析方法和监控指标&#xff0c;全程干货&#xff0c;建议收藏&#xff01; 01 如何进行库存分析&…

【MySQL】基本查询(三)聚合函数+group by

文章目录 一. 聚合函数二. group by子句结束语 建立如下表 //创建表结构 mysql> create table exam_result(-> id int unsigned primary key auto_increment,-> name varchar(20) not null comment 同学姓名,-> chinese float default 0.0 comment 语文成绩,->…

08_selenium实战——学习平台公开数据批量获取

0、:前言 该实战任务是对某视频平台中’标题’、 ‘点赞数量’、 ‘投币数量’、‘收藏数量’、‘播放次数’、以及前五条评论进行爬取。要求1:可以控制爬取视频的主题(爬取主题搜索之后的内容)要求2:可以控制爬取视频的数量要求3:对于评论数不足5条的用0填充评论内容爬虫…

vue启动项目,npm run dev出现error:0308010C:digital envelope routines::unsupported

运行vue项目&#xff0c;npm run dev的时候出现不支持错误error:0308010C:digital envelope routines::unsupported。 在网上找了很多&#xff0c;大部分都是因为版本问题&#xff0c;修改环境之类的&#xff0c;原因是对的但是大多还是没能解决。经过摸索终于解决了。 方法如…

第九课 排序

文章目录 第九课 排序排序算法lc912.排序数组--中等题目描述代码展示 lc1122.数组的相对排序--简单题目描述代码展示 lc56.合并区间--中等题目描述代码展示 lc215.数组中的第k个最大元素--中等题目描述代码展示 acwing104.货仓选址--简单题目描述代码展示 lc493.翻转树--困难题…

保护 Web 服务器安全性

面向公众的系统&#xff08;如 Web 服务器&#xff09;经常成为攻击者的目标&#xff0c;如果这些业务关键资源没有得到适当的保护&#xff0c;可能会导致安全攻击&#xff0c;从而导致巨大的财务后果&#xff0c;并在客户中失去良好的声誉。 什么是网络服务器审核 当有人想要…

无线振弦采集仪在岩土工程中如何远程监测和远程维护

无线振弦采集仪在岩土工程中如何远程监测和远程维护 随着岩土工程施工的不断发展和科技水平的不断提高&#xff0c;远程监测和远程维护设备也得到了广泛关注和应用。无线振弦采集仪是一种广泛应用于岩土工程中的测量仪器&#xff0c;在现代化施工中扮演着重要的角色。本文将就…

ChromeDriver驱动最新版下载

下载地址ChromeDriver - WebDriver for Chrome - Downloads selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 113 Current browser version is 117.0.5938.150 with binar…

2、模块传参和依赖

一、模块传参 使用函数 module_param(name,type,perm); 将指定的全局变量设置成模块参数 /* name:全局变量名 type&#xff1a;使用符号 实际类型 传参方式bool bool insmod xxx.ko 变量名0 或 1invbool bool insmod xx…

运营商sdwan优缺点及sdwan服务商优势

SD-WAN(软件定义广域网)作为一种重要的网络解决方案&#xff0c;已经受到了广泛的关注和采用。然而&#xff0c; 无论是由传统运营商提供的SD-WAN还是专门的SD-WAN服务提供商&#xff0c;都存在各自的优缺点。 运营商提供的SD-WAN的缺点&#xff1a; 1. 有限的灵活性&#xf…

数据库查询详解

数据库查询操作 前置&#xff1a;首先我们创建一个练习的数据库 /* SQLyog Professional v12.09 (64 bit) MySQL - 5.6.40-log : Database - studentsys ********************************************************************* *//*!40101 SET NAMES utf8 */;/*!40101 SET …

【uniapp】自定义导航栏时,设置安全距离,适配不同机型

1、在pages.json中&#xff0c;给对应的页面设置自定义导航栏样式 {"path": "pages/index/index","style": {"navigationStyle": "custom","navigationBarTextStyle": "white","navigationBarTitl…

智慧电力物联网系统引领电力行业数字化发展

智慧电力物联网系统是以提高用户侧电力运行安全、降低运维成本为目的的一套电力运维管理系统。综合分析采用智慧物联网、人工智能等现代化经济信息网络技术&#xff0c;配置智能采集终端、小安神童值班机器人或边缘网关&#xff0c;实现对企事业用户供配电系统的数字化远程监控…

网关、网桥、路由器和交换机之【李逵与李鬼】

概念 网关 网关简单来说是连接两个网络的设备,现在很多局域网都是采用路由器来接入网络,因此现在网关通常指的就是路由器的IP。网关可用于家庭或者小型企业,连接局域网和Internet,也有用于工业应用的。 网桥 网桥也叫桥接器,是连接两个局域网的一种存储/转发设备,它能…

Python字符串处理:掌握文本的艺术

更多资料获取 &#x1f913; 作者主页&#xff1a;涛哥聊Python &#x1f4da; 个人网站&#xff1a;涛哥聊Python 在Python编程中&#xff0c;字符串是一种不可或缺的数据类型&#xff0c;用于表示文本和字符数据。本文将深入探讨Python字符串的各个方面&#xff0c;从基础概…