深度学习-张量相关
一. 张量的创建
张量简介
张量是pytorch的基本数据结构
张量,英文为Tensor,是机器学习的基本构建模块,是以数字方式表示数据的形式。
例如,图像可以表示为形状为 [3, 224, 224] 的张量,这意味着 [colour_channels, height, width] ,因为图像具有 3 颜色通道(红色、绿色、蓝色),高度为 224 像素,宽度为 224 像素。
在张量语言(用于描述张量的语言)中,张量将具有三个维度,一个维度表示 colour_channels 、 height 和 width 。
张量的基本创建
根据数据创建tensor
默认64
# 1. 使用torch.tensor根据数据创建张量 # 1.1. 创建标量 data = torch.tensor(10) print(data) # 1.2. 创建numpy数组 data = np.random.randn(3, 4) data = torch.tensor(data) print(data) # 1.3. 创建张量 data = torch.tensor([[1, 2], [3, 4]]) print(data)
根据形状/数据创建Tensor
默认32
# 2.使用torch.Tensor根据形状/数据创建张量 # 2.1. 创建两行三列张量, 默认dtype为float32 data = torch.Tensor(2, 3) print(data) # 2.2. 如果传递列表, 则创建包含指定元素的张量 data = torch.Tensor([10]) print(data) data = torch.Tensor([1, 4]) print(data)
指定类型张量
# 3. torch.IntTensor(), torch.FloatTensor(), torch.DoubleTensor()创建指定类型的张量 # 3.1. 创建2行3列, dtype 为 int32 的张量 data = torch.IntTensor(2, 3) print(data) # 3.2. 注意: 如果传递的元素类型不正确, 则会进行类型转换 data = torch.IntTensor([2.5, 3.3]) print(data) # 3.3. 其他的类型 data = torch.ShortTensor() # int16 print(data) data = torch.LongTensor() # int64 print(data) data = torch.FloatTensor() # float32 print(data) data = torch.DoubleTensor() # float64 print(data)
线性张量与随机张量
torch.arange 和 torch.linspace 创建线性张量
torch.random.init_seed 和 torch.random.manual_seed 随机种子设置
torch.randn 创建随机张量
线性张量
torch.arange()
# 1.1 arange() 左闭右开 data = torch.arange(0, 11, 2) print(data)
torch.linspace()
# 1.2 linspace() 左闭右闭 data = torch.linspace(0, 10, 5) print(data)
区别
arange(start, end, step): 起始, 截至, 步长(每步走多少, 左闭右开)
linspace(start, end, steps): 起始, 截止, 步数(走几步, 左闭右闭)
随机张量
torch.random.initial_seed()查看随机种子
torch.random.manual_seed() 设置随机数种子
torch.randn() 创建随机张量
创建随机张量
# 2.1 创建随机张量 data = torch.randn(2, 3) # 2行3列 print(data) # 2.2 查看随机种子 print(torch.random.initial_seed()) # 查看默认种子, 机器码 # 2.3 创建随机种子 torch.random.manual_seed(1) # 设置随机种子 data = torch.randn(2, 3) # 随机张量 print(data) print(torch.random.initial_seed())
创建指定值张量
torch.ones 和 torch.ones_like(像什么形状) 创建全1张量
torch.zeros 和 torch.zeros_like 创建全0张量
torch.full([行数, 列数], 指定值) 和 torch.full_like 创建指定值张量
创建全0张量
创建结果为浮点型, zeros_like(data) => 创建形状和data一样的张量
# 3.1 创建全0张量
data_zeros = torch.zeros(2, 3)
print('0张量', data_zeros)
data_zeros = torch.zeros_like(data_zeros)
print('0张量', data_zeros)
创建全1张量
# 3.2 创建全1张量
data_ons = torch.ones(2, 3)
print('1张量', data_ons)
data_ons = torch.tensor(data_ons)
print('1张量', data_ons)
创建全指定值张量
# 3.3 创建指定值张量
data_full = torch.full((2, 3), 5)
print('指定值张量', data_full)
data_full = torch.full_like(data_full, 10)
print('指定值张量', data_full)
张量元素类型转换
data.type(torch.DoubleTensor)
data.double(), data.float()......小写
data.dtype: 查看数据类型
间接转换
data = torch.full([2, 3], 10) print(data.dtype) >>> torch.int64 # 将 data 元素类型转换为 float64 类型 data = data.type(torch.DoubleTensor) print(data.dtype) >>> torch.float64 # 转换为其他类型 # data = data.type(torch.ShortTensor) # int16 # data = data.type(torch.IntTensor) # int32 # data = data.type(torch.LongTensor) # int64 # data = data.type(torch.FloatTensor) # float32
直接转换
data = torch.full([2, 3], 10) print(data.dtype) >>> torch.int64 # 将 data 元素类型转换为 float64 类型 data = data.double() print(data.dtype) >>> torch.float64 # 转换为其他类型 # data = data.short() # data = data.int() # data = data.long() # data = data.float()
张量创建总结
创建张量的方式
-
torch.tensor() 根据指定数据创建张量
-
torch.Tensor() 根据形状创建张量, 其也可用来创建指定数据的张量
-
torch.IntTensor()、torch.FloatTensor()、torch.DoubleTensor() 创建指定类型的张量
创建线性和随机张量
-
torch.arrange() 和 torch.linspace() 创建线性张量
-
torch.random.initial_seed() 和 torch.random.manual_seed() 随机种子设置
-
torch.randn() 创建随机张量
创建01张量
-
torch.ones() 和 torch.ones_like() 创建全1张量
-
torch.zeros() 和 torch.zeros_like() 创建全0张量
-
torch.full() 和 torch.full_like() 创建全为指定值张量
张量元素类型转换
-
data.type(torch.DoubleTensor)
-
data.double()
二. 张量相关操作
张量的类型转换
张量转Numpy数组
使用 Tensor.numpy 函数可以将张量转换为 ndarray 数组,但是共享内存,可以使用 copy 函数避免共享。
import torch torch.manual_seed(21) data = torch.randn(2, 3) print(type(data)) data_numpy = data.numpy().copy() # 设置不共享内存 print(type(data_numpy)) data[0][0] = 100 print(data) print(data_numpy)
Numpy数组转张量
from_numpy(data_numpy):默认共享内存, 可以使用data_numpy.copy()复制一份, 避免内存共享
torch.tensor()/torch.Tensor ()此方法不共享内存
# numpy转张量 import numpy as np data_numpy = np.random.randn(2, 3) print(type(data_numpy)) print(data_numpy) # data_tensor = torch.from_numpy(data_numpy) # 此方法共享内存 # data_tensor = torch.from_numpy(data_numpy.copy()) # 此方法不共享内存 # data_tensor = torch.tensor(data_numpy) # 此方法不共享内存 data_tensor = torch.Tensor(data_numpy) # 此方法不共享内存 print(type(data_tensor)) print(data_tensor) data_tensor[0][0] = 100 print(data_numpy) print(data_tensor)
标量张量和数字转换
当只有一个元素的张量时, 可以使用data.item()函数将该值从张量中取出
# 标量张量和数字转换 data = torch.tensor(1) print(data.item()) data = torch.tensor([1, 2]) print(data.item()) # 报错!
张量类型转换总结
张量转换为 numpy 数组
-
data_tensor.numpy()
-
data_tensor.numpy().copy()
numpy 转换为张量
-
torch.from_numpy(data_numpy)
-
torch.tensor(data_numpy)
标量张量和数字转换
-
data.item()
张量的数值计算
基本运算
1. 加减乘除取负号: 2. add+、sub-、mul*、div/、neg负号 不修改原数据 3. add_、sub_、mul_、div_、neg_ 修改原数据
import torch torch.manual_seed(21) data1 = torch.randint(0, 10, [2, 3]) torch.manual_seed(22) data2 = torch.randint(10, 20, [3, 4]) torch.manual_seed(23) data3 = torch.randint(10, 20, [2, 3]) print(data1) print(data2) print(data3) # 不修改原数据 print(data1.add(2)) print(data1.sub(2)) print(data1.mul(2)) print(data1.div(2)) print(data1.neg()) print(data1) # # 修改原数据 print(data1.add_(2)) print(data1.sub_(2)) print(data1.mul_(2)) print(data1.neg_()) print(data1)
点乘运算
对应位置元素相乘
mul或者*
# 点乘 print(data1.mul(data3)) print(data1 * data3)
矩阵运算
点积
(n, m) * (m, p) = (n, p)
matmul或者@
# 点积 print(data1.matmul(data2)) print(data1 @ data2)
张量运算总结
张量基本运算函数
-
add、sub、mul、div、neg等函数
-
add、sub、mul、div、neg_等函数
张量的点乘运算
-
mul 和运算符 *
点积运算
-
运算符@用于进行两个矩阵的点乘运算
-
torch.matmul 对进行点乘运算的两矩阵形状没有限定,对数输入的 shape 不同的张量, 对应的最后几个维度必须符合矩阵运算规则
张量函数运算
PyTorch 为每个张量封装很多实用的计算函数:

import torch torch.manual_seed(21) data = torch.randint(1, 10, (2, 3), dtype=torch.float64) print(data) # 均值 print(data.mean()) print(data.mean(dim=0)) # 按列求和 print(data.mean(dim=1)) # 按行求和 # 平方 print(torch.pow(data, 2)) # 平方根 print(data.sqrt()) # 求和 print(data.sum()) print(data.sum(dim=0)) print(data.sum(dim=1)) # 指数计算(以e为底的指数) print(data.exp()) # 对数计算 print(data.log()) # 以e为底 print(data.log2()) print(data.log10())
张量索引操作
import torch # 随机生成数据 data = torch.randint(0, 10, [4, 5]) print(data) >>> tensor([[0, 7, 6, 5, 9],[6, 8, 3, 1, 0],[6, 3, 8, 7, 3],[4, 9, 5, 3, 1]])
简单行列索引
print(data[0]) # 第0行数据 >>> tensor([0, 7, 6, 5, 9]) print(data[:, 0]) # 所有行第0列数据 >>> tensor([0, 6, 6, 4])
列表索引
# 返回 (0, 2)、(1, 3) 两个位置的元素 print(data[[0, 1], [2, 3]]) # 第0行第2列和第1行第3列 >>> tensor([7, 3]) # 返回 0、1 行的 1、2 列共4个元素 print(data[[[0], [1]], [1, 2]]) >>> tensor([[7, 6],[8, 3]])
范围索引
# 前3行的前2列数据 print(data[:3, :2]) >>> tensor([[0, 7],[6, 8],[6, 3]]) # 第2行到最后的前2列数据 print(data[2:, :2]) >>> tensor([[6, 3],[4, 9]]) # 第0行、第2行的第0、1两列数据 print(data[0:3:2, :2])# data[行(start, end, step), 列(start, end, step)] >>>tensor([[0, 7],[6, 3]])
布尔索引
# 第三列大于5的行数据 print(data[data[:, 2] > 5]) >>> tensor([[0, 7, 6, 5, 9],[6, 3, 8, 7, 3]]) # 第二行大于5的列数据 # 所有数据第1列数据大于5的所有行数据 print(data[:, data[1] > 5]) # data[行, 列] => 第2行大于5的列 >>> tensor([[0, 7],[6, 8],[6, 3],[4, 9]]) # 所有行中第4列小于10的行数据 print(data[data[:, 3] < 10])
多维索引
# 范围索引 torch.random.manual_seed(21) data = torch.randint(0, 10, [3, 4, 5]) # 三通道、四行、五列 print(data) >>>tensor([[[3, 3, 6, 8, 6],[4, 0, 9, 8, 8],[3, 7, 2, 2, 6],[7, 8, 5, 9, 9]], [[9, 4, 4, 4, 2],[2, 0, 8, 1, 2],[9, 8, 8, 3, 1],[4, 1, 6, 8, 8]], [[4, 8, 2, 6, 3],[5, 8, 2, 9, 4],[6, 9, 5, 8, 6],[8, 5, 2, 0, 8]]]) print(data[:, 1:3, 2]) # 所有通道的第1行和第2行,第2列的数据 >>>tensor([[0, 8],[4, 0],[0, 7]]) print(data[1, :, :]) # 第二通道的所有行,所有列的数据 >>>tensor([[9, 4, 4, 4, 2],[2, 0, 8, 1, 2],[9, 8, 8, 3, 1],[4, 1, 6, 8, 8]])
张量形状操作
有重塑、堆叠、挤压和解压:
| 方法 | 单行描述 |
|---|---|
| torch.reshape(input, shape) | 重塑 input 到 shape (如果兼容),也可以使用 torch.Tensor.reshape()。 |
| tensor.view(shape) | 返回不同 shape 中的原始张量视图,但与原始张量共享相同的数据。 |
| tensor.contiguous() | 将张量转换到整块内存上 |
| torch.stack(tensors, dim=0) | 堆叠:沿着新的维度(dim)连接 tensors 的序列,所有 tensors 必须具有相同的大小。 |
| torch.squeeze(input) | 降维:挤压 input 以移除值为 1 的所有尺寸。 |
| torch.unsqueeze(input, dim) | 升维:返回在 dim 处添加了维度值 1 的 input。 |
| torch.transpose(input,dim1,dim2) | 维度交换:实现交换张量形状的指定维度 |
| torch.permute(input, dims) | 返回原始 input 的视图,其尺寸被置换(重新排列)为 dims。 |
深度学习模型(神经网络)都是以某种方式操纵张量。由于矩阵乘法的规则,如果形状不匹配,就会遇到错误。这些方法可帮助您确保张量的正确元素与其他张量的正确元素混合。
重塑维度形状
reshape
reshape 函数可以在保证张量数据不变的前提下
改变数据的维度,将其转换成指定的形状。使用
torch.reshape()增加一个维度。
import torch torch.random.manual_seed(21) data = torch.randint(0, 10, [4, 5, 6]) print(data) print(data.shape) print(data.size()) # 1. reshape # 1.1 降维 data1 = torch.reshape(data, [2, -1]) # -1表示自动计算 print(data1.shape) # torch.Size([2, 60]) # 1.2 改变形状 data2 = torch.reshape(data, [2, 5, -1]) print(data2.shape) # torch.Size([2, 5, 12])
view/contiguous
view 函数也可以用于修改张量的形状,只能用于存储在整块内存中的张量。
在 PyTorch 中,有些张量是由不同的数据块组成的,它们并没有存储在整块的内存中,view 函数无法对这样的张量进行变形处理。例如: 一个张量经过了 transpose 或者 permute 函数的处理之后,就无法使用 view 函数进行形状操作。
此时需要先使用 contiguous 函数转换为整块内存的张量,再使用 view 函数。
# 2. view(): 存储在一块内存上才可以操作 # 查看data是否在一块内存上 print(data.is_contiguous()) # True # 2.1 在一块内存上, 改变形状 data3 = data.view(3, 8, -1) print(data3.shape) # torch.Size([3, 8, 5]) # 2.2 不在一块内存上, 改变形状 # 2.2.1 交换数据维度, 使数据在不同的内存上 # data4 = data.permute(2, 0, 1) # 一次交换多个维度 data4 = torch.transpose(data, 1, 2) # 交换两个维度 print(data4.is_contiguous()) # False # 2.2.2 转换为同一内存 print(data4.contiguous().is_contiguous()) # True # 改变形状 data5 = data4.contiguous().view(3, 8, -1) print(data5.shape) # torch.Size([3, 8, 5])
stack
将新张量堆叠五次,使用
torch.stack()来实现。
x = torch.arange(1, 9) x_stack = torch.stack([x, x, x, x], dim=0) # 按0维堆叠 print(x_stack)
升维降维
squeeze 函数删除形状为 1 的维度(降维),unsqueeze 函数添加形状为1的维度(升维)。
unsqueeze升维
# 4. unsqueeze(): 增加维度 data = torch.tensor([1, 2, 3, 4, 5]) print(data.shape) # torch.Size([5]) data1 = data.unsqueeze(dim=0) print(data1.shape) # torch.Size([1, 5]) data2 = data.unsqueeze(dim=1) print(data2.shape) # torch.Size([5, 1]) data3 = data.unsqueeze(dim=-1) print(data3.shape) # torch.Size([5, 1])
squeeze降维
只可以将维度1的维度删除
# 5. squeeze(): 删除维度 data4 = data3.squeeze() print(data4.shape) # torch.Size([5]) data5 = data1.squeeze(dim=0) print(data5.shape) # torch.Size([5])
维度交换
transpose 函数可以实现交换张量形状的指定维度,
例如: 一个张量的形状为 (2, 3, 4) 可以通过 transpose 函数把 3 和 4 进行交换, 将张量的形状变为 (2, 4, 3) 。
permute 函数可以一次交换更多的维度。
# 6. 交换维度 data = torch.randint(0, 10, [4, 5, 6]) print(data.shape) # torch.Size([4, 5, 6]) # 交换1和2维度 data1 = torch.transpose(data, 1, 2) print(data1.shape) # torch.Size([4, 6, 5]) data2 = data.permute(0, 2, 1) print(data2.shape) # torch.Size([4, 6, 5])
张量形状总结
-
reshape 函数可以在保证张量数据不变的前提下改变数据的维度
-
squeeze 和 unsqueeze 函数可以用来增加或者减少维度
-
transpose 函数可以实现交换张量形状的指定维度, permute 可以一次交换更多的维度
-
view 函数也可以用于修改张量的形状, 但是它要求被转换的张量内存必须连续,所以一般配合 contiguous 函数使用
张量拼接
将多个张量按指定维度(根据维度索引)拼接成一个张量
torch.cat([data1, data2...], dim=维度索引)
import torch data1 = torch.randint(1, 11, [1, 3, 4]) data2 = torch.randint(1, 11, [1, 3, 4]) # print(data1) # print(data2) # 按0维拼接 data3 = torch.cat([data1, data2], dim=0) print(data3) print(data3.shape) # 按1维拼接 data4 = torch.cat([data1, data2], dim=1) print(data4) print(data4.shape) # 按2维拼接 data5 = torch.cat([data1, data2], dim=2) print(data5) print(data5.shape)
自动微分模块
再反向传播中, 用于计算梯度

正向传播: 由x得到z
反向传播: 由损失更新权重参数
一维
多维
import torch
def test02():# 输入张量 2*5x = torch.ones(2,5)# 目标值是 2*3y = torch.zeros(2,3)# 设置要更新的权重和偏置的初始值w = torch.randn(5, 3,requires_grad=True)b = torch.randn(3, requires_grad=True)# 设置网络的输出值z = torch.matmul(x, w) + b # 矩阵乘法# 设置损失函数,并进行损失的计算loss = torch.nn.MSELoss()loss = loss(z, y)# 自动微分loss.backward()# 打印 w,b 变量的梯度# backward 函数计算的梯度值会存储在张量的 grad 变量中print("W的梯度:", w.grad)print("b的梯度", b.grad)
案例-线性回归
pytorch模型构建流程:
准备训练集数据
使用 PyTorch 的 data.DataLoader 代替自定义的数据加载器
打乱数据顺序, 数据分批次
构建要使用的模型
使用 PyTorch 的 nn.Linear 代替自定义的假设函数
设置损失函数和优化器
使用 PyTorch 的 nn.MSELoss() 代替自定义的平方损失函数
使用 PyTorch 的 optim.SGD 代替自定义的优化器
模型训练
225原则:
2: 2个初始化参数(损失函数, 优化器)
2: 2个遍历(epoch: 轮次, 数据: 批次大小)
5: 前向传播, 损失函数, 梯度清零, 反向传播, 参数更新
构建数据集
# 导入相关模块
import torch
from torch.utils.data import TensorDataset # 构造数据集对象
from torch.utils.data import DataLoader # 数据加载器
from torch import nn # nn模块中有平方损失函数和假设函数
from torch import optim # optim模块中有优化器函数
from sklearn.datasets import make_regression # 创建线性回归模型数据集
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 定义函数创建数据集: 线性回归: y = kx + b
def creat_datasets():x, y, coef = make_regression(n_samples=100,n_features=1,noise=10,coef=True,bias=1.5,random_state=21)x = torch.tensor(x)y = torch.tensor(y)
return x, y, coef
if __name__ == '__main__':x, y, coef = creat_datasets()plt.scatter(x, y)x = torch.linspace(x.min(), x.max(), 1000)# y1 = torch.tensor([coef * i + 1.5 for i in x]) # 报错y1 = torch.tensor([i * coef + 1.5 for i in x]) # i为张量, 只可以张量 * 标量plt.plot(x, y1, label='predict')plt.legend()plt.grid()plt.xlabel('x')plt.ylabel('y')plt.show()
构建数据加载器和模型构建
# 构建数据加载器和模型 def data_loader(x, y):# 构造数据集对象dataset = TensorDataset(x, y)# 构造数据加载器# batch_size: 批次大小# batch: 批次数量# shuffle: 是否打乱顺序dataloader = DataLoader(dataset, batch_size=10, shuffle=True)# 构造模型model = nn.Linear(1, 1)return dataloader, model
训练参数设置
# 设置损失函数和优化器 def loss_optimizer(model):# 设置损失函数: 均方损失函数loss_fn = nn.MSELoss()# 设置优化器: 随机梯度下降, 学习率0.01optimizer = optim.SGD(model.parameters(), lr=0.01)return loss_fn, optimizer
模型训练
# 训练模型 def train_model(dataloader, model, loss_fn, optimizer):# 训练100轮epoch = 100# 存储每轮损失loss_epoch = []total_loss = 0train_sample = 0# 训练轮次for i in range(epoch):# 遍历批次for train_x, train_y in dataloader:# 预测值, 正向传播y_pred = model(train_x.type(torch.float32))# 计算损失loss = loss_fn(y_pred, train_y.reshape(-1, 1).type(torch.float32))# 累加损失total_loss += loss.item()# 累加样本数量train_sample += len(train_y)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 优化器更新参数optimizer.step()# 存储批次损失loss_epoch.append(total_loss / train_sample)return loss_epoch, epoch
轮次损失可视化
if __name__ == '__main__':x, y, coef = creat_datasets()dataloader, model = data_loader(x, y)loss_fn, optimizer = loss_optimizer(model)loss_epoch, epochs = train_model(dataloader, model, loss_fn, optimizer)print(loss_epoch)# 绘制损失变化曲线plt.plot(range(epochs), loss_epoch)plt.title('损失变化曲线')plt.grid()plt.show()# 绘制拟合直线plt.scatter(x, y)x = torch.linspace(x.min(), x.max(), 1000)y1 = torch.tensor([v * model.weight + model.bias for v in x])y2 = torch.tensor([v * coef + 1.5 for v in x])plt.plot(x, y1, label='训练')plt.plot(x, y2, label='真实')plt.grid()plt.legend()plt.show()
案例总结

相关文章:
深度学习-张量相关
一. 张量的创建 张量简介 张量是pytorch的基本数据结构 张量,英文为Tensor,是机器学习的基本构建模块,是以数字方式表示数据的形式。 例如,图像可以表示为形状为 [3, 224, 224] 的张量,这意味着 [colour_channels, h…...
电脑提示xinput1_3.dll丢失怎么解决,分享6种有效的解决方法
xinput1_3.dll 是一个动态链接库(DLL)文件,它在Windows操作系统中扮演着重要的角色,特别是在处理游戏控制器和其他输入设备的交互方面。这个文件是Microsoft DirectX软件包的一部分,DirectX是微软公司开发的一个多媒体…...
【计网】数据链路层笔记
【计网】数据链路层 数据链路层概述 数据链路层在网络体系结构中所处的地位 链路、数据链路和帧 链路(Link)是指从一个节点到相邻节点的一段物理线路(有线或无线),而中间没有任何其他的交换节点。 数据链路(Data Link)是基于链路的。当在一条链路上传送数据时&a…...
蓝牙FTP 协议详解及 Android 实现
文章目录 前言一、什么是蓝牙 FTP 协议?二、FTP 的工作流程1.蓝牙设备初始化2. 设备发现与配对3. 建立OBEX FTP 连接4. 文件传输文件上传(通过OBEX PUT命令)文件下载(通过OBEX GET命令) 5. 关闭OBEX会话 三、进阶应用与…...
【前端】Svelte:动画效果
在现代前端开发中,动画效果可以大大提升用户体验,使应用更生动、易用。Svelte 提供了灵活的动画 API,让开发者能够快速实现从简单过渡到复杂动画的各种效果。本文将系统性地介绍 Svelte 的动画功能,并通过多个示例演示如何创建动感…...
2024系统架构师--论基于架构的软件设计方法(ABSD)及应用(论文范文)
题目: 基于架构的软件设计(Architecture-Based Software Design,ABSD)方法以构成软件架构的商业、质量和功能需求等要素来驱动整个软件开发过程。ABSD是一个自顶向下,递归细化的软件开发方法,它以软件系统功能的分解为基础,通过选择架构风格实现质量和商业需求,并强调在架…...
ORU 的 Open RAN 管理平面 (M 平面)
[TOC](ORU 的 Open RAN 管理平面 (M 平面)) ORU 的 Open RAN 管理平面 (M 平面) https://www.techplayon.com/open-ran-management-plane-m-plane-for-open-radio-unit/ ORU M 平面 在 ORAN 中,设置参数的 O-RU 管理功能是通过 M-Plane 完成的。管理功能包括 O-…...
软件缺陷等级评定综述
1. 前言 正确评估软件缺陷等级,在项目的生命周期中有着重要的作用: 指导缺陷修复的优先级和资源分配 在软件开发和维护过程中,资源(包括人力、时间和资金)是有限的。通过明确缺陷的危险等级,可以帮助团队合…...
Nuxt.js 应用中的 schema:extend事件钩子详解
title: Nuxt.js 应用中的 schema:extend事件钩子详解 date: 2024/11/10 updated: 2024/11/10 author: cmdragon excerpt: schema:extend 钩子使开发者能够扩展默认数据模式,为特定业务需求添加自定义字段和验证。 categories: 前端开发tags: Nuxt钩子数据扩展自定义验证应…...
自然语言处理在客户服务中的应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 自然语言处理在客户服务中的应用 自然语言处理在客户服务中的应用 自然语言处理在客户服务中的应用 引言 自然语言处理概述 定义…...
OpenCoder:首个完全开源的顶级代码大模型,训练秘籍全公开!| LLM×MapReduce,无需训练就超越GPT-4!
大模型领域的发展日新月异,每天都有许多有趣的论文值得深入品读。下面是本期觉得比较有意思的论文: 1、OpenCoder:首个完全开源的顶级代码大模型,训练秘籍全公开!2、超长文本处理新突破!LLMMapReduce&…...
springboot静态资源映射不生效问题
最近有个同事问我,静态资源映射不生效的问题,很正常我想不就是配置下资源路径就可以了吗?类似配置如下代码 Configuration public class CorsConfig implements WebMvcConfigurer {Overridepublic void addResourceHandlers(ResourceHandlerR…...
通过 SSH 隧道将本地端口转发到远程主机
由于服务器防火墙,只开放了22端口,想要通过5901访问服务器上的远程桌面,可以通过下面的方式进行隧道转发。 一、示例命令 这条代码的作用是通过 SSH 创建一个 本地端口转发,将你本地的端口(5901)通过加密的 SSH 隧道连接到远程服务器上的端口(5901)。这种方式通常用于在…...
【北京迅为】itop-3588开发板摄像头使用手册Android12 双摄方案
本章节对应资料在网盘资料“iTOP-3588 开发板\02_【iTOP-RK3588 开发板】开发资料 \07_Android 系统开发配套资料\08_Android12 摄像头使用配套资料”目录下下载。 2.1 Android12 前摄后摄 网盘中默认的 Android12 源码支持四个摄像头单独打开,本小节我们来修改源码…...
初见Linux:基础开发工具
前言: 这篇文章我们将讲述Linux的基本开发工具,以及讨论Linux的生态圈,最后再了解vim开发工具。 Yum: YUM(Yellowdog Updater Modified)是一个在Linux系统中用于管理软件包的工具,特别是在基于…...
微服务架构面试内容整理-分布式配置管理-Nacos Config
Nacos Config 是 Nacos 提供的一个配置管理功能,专门用于动态管理应用的配置。在微服务架构中,Nacos Config 允许开发者集中管理和动态更新各个服务的配置,从而提升系统的灵活性和可维护性。以下是 Nacos Config 的主要特点、工作原理和使用场景: 主要特点 1. 动态配置管理…...
React官网生成Recat项目的区别
1. Next.js 特点: 页面级路由:使用文件系统路由,基于 /pages 文件夹的结构自动创建 URL 路径。渲染模式:支持三种渲染模式:静态生成 (SSG)、服务器端渲染 (SSR) 和客户端渲染 (CSR),并允许根据页面的具体需…...
网络安全---安全见闻
网络安全—安全见闻 拓宽视野不仅能够丰富我们的知识体系,也是自我提升和深造学习的重要途径!!! Web程序(网站) web站点、app都属于Web程序 二进制程序 与逆向分析挂钩 驱动程序 驱动程序也属于软件,以Windows系统…...
在 CSS 中,gap 是 布局容器(flex 或 grid)的属性。它用于设置容器内子元素之间的间距。
在 CSS 中,gap 是 布局容器(flex 或 grid)的属性。它用于设置容器内子元素之间的间距。以下是 gap 属性在不同布局中的应用: 1. 在 CSS Grid 布局中 gap 定义了网格行和列之间的间距。可以分别使用 row-gap 和 column-gap 设置行…...
[zotero]Ubuntu搭建WebDAV网盘
搭建Ubuntu Apache WebDAV网盘的综合步骤,使用666端口: 安装Apache和WebDAV模块: sudo apt update sudo apt install apache2 sudo a2enmod dav sudo a2enmod dav_fs创建WebDAV目录: sudo mkdir /var/www/webdav sudo chown www-d…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...




