4.线性神经网络
4.线性神经网络
目录
- 线性回归
- 线性回归的基本元素
- 线性模型
- 损失函数
- 解析解
- 随机梯度下降
- 矢量化加速
- 正态分布与平方损失
- 线性回归的基本元素
- 优化方法
- 梯度下降
- 选择学习率
- 小批量随机梯度下降
- 选择批量大小
- 总结
- 线性回归的从零开始实现
- 生成数据集
- 读取数据集
- 初始化模型参数
- 定义模型
- 定义损失函数
- 定义优化算法
- 训练
- 线性回归的简介实现
- 生成数据集
- 读取数据集
- 定义模型
- 初始化模型参数
- 定义损失函数
- 定义优化函数
- 训练
- softmax回归
- 分类问题
- 网络架构
- softmax运算
- 小批量样本的矢量化
- 损失函数
- L2 Loss均方损失函数
- L1 Loss绝对值损失函数
- Huber’s Robust Loss鲁棒损失函数
- 对数似然
- softmax及其导数
- 模型的预测和评估
- 图像分类数据集
- 读取数据集
- 读取小批量
- 整合所有组件
- softmax回归的从零开始实现
- 初始化模型参数
- 定义softmax操作
- 定义模型
- 定义损失函数
- 分类精度
- 训练
- 预测
- softmax回归的简洁实现
- 初始化模型参数
- 重新审视Softmax的实现
- 优化算法
- 训练
回归(regression)是能为一个或多个自变量与因变量之间关系建模的一类方法。 在自然科学和社会科学领域,回归经常用来表示输入和输出之间的关系。
在机器学习领域中的大多数任务通常都与_预测_(prediction)有关。 当我们想预测一个数值时,就会涉及到回归问题。 常见的例子包括:预测价格(房屋、股票等)、预测住院时间(针对住院病人等)、 预测需求(零售销量等)。 但不是所有的_预测_都是回归问题。 在后面的章节中,我们将介绍分类问题。分类问题的目标是预测数据属于一组类别中的哪一个。
线性回归
线性回归的基本元素
线性回归(linear regression)可以追溯到19世纪初, 它在回归的各种标准工具中最简单而且最流行。 线性回归基于几个简单的假设: 首先,假设自变量x和因变量y之间的关系是线性的, 即y可以表示为x中元素的加权和,这里通常允许包含观测值的一些噪声; 其次,我们假设任何噪声都比较正常,如噪声遵循正态分布。
为了解释_线性回归_,我们举一个实际的例子: 我们希望根据房屋的面积(平方英尺)和房龄(年)来估算房屋价格(美元)。 为了开发一个能预测房价的模型,我们需要收集一个真实的数据集。 这个数据集包括了房屋的销售价格、面积和房龄。
在机器学习的术语中,该数据集称为_训练数据集_(training data set) 或_训练集_(training set)。
每行数据(比如一次房屋交易相对应的数据)称为_样本_(sample), 也可以称为_数据点 _(data point)或_数据样本 _(data instance)。
我们把试图预测的目标(比如预测房屋价格)称为_标签_(label)或_目标 _(target)。
预测所依据的自变量(面积和房龄)称为_特征_(feature)或_协变量 _(covariate)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xBEaIir8-1673764739910)(image/image_AN4vNwK1j1.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pVoemAYT-1673764739914)(image/image_QkLP9mOKK9.png)]
线性模型可以看作一个单层的神经网络
我们将线性回归模型描述为一个神经网络。 需要注意的是,该图只显示连接模式,即只显示每个输入如何连接到输出,隐去了权重和偏置的值。
训练数据
参数学习
显示解
线性模型
损失函数
在我们开始考虑如何用模型_拟合_(fit)数据之前,我们需要确定一个拟合程度的度量。 损失函数(loss function)能够量化目标的_实际_值与_预测_值之间的差距。 通常我们会选择非负数作为损失,且数值越小表示损失越小,完美预测时的损失为0。 回归问题中最常用的损失函数是平方误差函数。 当样本i的预测值为y^(i)\hat{y}^{(i)}y^(i),其相应的真实标签为y(i)y^{(i)}y(i)时, 平方误差可以定义为以下公式:
l(i)(w,b)=12(y^(i)−y(i))2.l^{(i)}(\mathbf{w}, b) = \frac{1}{2} \left(\hat{y}^{(i)} - y^{(i)}\right)^2.l(i)(w,b)=21(y^(i)−y(i))2.
由于训练数据集并不受我们控制,所以经验误差只是关于模型参数的函数。 为了进一步说明,来看下面的例子。 我们为一维情况下的回归问题绘制图像。
由于平方误差函数中的二次方项, 估计值y^(i)\hat{y}^{(i)}y^(i)和观测值y(i)y^{(i)}y(i)之间较大的差异将导致更大的损失。 为了度量模型在整个数据集上的质量,我们需计算在训练集n个样本上的损失均值(也等价于求和)。
L(w,b)=1n∑i=1nl(i)(w,b)=1n∑i=1n12(w⊤x(i)+b−y(i))2.L(\mathbf{w}, b) =\frac{1}{n}\sum_{i=1}^n l^{(i)}(\mathbf{w}, b) =\frac{1}{n} \sum_{i=1}^n \frac{1}{2}\left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right)^2.L(w,b)=n1∑i=1nl(i)(w,b)=n1∑i=1n21(w⊤x(i)+b−y(i))2.
在训练模型时,我们希望寻找一组参数(w∗,b∗)\left(\mathbf{w}^{*}, b^{*}\right)(w∗,b∗), 这组参数能最小化在所有训练样本上的总损失。如下式:
w∗,b∗=argminw,bL(w,b).\mathbf{w}^{*}, b^{*}=\underset{\mathbf{w}, b}{\operatorname{argmin}} L(\mathbf{w}, b).w∗,b∗=w,bargminL(w,b).
解析解
随机梯度下降
矢量化加速
在训练我们的模型时,我们经常希望能够同时处理整个小批量的样本。 为了实现这一点,需要我们对计算进行矢量化, 从而利用线性代数库,而不是在Python中编写开销高昂的for循环。
%matplotlib inline
import math
import time
import numpy as np
import torch
from d2l import torch as d2l
为了说明矢量化为什么如此重要,我们考虑对向量相加的两种方法。
我们实例化两个全为1的10000维向量。 在一种方法中,我们将使用Python的for循环遍历向量; 在另一种方法中,我们将依赖对+
的调用。
n = 10000
a = torch.ones([n])
b = torch.ones([n])
我们将频繁地进行运行时间的基准测试,所以我们定义一个计时器:
class Timer: #@save"""记录多次运行时间"""def __init__(self):self.times = []self.start()def start(self):"""启动计时器"""self.tik = time.time()def stop(self):"""停止计时器并将时间记录在列表中"""self.times.append(time.time() - self.tik)return self.times[-1]def avg(self):"""返回平均时间"""return sum(self.times) / len(self.times)def sum(self):"""返回时间总和"""return sum(self.times)def cumsum(self):"""返回累计时间"""return np.array(self.times).cumsum().tolist()
现在我们可以对工作负载进行基准测试。
首先,我们使用for循环,每次执行一位的加法。
c = torch.zeros(n)
timer = Timer()
for i in range(n):c[i] = a[i] + b[i]
f'{timer.stop():.5f} sec'#----------输出结果-----------
'0.12068 sec'
或者,我们使用重载的+
运算符来计算按元素的和。
timer.start()
d = a + b
f'{timer.stop():.5f} sec'#----------输出结果-----------
'0.00000 sec'
结果很明显,第二种方法比第一种方法快得多。 矢量化代码通常会带来数量级的加速。 另外,我们将更多的数学运算放到库中,而无须自己编写那么多的计算,从而减少了出错的可能性。
正态分布与平方损失
接下来,我们通过对噪声分布的假设来解读平方损失目标函数。
正态分布和线性回归之间的关系很密切。 正态分布(normal distribution),也称为_高斯分布_(Gaussian distribution), 最早由德国数学家高斯(Gauss)应用于天文学研究。 简单的说,若随机变量x具有均值μ和方差σ2(标准差σ),其正态分布概率密度函数如下:
p(x)=12πσ2exp(−12σ2(x−μ)2)p(x)=\frac{1}{\sqrt{2 \pi \sigma^{2}}} \exp \left(-\frac{1}{2 \sigma^{2}}(x-\mu)^{2}\right) p(x)=2πσ21exp(−2σ21(x−μ)2)
下面我们定义一个Python函数来计算正态分布。
def normal(x, mu, sigma):p = 1 / math.sqrt(2 * math.pi * sigma**2)return p * np.exp(-0.5 / sigma**2 * (x - mu)**2)
我们现在可视化正态分布。
# 再次使用numpy进行可视化
x = np.arange(-7, 7, 0.01)# 均值和标准差对
params = [(0, 1), (0, 2), (3, 1)]
d2l.plot(x, [normal(x, mu, sigma) for mu, sigma in params], xlabel='x',ylabel='p(x)', figsize=(4.5, 2.5),legend=[f'mean {mu}, std {sigma}' for mu, sigma in params])
优化方法
梯度下降
选择学习率
学习率不能太大也不能太小,人为选择
小批量随机梯度下降
选择批量大小
不能太小:每次计算量太小,不适合并行来最大利用计算资源
不能太大:内存消耗增加,浪费计算。例如所有的样本都是相同的
总结
- 梯度下降通过不断沿着反梯度方向更新参数求解
- 小批量随机梯度下降是深度学习默认的求解算法
- 两个重要的超参数是批量大小和学习率
线性回归的从零开始实现
在了解线性回归的关键思想之后,我们可以开始通过代码来动手实现线性回归了。 在这一节中,我们将从零开始实现整个方法, 包括数据流水线、模型、损失函数和小批量随机梯度下降优化器。 虽然现代的深度学习框架几乎可以自动化地进行所有这些工作,但从零开始实现可以确保我们真正知道自己在做什么。 同时,了解更细致的工作原理将方便我们自定义模型、自定义层或自定义损失函数。 在这一节中,我们将只使用张量和自动求导。 在之后的章节中,我们会充分利用深度学习框架的优势,介绍更简洁的实现方式。
%matplotlib inline
import random
import torch
from d2l import torch as d2l
生成数据集
为了简单起见,我们将根据带有噪声的线性模型构造一个人造数据集。 我们的任务是使用这个有限样本的数据集来恢复这个模型的参数。 我们将使用低维数据,这样可以很容易地将其可视化。
在下面的代码中,我们生成一个包含1000个样本的数据集, 每个样本包含从标准正态分布中采样的2个特征。 我们的合成数据集是一个矩阵X∈R1000×2\mathbf{X}\in \mathbb{R}^{1000 \times 2}X∈R1000×2。
def synthetic_data(w, b, num_examples): #@save"""生成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))
这是一个名为 synthetic_data()
的函数,用于生成用于训练线性回归模型的虚拟数据。
它有三个参数:
w
:线性模型的权重b
:线性模型的偏移量num_examples
:要生成的样本数
它的工作流程如下:
- 使用
torch.normal()
函数生成均值为 0,标准差为 1 的随机数组X
。数组的形状为(num_examples
,len(w)
)。
📌形状为(
num_examples
,len(w)
)的数组是一个二维数组。它的第一维大小为num_examples
,表示数组包含的样本数。第二维大小为len(w)
,表示数组包含的特征数。
- 使用线性模型的权重
w
和偏移量b
计算y
。具体来说,y=Xw+b
。 - 使用
torch.normal()
函数为每个样本添加噪声。噪声的均值为 0,标准差为 0.01。 - 返回生成的输入数组
X
和标签数组y
。
true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
注意,features
中的每一行都包含一个二维数据样本, labels
中的每一行都包含一维标签值(一个标量)。
首先创建了两个张量 true_w
和 true_b
。
true_w
是一个长度为 2 的张量,包含两个数字 2 和 -3.4。
true_b
是一个数字 4.2。
然后,它调用了前面定义的 synthetic_data()
函数,生成了虚拟数据。这个函数接受三个参数:线性模型的权重 true_w
,偏移量 true_b
和样本数 1000
。它返回两个数组:输入数组 features
和标签数组 labels
。
features
数组是一个形状为(1000,2)的张量,包含 1000 个样本,每个样本有 2 个特征。
labels
数组是一个形状为(1000,1)的张量,包含 1000 个样本的标签
print('features:', features[0],'\nlabel:', labels[0])#----------输出结果-----------
features: tensor([0.2525, 0.7209])
label: tensor([2.2487])
通过生成第二个特征features[:, 1]
和labels
的散点图, 可以直观观察到两者之间的线性关系。
features
数组的第一个样本和 labels
数组的第一个样本是对应的,即第一个样本的特征和标签是一组。
d2l.set_figsize()
d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BKhjxcuh-1673764739920)(image/image_MiudYXJst-.png)]
读取数据集
回想一下,训练模型时要对数据集进行遍历,每次抽取一小批量样本,并使用它们来更新我们的模型。 由于这个过程是训练机器学习算法的基础,所以有必要定义一个函数, 该函数能打乱数据集中的样本并以小批量方式获取数据。
在下面的代码中,我们定义一个data_iter
函数, 该函数接收批量大小、特征矩阵和标签向量作为输入,生成大小为batch_size
的小批量。 每个小批量包含一组特征和标签。
def data_iter(batch_size, features, labels):num_examples = len(features) # 样本长度indices = list(range(num_examples)) # 创建样本索引# 这些样本是随机读取的,没有特定的顺序random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices = torch.tensor(indices[i: min(i + batch_size, num_examples)])yield features[batch_indices], labels[batch_indices]
这是一个名为 data_iter()
的函数,用于生成输入数据的迭代器。
它有三个参数:
batch_size
:批量大小。features
:输入数据的特征数组。labels
:输入数据的标签数组。
它的工作流程如下:
- 计算输入数据的样本数
num_examples
。 - 创建样本索引的列表
indices
。 - 打乱样本的顺序,使得它们的顺序是随机的。
- 使用循环,逐个读取批量的样本。
- 使用
yield
语句返回当前批量的特征数组和标签数组。
这段代码中的 indices[i: min(i + batch_size, num_examples)]
是一个切片操作,它用于从索引列表 indices
中选取一个连续的子序列。
i: min(i + batch_size, num_examples)
表示从索引 i
开始,选取连续的索引。这个子序列的长度为 batch_size
,但是如果 i + batch_size
大于 num_examples
,那么这个子序列就不会包含最后几个索引。例如,如果 num_examples=10
,batch_size=3
和 i=5
,那么这个切片操作的结果就是 [5, 6, 7]。
通常,我们利用GPU并行运算的优势,处理合理大小的“小批量”。 每个样本都可以并行地进行模型计算,且每个样本损失函数的梯度也可以被并行计算。 GPU可以在处理几百个样本时,所花费的时间不比处理一个样本时多太多。
我们直观感受一下小批量运算:读取第一个小批量数据样本并打印。 每个批量的特征维度显示批量大小和输入特征数。 同样的,批量的标签形状与batch_size
相等。
batch_size = 10for X, y in data_iter(batch_size, features, labels):print(X, '\n', y)break#----------输出结果-----------
tensor([[ 0.0221, 0.2320],[ 0.6794, -0.5034],[ 0.1363, -0.9847],[ 0.4438, -0.1550],[-0.8514, 0.1900],[ 0.0214, 0.9961],[-1.1829, 0.7807],[-1.0912, 1.1282],[ 0.3664, -1.3300],[-0.5001, 0.6672]]) tensor([[ 3.4437],[ 7.2608],[ 7.8031],[ 5.6222],[ 1.8395],[ 0.8499],[-0.8188],[-1.8158],[ 9.4456],[ 0.9353]])
当我们运行迭代时,我们会连续地获得不同的小批量,直至遍历完整个数据集。 上面实现的迭代对教学来说很好,但它的执行效率很低,可能会在实际问题上陷入麻烦。 例如,它要求我们将所有数据加载到内存中,并执行大量的随机内存访问。 在深度学习框架中实现的内置迭代器效率要高得多, 它可以处理存储在文件中的数据和数据流提供的数据。
初始化模型参数
在我们开始用小批量随机梯度下降优化我们的模型参数之前, 我们需要先有一些参数。 在下面的代码中,我们通过从均值为0、标准差为0.01的正态分布中采样随机数来初始化权重, 并将偏置初始化为0。
w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
这段代码中使用了 PyTorch 库中的 normal()
函数和 zeros()
函数分别创建了一个服从正态分布的张量和一个全 0 张量。
normal()
函数的参数有:
0
:均值。0.01
:标准差。size=(2,1)
:张量的形状。这里的形状是 (2,1),表示这个张量有 2 行和 1 列。requires_grad=True
:是否要跟踪这个张量的梯度。如果设为True
,那么这个张量在反向传播中会自动计算梯度。
zeros()
函数的参数有:
1
:张量的形状。这里的形状是 (1,),表示这个张量有 1 个元素。requires_grad=True
:是否要跟踪这个
在初始化参数之后,我们的任务是更新这些参数,直到这些参数足够拟合我们的数据。 每次更新都需要计算损失函数关于模型参数的梯度。 有了这个梯度,我们就可以向减小损失的方向更新每个参数。
定义模型
接下来,我们必须定义模型,将模型的输入和参数同模型的输出关联起来。
def linreg(X, w, b): #@save"""线性回归模型"""return torch.matmul(X, w) + b
这是一个名为 linreg()
的函数,它实现了一个线性回归模型。
它有三个参数:
X
:输入数据的特征数组。w
:模型的权重参数。b
:模型的偏移参数。
它的工作流程如下:
- 使用 PyTorch 库中的
matmul()
函数计算矩阵乘法。 - 将矩阵乘法的结果加上偏移参数
b
。 - 返回结果。
这个函数的输入是输入数据的特征数组和模型的权重和偏移参数,输出是线性回归模型的预测结果。
定义损失函数
因为需要计算损失函数的梯度,所以我们应该先定义损失函数
def squared_loss(y_hat, y): #@save"""均方损失"""return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
这是一个名为 squared_loss()
的函数,它实现了均方损失的计算。
它有两个参数:
y_hat
:模型的预测结果。y
:真实的标签。
它的工作流程如下:
- 将预测结果与真实标签的差平方。
- 将平方的结果除以 2。
- 返回结果。
这个函数的输入是模型的预测结果和真实的标签,输出是均方损失的值。
定义优化算法
在每一步中,使用从数据集中随机抽取的一个小批量,然后根据参数计算损失的梯度。 接下来,朝着减少损失的方向更新我们的参数。 下面的函数实现小批量随机梯度下降更新。 该函数接受模型参数集合、学习速率和批量大小作为输入。每 一步更新的大小由学习速率lr
决定。 因为我们计算的损失是一个批量样本的总和,所以我们用批量大小(batch_size
) 来规范化步长,这样步长大小就不会取决于我们对批量大小的选择。
def sgd(params, lr, batch_size): #@save"""小批量随机梯度下降"""with torch.no_grad():for param in params:param -= lr * param.grad / batch_sizeparam.grad.zero_()
这是一个名为 sgd()
的函数,它实现了小批量随机梯度下降 (SGD) 算法。
它有三个参数:
params
:模型的参数列表。lr
:学习率。batch_size
:批量大小。
它的工作流程如下:
- 使用 PyTorch 库中的
no_grad()
函数创建一个上下文管理器。 - 使用循环,逐个处理模型的参数。
- 使用梯度下降的更新规则更新参数的值。
- 使用
zero_()
函数清空参数的梯度。
这个函数的作用是:对于给定的模型参数,使用 SGD 算法进行一次梯度下降。
训练
现在我们已经准备好了模型训练所有需要的要素,可以实现主要的训练过程部分了。 理解这段代码至关重要,因为从事深度学习后, 相同的训练过程几乎一遍又一遍地出现。 在每次迭代中,我们读取一小批量训练样本,并通过我们的模型来获得一组预测。 计算完损失后,我们开始反向传播,存储每个参数的梯度。 最后,我们调用优化算法sgd
来更新模型参数。
概括一下,我们将执行以下循环:
- 初始化参数
- 重复以下训练,直到完成
- 计算梯度g←∂(w,b)1∣B∣∑i∈Bl(x(i),y(i),w,b)\mathbf{g} \leftarrow \partial_{(\mathbf{w},b)} \frac{1}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} l(\mathbf{x}^{(i)}, y^{(i)}, \mathbf{w}, b)g←∂(w,b)∣B∣1∑i∈Bl(x(i),y(i),w,b)
- 更新参数(w,b)←(w,b)−ηg(\mathbf{w}, b) \leftarrow (\mathbf{w}, b) - \eta \mathbf{g}(w,b)←(w,b)−ηg
在每个_迭代周期_(epoch)中,我们使用data_iter
函数遍历整个数据集, 并将训练数据集中所有样本都使用一次(假设样本数能够被批量大小整除)。 这里的迭代周期个数num_epochs
和学习率lr
都是超参数,分别设为3和0.03。
lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss
for epoch in range(num_epochs):for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w, b), y) # X和y的小批量损失# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,# 并以此计算关于[w,b]的梯度l.sum().backward()sgd([w, b], lr, batch_size) # 使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(features, w, b), labels)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')#------------输出结果------------
epoch 1, loss 0.041482
epoch 2, loss 0.000166
epoch 3, loss 0.000049
这是一段训练模型的代码。它包含了两个循环:
- 第一个循环按照周期数重复迭代数据。
- 第二个循环按照批量大小迭代数据。
每个周期包含多个批次,在每个批次中,它会执行以下操作:
- 计算当前批次的损失值。
- 计算当前批次的梯度。
- 使用 SGD 算法更新模型的参数。
在每个周期结束时,它会计算整个训练集的损失值,并将其打印出来。
整个训练过程包括多个周期,每个周期包含多个批次,每个批次包含多个样本。
因为我们使用的是自己合成的数据集,所以我们知道真正的参数是什么。 因此,我们可以通过比较真实参数和通过训练学到的参数来评估训练的成功程度。 事实上,真实参数和通过训练学到的参数确实非常接近。
print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差: {true_b - b}')#------------输出结果------------
w的估计误差: tensor([ 0.0003, -0.0002], grad_fn=<SubBackward0>)
b的估计误差: tensor([0.0010], grad_fn=<RsubBackward1>)
线性回归的简介实现
生成数据集
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l
true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)
def synthetic_data(w, b, num_examples): #@save"""生成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))
读取数据集
我们可以调用框架中现有的API来读取数据。 我们将features
和labels
作为API的参数传递,并通过数据迭代器指定batch_size
。 此外,布尔值is_train
表示是否希望数据迭代器对象在每个迭代周期内打乱数据。
def load_array(data_arrays, batch_size, is_train=True): #@save"""构造一个PyTorch数据迭代器"""dataset = data.TensorDataset(*data_arrays)return data.DataLoader(dataset, batch_size, shuffle=is_train)batch_size = 10
data_iter = load_array((features, labels), batch_size)
next(iter(data_iter))# ---------------输出结果------------
[tensor([[ 0.6718, 0.5967],[-1.2405, -0.6843],[-1.3672, 0.0093],[-0.1689, 0.5642],[-0.1460, -1.2817],[ 0.8564, 0.5281],[ 1.2138, 0.6259],[-0.7343, -0.1812],[ 1.0611, 0.7354],[ 0.0861, -0.0404]]),tensor([[3.5074],[4.0387],[1.4269],[1.9447],[8.2659],[4.1071],[4.4991],[3.3432],[3.8256],[4.5022]])]
这段代码用于创建一个 PyTorch 数据迭代器。
它的工作流程如下:
- 将输入数据转换为 PyTorch 的
TensorDataset
格式。 - 使用
DataLoader
函数创建一个数据迭代器。 - 使用
iter()
函数获取数据迭代器的迭代器。 - 使用
next()
函数获取数据迭代器的下一个批次数据。
在这段代码中,输入数据是 features
和 labels
两个张量,批量大小是 batch_size
。
这个数据迭代器每次迭代时会返回一个批次的输入数据和标签,用于训练模型。
dataset = data.TensorDataset(*data_arrays)
其中这句代码创建了一个 TensorDataset
类的实例。这个类是 PyTorch 中的数据集类,用于将数据保存在张量中。
在这句代码中,*data_arrays
是 Python 中的打散参数 (unpacking arguments) 特性。它将 data_arrays
这个包含多个张量的元组,打散成多个单独的张量作为参数传入 TensorDataset
类的构造函数。
例如,如果 data_arrays
是 (tensor_1, tensor_2, tensor_3)
这样的元组,那么 *data_arrays
将被解释为 tensor_1, tensor_2, tensor_3
,这样就可以直接传入 TensorDataset
类的构造函数了。
定义模型
对于标准深度学习模型,我们可以使用框架的预定义好的层。这使我们只需关注使用哪些层来构造模型,而不必关注层的实现细节。 我们首先定义一个模型变量net
,它是一个Sequential
类的实例。 Sequential
类将多个层串联在一起。 当给定输入数据时,Sequential
实例将数据传入到第一层, 然后将第一层的输出作为第二层的输入,以此类推。 在下面的例子中,我们的模型只包含一个层,因此实际上不需要Sequential
。 但是由于以后几乎所有的模型都是多层的,在这里使用Sequential
会让你熟悉“标准的流水线”。
这一单层被称为全连接层(fully-connected layer), 因为它的每一个输入都通过矩阵-向量乘法得到它的每个输出。
在PyTorch中,全连接层在Linear
类中定义。 值得注意的是,我们将两个参数传递到nn.Linear
中。 第一个指定输入特征形状,即2,第二个指定输出特征形状,输出特征形状为单个标量,因此为1。
# nn是神经网络的缩写
from torch import nnnet = nn.Sequential(nn.Linear(2, 1))
这段代码创建了一个线性回归模型。线性回归模型是一种简单的神经网络模型,它只包含一个全连接层 (fully-connected layer),用于对输入数据进行线性变换。
具体来说,这段代码创建了一个 Sequential
类的实例,该实例是一个多层感知机 (multilayer perceptron, MLP)。它包含一个输入层和一个输出层,输入层的大小是 2,输出层的大小是 1。
这个模型的输入数据是 2 维的,输出是 1 维的。它可以用于对 2 维输入数据进行线性回归。
初始化模型参数
在使用net
之前,我们需要初始化模型参数。
如在线性回归模型中的权重和偏置。 深度学习框架通常有预定义的方法来初始化参数。 在这里,我们指定每个权重参数应该从均值为0、标准差为0.01的正态分布中随机采样, 偏置参数将初始化为零。
正如我们在构造nn.Linear
时指定输入和输出尺寸一样, 现在我们能直接访问参数以设定它们的初始值。 我们通过net[0]
选择网络中的第一个图层, 然后使用weight.data
和bias.data
方法访问参数。 我们还可以使用替换方法normal_
和fill_
来重写参数值。
net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)# ---------------输出结果------------
tensor([0.])
这段代码对线性回归模型的参数进行初始化。
在这段代码中,net[0]
表示线性回归模型的第一层,也就是唯一的一层。这一层包含两个参数:权重 (weight) 和偏差 (bias)。
weight.data.normal_(0, 0.01)
用于将权重初始化为均值为 0,标准差为 0.01 的随机数。
bias.data.fill_(0)
用于将偏差初始化为 0。
通常来说,我们需要对模型的参数进行初始化,以便模型在训练时能够更快收敛。对参数进行随机初始化可以帮助避免梯度消失或梯度爆炸的问题。
定义损失函数
计算均方误差使用的是MSELoss
类,也称为平方L2范数。 默认情况下,它返回所有样本损失的平均值。
loss = nn.MSELoss()
定义优化函数
小批量随机梯度下降算法是一种优化神经网络的标准工具, PyTorch在optim
模块中实现了该算法的许多变种。 当我们实例化一个SGD
实例时,我们要指定优化的参数 (可通过net.parameters()
从我们的模型中获得)以及优化算法所需的超参数字典。 小批量随机梯度下降只需要设置lr
值,这里设置为0.03。
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
训练
通过深度学习框架的高级API来实现我们的模型只需要相对较少的代码。 我们不必单独分配参数、不必定义我们的损失函数,也不必手动实现小批量随机梯度下降。 当我们需要更复杂的模型时,高级API的优势将大大增加。 当我们有了所有的基本组件,训练过程代码与我们从零开始实现时所做的非常相似。
回顾一下:在每个迭代周期里,我们将完整遍历一次数据集(train_data
), 不停地从中获取一个小批量的输入和相应的标签。 对于每一个小批量,我们会进行以下步骤:
- 通过调用
net(X)
生成预测并计算损失l
(前向传播)。 - 通过进行反向传播来计算梯度。
- 通过调用优化器来更新模型参数。
为了更好的衡量训练效果,我们计算每个迭代周期后的损失,并打印它来监控训练过程。
num_epochs = 3
for epoch in range(num_epochs):for X, y in data_iter:l = loss(net(X) ,y)trainer.zero_grad()l.backward()trainer.step()l = loss(net(features), labels)print(f'epoch {epoch + 1}, loss {l:f}')# ---------------输出结果------------
epoch 1, loss 0.000271
epoch 2, loss 0.000098
epoch 3, loss 0.000098
这段代码实现了线性回归模型的训练过程。
训练过程分为多个 epoch,每个 epoch 中包含多个批次 (batch)。在每个批次中,首先使用线性回归模型对输入数据进行预测,然后计算预测结果与真实标签之间的损失。
然后使用反向传播算法(backpropagation)计算每个参数的梯度,并更新参数。最后使用更新后的参数再次预测,计算并输出当前 epoch 的损失。
下面我们比较生成数据集的真实参数和通过有限数据训练获得的模型参数。 要访问参数,我们首先从net
访问所需的层,然后读取该层的权重和偏置。 正如在从零开始实现中一样,我们估计得到的参数与生成数据的真实参数非常接近。
w = net[0].weight.data
print('w的估计误差:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b的估计误差:', true_b - b)# ---------------输出结果------------
w的估计误差: tensor([-0.0002, -0.0008])
b的估计误差: tensor([0.0002])
这段代码用于输出训练后线性回归模型的参数,以及这些参数与真实参数之间的误差。
net[0].weight.data
表示线性回归模型的权重,net[0].bias.data
表示线性回归模型的偏差。
true_w
和 true_b
是真实参数,用于生成训练数据。
输出的结果表明,训练后的线性回归模型的参数与真实参数之间的误差很小。
softmax回归
回归可以用于预测_多少_的问题。 比如预测房屋被售出价格,或者棒球队可能获得的胜场数,又或者患者住院的天数。
事实上,我们也对_分类_问题感兴趣:不是问“多少”,而是问“哪一个”:
- 某个电子邮件是否属于垃圾邮件文件夹?
- 某个用户可能_注册_或_不注册_订阅服务?
- 某个图像描绘的是驴、狗、猫、还是鸡?
- 某人接下来最有可能看哪部电影?
通常,机器学习实践者用_分类_这个词来描述两个有微妙差别的问题:
1. 我们只对样本的“硬性”类别感兴趣,即属于哪个类别;
2. 我们希望得到“软性”类别,即得到属于每个类别的概率。 这两者的界限往往很模糊。其中的一个原因是:即使我们只关心硬类别,我们仍然使用软类别的模型。
分类问题
网络架构
为了估计所有可能类别的条件概率,我们需要一个有多个输出的模型,每个类别对应一个输出。 为了解决线性模型的分类问题,我们需要和输出一样多的仿射函数(affine function)。 每个输出对应于它自己的仿射函数。
在我们的例子中,由于我们有4个特征和3个可能的输出类别, 我们将需要12个标量来表示权重(带下标的www), 3个标量来表示偏置(带下标的bbb)。 下面我们为每个输入计算三个未规范化的预测(logit):o1o_1o1、o2o_2o2和o3o_3o3。
softmax运算
现在我们将优化参数以最大化观测数据的概率。 为了得到预测结果,我们将设置一个阈值,如选择具有最大概率的标签。
要将输出视为概率,我们必须保证在任何数据上的输出都是非负的且总和为1。 此外,我们需要一个训练的目标函数,来激励模型精准地估计概率。 例如, 在分类器输出0.5的所有样本中,我们希望这些样本是刚好有一半实际上属于预测的类别。 这个属性叫做校准(calibration)。
社会科学家邓肯·卢斯于1959年在选择模型(choice model)的理论基础上 发明的softmax函数正是这样做的: softmax函数能够将未规范化的预测变换为非负数并且总和为1,同时让模型保持 可导的性质。 为了完成这一目标,我们首先对每个未规范化的预测求幂,这样可以确保输出非负。 为了确保最终输出的概率值总和为1,我们再让每个求幂后的结果除以它们的总和。如下式:
y^=softmax(o)其中y^j=exp(oj)∑kexp(ok)\hat{\mathbf{y}}=\operatorname{softmax}(\mathbf{o}) \quad 其中 \quad \hat{y}_{j}=\frac{\exp \left(o_{j}\right)}{\sum_{k} \exp \left(o_{k}\right)} y^=softmax(o)其中y^j=∑kexp(ok)exp(oj)
小批量样本的矢量化
损失函数
L2 Loss均方损失函数
L1 Loss绝对值损失函数
Huber’s Robust Loss鲁棒损失函数
对数似然
softmax及其导数
模型的预测和评估
在训练softmax回归模型后,给出任何样本特征,我们可以预测每个输出类别的概率。 通常我们使用预测概率最高的类别作为输出类别。 如果预测与实际类别(标签)一致,则预测是正确的。 在接下来的实验中,我们将使用精度(accuracy)来评估模型的性能。 精度等于正确预测数与预测总数之间的比率。
图像分类数据集
MNIST数据集 (LeCun et al., 1998) 是图像分类中广泛使用的数据集之一,但作为基准数据集过于简单。 我们将使用类似但更复杂的Fashion-MNIST数据集 (Xiao et al., 2017)。
%matplotlib inline
import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2ld2l.use_svg_display()
读取数据集
我们可以通过框架中的内置函数将Fashion-MNIST数据集下载并读取到内存中。
# 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,
# 并除以255使得所有像素的数值均在0~1之间
trans = transforms.ToTensor() # 预处理:把图片转换为pytorch的tensor
mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)
mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FHUrY3r2-1673764739924)(image/image_PmKwQ2RcZP.png)]
这个代码分别使用 torchvision.datasets.FashionMNIST
函数加载了训练数据和测试数据。其中,参数 root
指定了数据所在的文件夹,参数 train
指定是加载训练数据还是测试数据,参数 transform
指定了对数据进行的变换,在这里使用了 transforms.ToTensor
函数将图像数据从 PIL
类型变换成32位浮点数格式,并除以255使得所有像素的数值均在0~1之间。参数 download
指定是否自动下载数据。
📌Fashion-MNIST由10个类别的图像组成, 每个类别由训练数据集(train dataset)中的6000张图像 和测试数据集(test dataset)中的1000张图像组成。 因此,训练集和测试集分别包含60000和10000张图像。 测试数据集不会用于训练,只用于评估模型性能。
len(mnist_train), len(mnist_test)
输出
(60000, 10000)
每个输入图像的高度和宽度均为28像素。 数据集由灰度图像组成,其通道数为1。 为了简洁起见,本书将高度h像素、宽度w像素图像的形状记为h×wh \times wh×w或(h,w)(h,w)(h,w)。
# 查看第一张图片的shape
mnist_train[0][0].shape
输出
torch.Size([1, 28, 28])
Fashion-MNIST中包含的10个类别,分别为t-shirt(T恤)、trouser(裤子)、pullover(套衫)、dress(连衣裙)、coat(外套)、sandal(凉鞋)、shirt(衬衫)、sneaker(运动鞋)、bag(包)和ankle boot(短靴)。 以下函数用于在数字标签索引及其文本名称之间进行转换**。**
def get_fashion_mnist_labels(labels): #@save"""返回Fashion-MNIST数据集的文本标签"""text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']return [text_labels[int(i)] for i in labels]
这段代码定义了一个函数 get_fashion_mnist_labels
,用于将 Fashion-MNIST 数据集的数字标签转换为文本标签。具体来说,该函数接受一个数字标签的列表,并返回一个与输入列表长度相同的文本标签列表。 在函数内部,定义了一个文本标签列表text_labels
,包含了 Fashion-MNIST 数据集中的 10 个类别,即 t-shirt、trouser、pullover、dress、coat、sandal、shirt、sneaker、bag 和 ankle boot。然后,使用列表推导式将输入的数字标签列表中的每个元素转换为文本标签,并返回转换后的文本标签列表。
我们现在可以创建一个函数来可视化这些样本。
def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5): #@save"""绘制图像列表"""figsize = (num_cols * scale, num_rows * scale) # 图像的长和宽_, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)axes = axes.flatten()for i, (ax, img) in enumerate(zip(axes, imgs)):if torch.is_tensor(img):# 图片张量ax.imshow(img.numpy())else:# PIL图片ax.imshow(img)ax.axes.get_xaxis().set_visible(False)ax.axes.get_yaxis().set_visible(False)if titles:ax.set_title(titles[i])return axes
这个函数的作用是将一个列表中的图像绘制到多个子图中,num_rows 和 num_cols 参数指定了将图像绘制成几行几列的矩阵。imags 参数是图像列表,titles 参数是图像标题列表,scale 参数是每个子图的高度和宽度与默认值的比值。在循环中,对于每个子图,首先判断图像是否是一个张量,如果是的话使用 imshow 函数绘制张量的内容,否则直接绘制 PIL 图像的内容。最后,如果传入了标题列表,就设置子图的标题。
d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
函数返回一个包含画板和轴的二元组。这个函数会创建一个新的画板,并将其分成 num_rows
行和 num_cols
列的网格。然后,它会在每个网格中创建一个轴。这个函数返回的第一个值是画板本身,第二个值是一个轴数组,它是一个二维数组,第 i 行第 j 列对应网格中的第 i 行第 j 列的轴。
axes = axes.flatten()
函数将二维数组展平成一维数组,即把所有轴都放在一个列表中。
在循环中,对于每个子图和图像对,它会检查图像是否是张量。如果是,则使用imshow函数绘制张量中的图像。否则,使用imshow绘制PIL图像。然后,它会隐藏子图的坐标轴,并如果有标题,则将标题添加到子图中。最后,函数返回子图矩阵。
以下是训练数据集中前几个样本的图像及其相应的标签。
X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))
show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y));
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W9rqVBX1-1673764739924)(image/image__PlVdGW80H.png)]
这段代码的作用是从 Fashion-MNIST 训练集中取出一个批次的数据,并使用 show_images 函数将这批数据中的图像可视化出来。具体来说,首先使用 data.DataLoader 函数从 mnist_train 中取出一个批次的数据。然后使用 X.reshape 将每张图像的张量重塑为二维张量,并传入 show_images 函数进行可视化。可视化结果中,每张图像都有一个对应的标签,使用 get_fashion_mnist_labels 函数将标签的数字索引转换为文本名称。
读取小批量
为了使我们在读取训练集和测试集时更容易,我们使用内置的数据迭代器,而不是从零开始创建。 回顾一下,在每次迭代中,数据加载器每次都会读取一小批量数据,大小为batch_size
。 通过内置数据迭代器,我们可以随机打乱了所有样本,从而无偏见地读取小批量。
batch_size = 256def get_dataloader_workers(): #@save"""使用4个进程来读取数据"""return 4train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,num_workers=get_dataloader_workers())
此代码创建了一个PyTorch的DataLoader,用于在训练期间从FashionMNIST数据集中加载小批量数据。DataLoader提供了一个更方便的方法来遍历数据集中的所有样本,并在训练时提供批量数据。参数batch_size定义了每个批量的大小,参数shuffle表示是否在每个epoch之间对数据进行洗牌,num_workers定义了使用几个进程来加载数据。
我们看一下读取训练数据所需的时间。
timer = d2l.Timer()
for X, y in train_iter:continue
f'{timer.stop():.2f} sec'
输出
'2.18 sec'
这个代码创建了一个数据加载器,用于读取Fashion-MNIST训练数据集中的每个批次。训练数据集中的每个样本都将打包成一个批次。这个代码还使用了一个定时器来测量数据加载器读取一个批次的时间。
整合所有组件
现在我们定义load_data_fashion_mnist
函数,用于获取和读取Fashion-MNIST数据集。 这个函数返回训练集和验证集的数据迭代器。 此外,这个函数还接受一个可选参数resize
,用来将图像大小调整为另一种形状。
def load_data_fashion_mnist(batch_size, resize=None): #@save"""下载Fashion-MNIST数据集,然后将其加载到内存中"""trans = [transforms.ToTensor()]if resize:trans.insert(0, transforms.Resize(resize))trans = transforms.Compose(trans)mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)return (data.DataLoader(mnist_train, batch_size, shuffle=True,num_workers=get_dataloader_workers()),data.DataLoader(mnist_test, batch_size, shuffle=False,num_workers=get_dataloader_workers()))
这段代码用来下载并加载Fashion-MNIST数据集。它通过使用torchvision的FashionMNIST数据集类实现,并将数据集的训练集和测试集读取到内存中。首先,使用transforms.ToTensor()将数据从PIL类型转换为张量,并将像素值除以255使得值域在0~1之间。如果传入了resize参数,则使用transforms.Resize()将图像的大小调整为指定大小。最后,使用transforms.Compose()将所有转换组成一个序列,然后传给FashionMNIST类的transform参数。
最后,返回由两个DataLoader实例组成的元组,分别对应训练集和测试集。对于训练集,shuffle参数设置为True,表示将数据打乱。在测试集上,shuffle参数设置为False,表示保持数据顺序。num_workers参数指定使用4个进程来读取数据,可以加快数据加载速度。
下面,我们通过指定resize
参数来测试load_data_fashion_mnist
函数的图像大小调整功能。
train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:print(X.shape, X.dtype, y.shape, y.dtype)break
输出
torch.Size([32, 1, 64, 64]) torch.float32 torch.Size([32]) torch.int64
输出为(32, 1, 64, 64) torch.float32 (32,) torch.int64,表示训练集中包含32个样本,每个样本为1个通道、64x64像素的张量,标签为32个整数。
我们现在已经准备好使用Fashion-MNIST数据集,便于下面的章节调用来评估各种分类算法。
softmax回归的从零开始实现
import torch
from IPython import display
from d2l import torch as d2lbatch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) # 返回训练集和测试集的迭代器
初始化模型参数
和之前线性回归的例子一样,这里的每个样本都将用固定长度的向量表示。 原始数据集中的每个样本都是28×28的图像。 本节将展平每个图像,把它们看作长度为784的向量。 在后面的章节中,我们将讨论能够利用图像空间结构的特征, 但现在我们暂时只把每个像素位置看作一个特征。
回想一下,在softmax回归中,我们的输出与类别一样多。** 因为我们的数据集有10个类别,所以网络输出维度为10。** 因此,权重将构成一个784×10的矩阵, 偏置将构成一个1×10的行向量。 与线性回归一样,我们将使用正态分布初始化我们的权重W
,偏置初始化为0。
num_inputs = 784
num_outputs = 10W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)
b = torch.zeros(num_outputs, requires_grad=True)
这段代码中,num_inputs
和num_outputs
是用来指定模型输入和输出的维度的。具体来说,num_inputs
指的是输入数据的特征数量,而num_outputs
指的是模型的输出类别数量。在这里,num_inputs
被赋值为784,num_outputs
被赋值为10。
然后,代码中的W和b是模型的权重和偏移量。它们都是PyTorch张量,并且都有requires_grad参数被设置为True,表示这些张量需要被追踪,以便在反向传播时计算梯度。W张量是一个形状为(num_inputs, num_outputs)的矩阵,b张量是一个长度为num_outputs的向量。W和b张量的初始值都是随机初始化的,使用均值为0、标准差为0.01的正态分布随机生成的。
定义softmax操作
在实现softmax回归模型之前,我们简要回顾一下sum
运算符如何沿着张量中的特定维度工作。
给定一个矩阵X
,我们可以对所有元素求和(默认情况下)。 也可以只求同一个轴上的元素,即同一列(轴0)或同一行(轴1)。 如果X
是一个形状为(2, 3)
的张量,我们对列进行求和, 则结果将是一个具有形状(3,)
的向量。 当调用sum
运算符时,我们可以指定保持在原始张量的轴数,而不折叠求和的维度。 这将产生一个具有形状(1, 3)
的二维张量。
X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
X.sum(0, keepdim=True), X.sum(1, keepdim=True)
输出
(tensor([[5., 7., 9.]]),tensor([[ 6.],[15.]]))
回想一下,[实现softmax]由三个步骤组成:
- 对每个项求幂(使用
exp
); - 对每一行求和(小批量中每个样本是一行),得到每个样本的规范化常数;
- 将每一行除以其规范化常数,确保结果的和为1。
softmax(X)ij=exp(Xij)∑kexp(Xik)\operatorname{softmax}(\mathbf{X})_{i j}=\frac{\exp \left(\mathbf{X}_{i j}\right)}{\sum_{k} \exp \left(\mathbf{X}_{i k}\right)} softmax(X)ij=∑kexp(Xik)exp(Xij)
def softmax(X):X_exp = torch.exp(X)partition = X_exp.sum(1, keepdim=True)return X_exp / partition # 这里应用了广播机制
正如上述代码,对于任何随机输入,我们将每个元素变成一个非负数。 此外,依据概率原理,每行总和为1。
# 创建随机的均值为0,方差为1,2行5列的矩阵x
X = torch.normal(0, 1, (2, 5))
X_prob = softmax(X)
X_prob, X_prob.sum(1)
在这个代码中,我们定义了一个名为softmax
的函数,这个函数接受一个名为X
的矩阵,并将它转换为概率分布。它通过对矩阵X
中的每个元素求幂,确保所有值都是正数,然后将指数化的值除以它们的和来归一化。这在构建概率分布或用于分类任务的输出(可以解释为概率)时非常有用。
例如,在多类分类的情况下,可以将模型的输出通过softmax
函数传递,以获得类别的概率分布,其中预测的类别是概率最高的类别。
在给定的代码中,对矩阵X
求幂,然后将结果矩阵按其行元素的和(即沿着列)进行除法。sum
方法的keepdim
参数指定结果矩阵应与输入矩阵具有相同的维数,其中沿指定轴的元素的和在结果矩阵中是单个元素。这是为了确保可以逐元素应用除法操作。
最后,将打印出结果矩阵X_prob
和它的行和。由于softmax
函数的输出是概率分布,因此行和应该等于1。
输出
(tensor([[0.0699, 0.0579, 0.0616, 0.1511, 0.6596],[0.0676, 0.1175, 0.4517, 0.2931, 0.0700]]),tensor([1.0000, 1.0000]))
注意,虽然这在数学上看起来是正确的,但我们在代码实现中有点草率。 矩阵中的非常大或非常小的元素可能造成数值上溢或下溢,但我们没有采取措施来防止这点。
定义模型
定义softmax操作后,我们可以实现softmax回归模型。 下面的代码定义了输入如何通过网络映射到输出。 注意,将数据传递到模型之前,我们使用reshape
函数将每张原始图像展平为向量。
def net(X):return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b)
这个代码定义了一个名为net
的函数,该函数接受一个名为X
的张量作为输入,并返回由softmax
函数计算得到的概率分布。
首先,将张量X
的形状重新调整为具有两个维度的形状,其中第一维大小是-1,第二维大小为另一个张量W
的第一维大小。这里的reshape
方法可以用来重新调整张量的形状。其中,使用-1作为第一维的大小意味着这一维的大小将根据输入张量的总元素数和新形状的其他维度的大小自动计算。
接下来,使用矩阵乘法将调整后的张量X
与另一个张量W
相乘,然后将结果与另一个张量b
相加。然后,将结果传递给softmax
函数,并将计算的概率分布作为函数的输出返回。
定义损失函数
接下来,我们实现交叉熵损失函数。 这可能是深度学习中最常见的损失函数,因为目前分类问题的数量远远超过回归问题的数量。
回顾一下,交叉熵采用真实标签的预测概率的负对数似然。 这里我们不使用Python的for循环迭代预测(这往往是低效的), 而是通过一个运算符选择所有元素。
下面,我们创建一个数据样本y_hat
,其中包含2个样本在3个类别的预测概率, 以及它们对应的标签y
。 有了y
,我们知道在第一个样本中,第一类是正确的预测; 而在第二个样本中,第三类是正确的预测。 然后使用y
作为y_hat
中概率的索引, 我们选择第一个样本中第一个类的概率和第二个样本中第三个类的概率。
y = torch.tensor([0, 2])
y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
y_hat[[0, 1], y]
这段代码会输出一个包含两个元素的张量,这两个元素分别对应输入张量y_hat
的第一行第一列和第二行第三列的元素。
首先,我们有两个张量y
和y_hat
。y
是一个包含两个整数的张量,表示两行的索引,而y_hat
是一个2x3的张量,其中每行表示一个概率分布。
然后,我们使用索引操作符**[...]
来访问张量y_hat
**的每行。在这里,第一个索引[0, 1]指定了要选择的行,而第二个索引y指定了要选择的列。这会返回一个包含第一行第一列和第二行第三列元素的张量。
因此,输出为tensor([0.1, 0.5])
。
输出
tensor([0.1000, 0.5000])
现在我们只需一行代码就可以实现交叉熵损失函数。
def cross_entropy(y_hat, y):return - torch.log(y_hat[range(len(y_hat)), y])cross_entropy(y_hat, y)
这个代码定义了一个名为cross_entropy
的函数,该函数计算给定的概率分布和标签的交叉熵。
交叉熵是用于度量两个概率分布之间的差异的常见度量。在分类任务中,通常使用真实标签的概率分布和预测标签的概率分布之间的交叉熵作为损失函数。交叉熵越小,两个概率分布之间的差异就越小,这意味着预测标签的概率分布更接近真实标签的概率分布。
我们对返回的张量求负对数,并将结果作为函数的输出返回。
最后,我们调用函数并传入概率分布和标签的张量作为参数,并打印出结果。输出应该是一个包含两个元素的张量,表示概率分布和标签之间的交叉熵。
输出
tensor([2.3026, 0.6931])
分类精度
给定预测概率分布y_hat
,当我们必须输出硬预测(hard prediction)时, 我们通常选择预测概率最高的类。 许多应用都要求我们做出选择。如Gmail必须将电子邮件分类为“Primary(主要邮件)”、 “Social(社交邮件)”“Updates(更新邮件)”或“Forums(论坛邮件)”。 Gmail做分类时可能在内部估计概率,但最终它必须在类中选择一个。
当预测与标签分类y
一致时,即是正确的。 分类精度即正确预测数量与总预测数量之比。 虽然直接优化精度可能很困难(因为精度的计算不可导), 但精度通常是我们最关心的性能衡量标准,我们在训练分类器时几乎总会关注它。
为了计算精度,我们执行以下操作。 首先,如果y_hat
是矩阵,那么假定第二个维度存储每个类的预测分数。 我们使用argmax
获得每行中最大元素的索引来获得预测类别。 然后我们将预测类别与真实y
元素进行比较。 由于等式运算符“==
”对数据类型很敏感, 因此我们将y_hat
的数据类型转换为与y
的数据类型一致。 结果是一个包含0(错)和1(对)的张量。 最后,我们求和会得到正确预测的数量。
def accuracy(y_hat, y): #@save"""计算预测正确的数量"""if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:y_hat = y_hat.argmax(axis=1)cmp = y_hat.type(y.dtype) == yreturn float(cmp.type(y.dtype).sum())
这个函数用于计算分类任务的准确率。
输入参数:
- y_hat:模型预测的输出。
- y:真实的输出。
输出:
- float:预测正确的数量占总样本数的比例,即准确率。
流程:
- 判断 y_hat 的维度是否大于 1,如果是,将 y_hat 的最后一维按照最大值的索引取值。这是因为,如果 y_hat 为 one-hot 形式的输出,需要将它转换为单个数字编号的形式。
- 比较 y_hat 和 y 相等的数量,并将结果转换为浮点数返回。
我们将继续使用之前定义的变量y_hat
和y
分别作为预测的概率分布和标签。 可以看到,第一个样本的预测类别是2(该行的最大元素为0.6,索引为2),这与实际标签0不一致。 第二个样本的预测类别是2(该行的最大元素为0.5,索引为2),这与实际标签2一致。 因此,这两个样本的分类精度率为0.5。
accuracy(y_hat, y) / len(y)
输出
0.5
同样,对于任意数据迭代器data_iter
可访问的数据集, 我们可以评估在任意模型net
的精度。
def evaluate_accuracy(net, data_iter): #@save"""计算在指定数据集上模型的精度"""if isinstance(net, torch.nn.Module):net.eval() # 将模型设置为评估模式metric = Accumulator(2) # 正确预测数、预测总数with torch.no_grad():for X, y in data_iter:metric.add(accuracy(net(X), y), y.numel())return metric[0] / metric[1]
这段代码定义了一个函数 evaluate_accuracy
,用于计算给定的神经网络在给定的数据迭代器上的精度。
首先,判断给定的神经网络是否是 torch.nn.Module
的实例。如果是,就将其设置为评估模式。
接下来,创建一个累加器 metric
,它有两个元素。然后使用 torch.no_grad()
上下文管理器禁用自动求导。 在这个上下文中,对数据迭代器中的每个输入数据和标签进行循环。每次循环中,调用函数 accuracy 计算输入数据的准确率,并将其添加到累加器 metric 中。最后,计算并返回累加器中正确预测数与预测总数之比。
函数的输入包括神经网络 net 和数据迭代器 data_iter。输出是神经网络在数据迭代器上的精度。
这里定义一个实用程序类Accumulator
,用于对多个变量进行累加。 在上面的evaluate_accuracy
函数中, 我们在Accumulator
实例中创建了2个变量, 分别用于存储正确预测的数量和预测的总数量。 当我们遍历数据集时,两者都将随着时间的推移而累加。
class Accumulator: #@save"""在n个变量上累加"""def __init__(self, n):self.data = [0.0] * ndef add(self, *args):self.data = [a + float(b) for a, b in zip(self.data, args)]def reset(self):self.data = [0.0] * len(self.data)def __getitem__(self, idx):return self.data[idx]
这是一个可以在多个变量上累加的辅助类。
该类包含一个列表,其中存储了当前的累加值。它有三个方法:
- add: 将给定的值分别与列表中对应位置的值相加,并将结果存回列表。
- reset: 将列表中所有值设为 0。
- getitem: 返回列表中指定位置的值。
例如,可以使用这个类来跟踪多个统计信息(如精度、召回率、F1 值)。
由于我们使用随机权重初始化net
模型, 因此该模型的精度应接近于随机猜测。 例如在有10个类别情况下的精度为0.1。
evaluate_accuracy(net, test_iter)
输出
0.1045
训练
在这里,我们重构训练过程的实现以使其可重复使用。 首先,我们定义一个函数来训练一个迭代周期。 请注意,updater
是更新模型参数的常用函数,它接受批量大小作为参数。 它可以是d2l.sgd
函数,也可以是框架的内置优化函数。
def train_epoch_ch3(net, train_iter, loss, updater): #@save"""训练模型一个迭代周期(定义见第3章)"""# 将模型设置为训练模式if isinstance(net, torch.nn.Module):net.train()# 训练损失总和、训练准确度总和、样本数metric = Accumulator(3)for X, y in train_iter:# 计算梯度并更新参数y_hat = net(X)l = loss(y_hat, y)if isinstance(updater, torch.optim.Optimizer):# 使用PyTorch内置的优化器和损失函数updater.zero_grad()l.mean().backward()updater.step()else:# 使用定制的优化器和损失函数l.sum().backward()updater(X.shape[0]) # 表示输入数据的 batch sizemetric.add(float(l.sum()), accuracy(y_hat, y), y.numel())# 返回训练损失和训练精度return metric[0] / metric[2], metric[1] / metric[2]
这段代码定义了一个函数 train_epoch_ch3
,用于训练模型一个迭代周期。
首先,判断给定的神经网络是否是 torch.nn.Module
的实例。如果是,将其设置为训练模式。
然后,创建一个累加器 metric
,它有三个元素。对数据迭代器中的每个输入数据和标签进行循环。每次循环中,使用神经网络对输入数据进行预测,并计算预测值与标签之间的损失。
然后,判断给定的优化器是否是 PyTorch 内置的优化器。如果是,就使用 PyTorch 内置的优化器来更新神经网络的参数。否则,使用定制的优化器来更新参数。
最后,将计算的损失值、准确率和样本数加到累加器 metric
中。
函数的输入包括神经网络 net
、数据迭代器 train_iter
、损失函数 loss
和优化器 updater
。输出是训练损失和训练准确率。
在展示训练函数的实现之前,我们定义一个在动画中绘制数据的实用程序类Animator, 它能够简化本书其余部分的代码。
class Animator: #@save"""在动画中绘制数据"""def __init__(self, xlabel=None, ylabel=None, legend=None, xlim=None,ylim=None, xscale='linear', yscale='linear',fmts=('-', 'm--', 'g-.', 'r:'), nrows=1, ncols=1,figsize=(3.5, 2.5)):# 增量地绘制多条线if legend is None:legend = []d2l.use_svg_display()self.fig, self.axes = d2l.plt.subplots(nrows, ncols, figsize=figsize)if nrows * ncols == 1:self.axes = [self.axes, ]# 使用lambda函数捕获参数self.config_axes = lambda: d2l.set_axes(self.axes[0], xlabel, ylabel, xlim, ylim, xscale, yscale, legend)self.X, self.Y, self.fmts = None, None, fmtsdef add(self, x, y):# 向图表中添加多个数据点if not hasattr(y, "__len__"):y = [y]n = len(y)if not hasattr(x, "__len__"):x = [x] * nif not self.X:self.X = [[] for _ in range(n)]if not self.Y:self.Y = [[] for _ in range(n)]for i, (a, b) in enumerate(zip(x, y)):if a is not None and b is not None:self.X[i].append(a)self.Y[i].append(b)self.axes[0].cla()for x, y, fmt in zip(self.X, self.Y, self.fmts):self.axes[0].plot(x, y, fmt)self.config_axes()display.display(self.fig)display.clear_output(wait=True)
接下来我们实现一个训练函数, 它会在train_iter
访问到的训练数据集上训练一个模型net
。 该训练函数将会运行多个迭代周期(由num_epochs
指定)。 在每个迭代周期结束时,利用test_iter
访问到的测试数据集对模型进行评估。 我们将利用Animator
类来可视化训练进度。
def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater): #@save"""训练模型(定义见第3章)"""animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],legend=['train loss', 'train acc', 'test acc'])for epoch in range(num_epochs):train_metrics = train_epoch_ch3(net, train_iter, loss, updater)test_acc = evaluate_accuracy(net, test_iter)animator.add(epoch + 1, train_metrics + (test_acc,))train_loss, train_acc = train_metricsassert train_loss < 0.5, train_lossassert train_acc <= 1 and train_acc > 0.7, train_accassert test_acc <= 1 and test_acc > 0.7, test_acc
这段代码定义了一个函数 train_ch3
,用于训练模型。输入参数包括神经网络 net
、训练数据迭代器 train_iter
、测试数据迭代器 test_iter
、损失函数 loss
、迭代周期数 num_epochs
和优化器 updater
。
首先,创建一个 Animator
对象 animator
。这个对象用于在训练过程中实时绘制训练损失和训练准确率以及测试准确率的图像。
然后,使用循环迭代 num_epochs
次,每次调用函数 train_epoch_ch3
训练一个迭代周期,并计算测试准确率。每次迭代完成后,将训练损失和训练准确率以及测试准确率的值传递给 Animator
对象的 add
方法,以便在图像中添加数据。
最后,函数 train_ch3
使用三个 assert
语句检查训练损失、训练准确率和测试准确率是否满足预期的要求。这些要求是:训练损失小于 0.5,训练准确率大于 0.7 且小于等于 1,测试准确率大于 0.7 且小于等于 1。如果这些要求满足,则函数会正常结束。如果有任意一个要求不满足,则会抛出 AssertionError
异常,并输出不符合要求的指标的值。
作为一个从零开始的实现,我们使用小批量随机梯度下降来优化模型的损失函数,设置学习率为0.1。
lr = 0.1def updater(batch_size):return d2l.sgd([W, b], lr, batch_size)
现在,我们训练模型10个迭代周期。 请注意,迭代周期(num_epochs
)和学习率(lr
)都是可调节的超参数。 通过更改它们的值,我们可以提高模型的分类精度。
num_epochs = 10
train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r5dE4cWV-1673764739925)(image/image_9_wplYYaxo.png)]
预测
现在训练已经完成,我们的模型已经准备好对图像进行分类预测。 给定一系列图像,我们将比较它们的实际标签(文本输出的第一行)和模型预测(文本输出的第二行)。
def predict_ch3(net, test_iter, n=6): #@save"""预测标签(定义见第3章)"""for X, y in test_iter:breaktrues = d2l.get_fashion_mnist_labels(y)preds = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1))titles = [true +'\n' + pred for true, pred in zip(trues, preds)]d2l.show_images(X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n])predict_ch3(net, test_iter)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VMv5pdEB-1673764739925)(image/image_el_KNzg1fl.png)]
softmax回归的简洁实现
线性回归变得更加容易。 同样,通过深度学习框架的高级API也能更方便地实现softmax回归模型。 本节如在 3.6节中一样, 继续使用Fashion-MNIST数据集,并保持批量大小为256。
from mxnet import gluon, init, npx
from mxnet.gluon import nn
from d2l import mxnet as d2lnpx.set_np()batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
初始化模型参数
softmax回归的输出层是一个全连接层。 因此,为了实现我们的模型, 我们只需在Sequential
中添加一个带有10个输出的全连接层。 同样,在这里Sequential
并不是必要的, 但它是实现深度模型的基础。 我们仍然以均值0和标准差0.01随机初始化权重。
# PyTorch不会隐式地调整输入的形状。因此,
# 我们在线性层前定义了展平层(flatten),来调整网络输入的形状
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)net.apply(init_weights);
这段代码中,首先定义了一个神经网络 net
。这个神经网络是一个序列(Sequential
),包含两个层:展平层(Flatten
)和线性层(Linear
)。
展平层用于将输入数据的形状从(batch_size, channel, height, width
)转换为(batch_size, channel_height_width
)。这样,线性层才能接受这些输入数据。
接下来定义了一个函数 init_weights
,用于初始化模型参数。函数 init_weights
使用 PyTorch 的内置函数 nn.init.normal_
将线性层的权重初始化为正态分布的随机数。
最后,使用 net
的 apply
方法,将函数 init_weights
应用到每一层的参数上。这样, **net
**的每一层的参数都会被初始化。
重新审视Softmax的实现
loss = nn.CrossEntropyLoss(reduction='none')
优化算法
在这里,我们使用学习率为0.1的小批量随机梯度下降作为优化算法。 这与我们在线性回归例子中的相同,这说明了优化器的普适性
trainer = torch.optim.SGD(net.parameters(), lr=0.1)
训练
num_epochs = 10
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
和以前一样,这个算法使结果收敛到一个相当高的精度,而且这次的代码比之前更精简了。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4498040.html
如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!
钉钉ppt放映显示备注_PPT的备注怎么用,放映PPT时如何显示备注 来看看吧
在使用PPT进行演讲的过程中,如何防止自己忘记演讲的主题和内容呢?在PPT的备注中注明我们演讲主题和内容的关键词是一个很好的解决方法。那么PPT的备注怎么用呢?操作方法01在使用PPT进行演讲的过程中,怕演讲时忘记一些晦涩的知识或…...

2019UNCTF-RE-very_easy_re
2019UNCTF-RE-very_easy_revery_easy_re题目解析开始1.题目2.查壳3.IDA静态分析4.上脚本5.get flag结语每天一题,只能多不能少very_easy_re 题目解析 的确是very easy,不过不是对我。base64再加简单的转换。 开始 1.题目 给出一个exe程序。 2.查壳…...

一些常用的 Emoji 符号(可直接复制)
表情类 😀 😁 😂 🤣 😃 😄 😅 😆 😉 😊 😋 😎 😍 😘 😗 😙 😚 ☺️ &#…...

自动驾驶感知算法实战11——多传感器融合感知方案详解
自动驾驶感知算法实战专栏:https://blog.csdn.net/charmve/category_12097938.html目录 1 何为多传感器融合?2 多传感器融合的优势3. 多传感器融合的先决条件3.1 统一时钟3.2 统一坐标系4. 多传感器融合算法分类4.1 后端融合算法4.2 前端融合算法5. 总结在自动驾驶的感知领域…...

php pdo mysql 超时_为 PDO 增加读写超时
定义枚举类型首先,我们先要创建枚举类型,也就是未来在 PHP 代码中,setAttribute 传入的 KEY原生的这个 key 值都定义在 Zend/ext/pdo/php_pdo_driver.h 中:enum pdo_attribute_type {PDO_ATTR_AUTOCOMMIT,/* use to turn on or of…...

Elasticsearch监控cerebro部署
# 下载地址 https://github.com/lmenezes/cerebro https://github.com/lmenezes/cerebro/releases # 解压 tar xzf cerebro-0.8.5.tgz # 启动 cerebro-0.8.5/bin/cerebro # 后台启动 nohup ./cerebro > cerebro.log & # 配置ES服务器 hosts [#{# host "h…...

mysql pdo 端口_pdo连接mysql
header(Content-Type:text/html;charsetutf-8);//配置数据库连接信息$dbms mysql; //数据库类型$host localhost; //数据库主机名$port 3306; //端口号$dbname itcast; //数据库名$charset utf8; //字符集$user root; //用户名$password 123456; //密码2、使用PDO连接数…...

李沐论文精读笔记( ResNet、Transformer、GAN、BERT)
文章目录一、 ResNet1.0 摘要,论文导读1.1 导论1.1.1 为什么提出残差结构?1.1.2 实验验证1.2 相关工作1.3 实验部分1.3.1 不同配置的ResNet结构1.3.2 残差结构效果对比1.3.3 残差结构中,输入输出维度不一致如何处理1.3.4 深层ResNet引入瓶颈结…...

【JS】正则表达式——允许中间有空格的标题
【JS】正则表达式——允许中间有空格的标题 具体要求: 只允许输入中文、大小写英文、数字、横线和下划线,首尾不能有空格,中间可以有单个的空格作为分割符,但不可以有连续的空格 长度:至少有1个字符 解析:…...

Power bi 超市经典案例之退货分析(二)
关注微信公共号:小程在线 关注CSDN博客:程志伟的博客 数据集链接见微信公共号底端 1. 单击“可视化”窗格中的“堆积柱形图”图标, 在画布区域会出现堆积柱形图的模板, 由于没有填入数据, 因此堆积柱形图是灰色的。 2…...

Linux上使用telnet连接本机IP地址端口
场景 Linux开启了iptables!!! 开启本机TCP80端口服务。Linux本机IP地址是192.168.204.129。本机telnet连接本机的TCP80端口。 目的 telnet 192.168.204.129 80,能够连接通。 输入规则 1)需要配置一个让本机TCP80端…...

【kubernetes系列学习】如何使pod和host主机的时间保持一致?
文章目录【kubernetes系列学习】如何使pod和host主机的时间保持一致?问题及主要目的实验环境信息实验1:正常创建pod,pod和host的时间不一致实验2:挂载主机的/usr/share/zoneinfo/Asia/Shanghai实验3:挂载主机的/etc/lo…...

CDH大数据平台 31Cloudera Manager Console之impala hive负载均衡(markdown新版)
💖个人主页:@与自己作战 💯作者简介:CSDN@博客专家、CSDN@大数据领域优质创作者、CSDN@内容合伙人、阿里云@专家博主 🆘希望大佬们多多支持,携手共进 📝 如果文章对你有帮助的话,欢迎评论💬点赞👍收藏📂加关注 ⛔如需要支持请私信我,💯必支持 文章目录 一…...

PDO的介绍及使用
本文目录一、PDO介绍1.1 链接数据库方式1.2 PDO介绍1.2.1 开启PDO扩展1.3 PDO核心类1.4 实例化PDO对象1.4.1 DSN1.4.2 实例化PDO1.4.3 注意事项二、使用PDO2.1 执行数据操作语句2.1.1、增加2.1.2、改2.1.3、删2.1.4、查:2.1.4.1、返回二维数组1、返回关联和索引数组…...

ERROR: invalid byte sequence for encoding UTF8: 0x00
1、使用kettle批量导入数据的时候,数据出现了下面的错误。ERROR: invalid byte sequence for encoding "UTF8": 0x00 关键点:“0x00”意思是:十进制数字0。 所以,解决方法就是将这个出现这个内容的字段进行修改即可&a…...

阻塞车间调度
阻塞车间调度 当前机器上的作业处理必须保留在该机器上,直到下一台机器可用于处理为止。也就是说如果该作业要执行的下一个工序的机器被使用,则该机器必须被占用。 n个作业必须在m个机器f个工厂上进行处理,在每一个工厂中连续机器之间没有缓…...

1-14 字符串、相等性规则、值传递与引用传递
1 相等性规则 比较运算符 比较基本数据类型,判断的是值是否相等(基本数据类型只能用“”比较)比较引用类型,判断的是内存地址是否相等 equals()方法 Object类的equals()方法,比较的内存地址是否想等;Stri…...

signature=b061631e3496594bd0b88f0cbaad0d58,bcrypt
3.2.0 release-----BEGIN PGP SIGNATURE-----iQFMBAABCAA2FiEEBf2foWz3VzUNkaVgI1rl8Sn57ZgFAl85a10YHHBhdWwubC5rZWhyZXJAZ21haWwuY29tAAoJECNa5fEpe2YbhUH/1TZ2eRMHzvRQejOWSjpo9MXBh/dzHNH2TTB5DkQM/LOPp70UNVKEpX7m1z4Ab0wykQ9eBAOMZ7tRxd8rZ4mMHzgAnbBOtSqUy3gUUdYESykJc...

【Spring】——9、如何指定初始化和销毁的方法?
📫作者简介:zhz小白 公众号:小白的Java进阶之路 专业技能: 1、Java基础,并精通多线程的开发,熟悉JVM原理 2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线…...

pdo_mysql扩展库_MySQL数据库之PDO扩展
PDO概述连接数据库方式mysql扩展 (这种方式php7已经淘汰)mysqli扩展PDO扩展PDO介绍PDO(PHP Data Object)扩展为PHP访问各种数据库提供了一个轻量级,一致性的接口无论访问什么数据库,都可以通过一致性的接口去操作开启PDO扩展开启PDO连接MySQL扩展extensi…...

RHEL/CentOS修改hostname
1、CentOS6/RHEL6 对于6系的红帽Linux,修改hostname较为麻烦,如果只是需要临时修改hostname,只需要使用hostname命令即可: hostname your-new-temp-hostname如果需要永久修改hostname,则需要修改两个地方:…...

springboot 实现多数据源的底层原理
目录 1 spring操作数据库的流程2 自定义DataSource对象3 AbstractRoutingDataSource4 使用aop和注解的形式配置多数据源1 spring操作数据库的流程 我们一般是在项目里面配置mybatis框架,在yml里面配置数据库的链接信息,然后写mapper层进行操作数据库 我们都知道,mybatis框…...

各种ajax写法默写默写默写readyState的状态码,axios,fetch,promise,ayse await
原生 <script>//创建异步对象const xhrnew XMLHttpRequest()//设置url和发送方式xhr.open(GET,"https://api-hmugo-web.itheima.net/api/public/v1/goods/search")//发送请求xhr.send()xhr.onreadystatechange function () {if (xhr.readyState4 &&x…...

【SpringCloud】03 nacos集群模式
nacos集群模式 如果nacos单机出现故障,导致所有微服务服务注册和拉取相应的服务信息。从而导致整个项目无法使用。 注意: nacos1.3以后才允许集群的搭建。必须停止你虚拟机的网卡 条件: 8849 8850 8851 这三台nacos集群。 (1)指定mysql存储源…...

22.10.16 LC周赛 第2至4题
22.10.16 LC周赛 第2至4题 这次周赛终于做出3道题,可惜比我强的太多了!不说废话了,好好总结一下,继续保持学习,今天的每日一题挺有意思,一会去好好看一下! 6205. 反转之后不同整数的数目&am…...

windows搭建Qt与VTK
最后更新时间:2022.10.16 参考内容:开源地址 工具 VS2022Qt 6.4CMake 3.24.2VTK9.2.2源码 编译VTK 下载源码解压;在源码中创建一个build文件夹用于源外构建通过菜单栏中的x64 Native Tools Command Prompt for VS 2022打开CMake GUI&#…...

C++正则表达式
C正则表达式 表达式: 一般字符:可匹配目标序列中相同的字符通配符 . :可匹配目标序列中除了换行符外的任何字符[expr]形式表达式: 可以匹配目标序列中包含在表达式expr定义集内的字符或者排序规则表达式,采用 [^**expr…...

接口自动化测试工具- postman-基础篇 发送http get Request
1. 最简单的示例 新建请求填写请求方式:Get天下请求URL:https://www.baidu.com 1.1. click New去新建请求 1.2. 选择http Request 1.3 发送请求 2. 带参数的示例 2.1 新建请求 2.2 填写请求方式:Get 2.3 填写请求URL:https://ht…...

【微信小程序】列表渲染
✅作者简介:CSDN内容合伙人、阿里云专家博主、51CTO专家博主🏆 📃个人主页:hacker707的csdn博客 🔥系列专栏:微信小程序🥇 💬个人格言:不断的翻越一座又一座的高山&#…...

SQL入门学习
1.SQL service 系统概述 SQL service 是一个可扩展的、高性能的、为分布式客户机 / 服务器计算所设计的数据库管理系统 数据库系统组成 数据库用户软件系统硬件系统 #mermaid-svg-D4YJ2yZcngquU7nH {font-family:"trebuchet ms",verdana,arial,sans-serif;font-si…...

空格的正则表达式
在正则表达式想使用空格的时候不能采用\s的方法,因为\s指的是空白,就是所有空白。 如果想表示单纯的空格的话可以采用:[ ] 方括号本身就是匹配其中的字符,那么其中放空格就是匹配空格; 如果有其他正则表达式问题可以查看&#…...

python正则表达式空格_python中的正则表达式的使用
一、正则表达式简介正则表达式:又称正规表示式、正规表示法、正规表达式、规则表示式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或者是RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列某个句法规则的…...

IPv4概述
1 IPv4分组 1.1 IPv4分组的格式 1.2 IP数据报分片 1.3 网络层转发分组的流程 2 IPv4地址与NAT 2.1 IPv4地址 五类IP地址: 在各类IP地址中,有些IP地址有特殊用途,不用做主机的IP地址。 主机号全是0表示本网络本身 A类:1.0.…...

pdo操作oracle,PDO基础操作
创建PDO对象使用PDO在与不同数据库管理系统之间交互时,PDO对象中的成员方法是统一各种数据库的访问接口,所以在使用PDO与数据库进行交互之前,首先要创建一个PDO对象。在通过构造方法创建对象的同时,需要建立一个与数据库服务器的连…...

Qt正则表达式
正则表达式 正则表达式即一个文本匹配字符串的一种模式,Qt中QRegExp类实现使用正则表达式进行模式匹配,且完全支持Unicode,主要应用:字符串验证、搜索、查找替换、分割。 正则表达式中字符及字符集 正则表达式中的量词 正则表…...

java基础内存分配介绍
java内存分配介绍栈堆方法区本地方法栈寄存器 方法区:字节码文件加载时进入的内存。 栈内存:方法运行时所进入的内存,变量也在这里。 堆内存:new出来的东西在这块内存中开辟空间并且产生地址。 数组使用常见问题;如果访问的元素位置超过最大索引,执行时会出现数组索引越…...

PDO是什么?
PDO一是PHP数据对象(PHP Data Object)的缩写。它被描述为“在PHP中访问数据库的轻量级,兼容性的接口” PDO的好处: 免于SQL注入攻击。通用,可以连接多种类型的数据库。 POD连接数据库 $dsn mysql:dbnameblog;host…...

【CNN】MobileNet——卷积神经网络中轻量级的经典
前言 MobileNet 系列 是 Andrew G. Howard(Google Inc.) 等人于 2017 年(其实是 2016 年先于 Xception 已经提出,但是直到 2017 年才挂到 arXiv 上)在 MobileNets: Efficient Convolutional Neural Networks for Mobi…...

虚拟局域网技术 (VLAN技术、tag帧、交换机端口的VLAN属性、以太网交换机的转发流程)
虚拟局域网技术 (VLAN技术) 将一个大型的局域网人为地划分成多个孤立的局域网。 一个VLAN就是一个广播域,划分VLAN就是把一个广播域划分为多个广播域。 将划分的各个VLAN互联需要路由器。 划分虚拟局域网的作用 限制广播,提高带…...

vue组件孙子调用爷爷的方法
1、在爷爷组件中设置provide(){ return{ saveFun:this.saveFun } }, saveFun我自己的方法 provide和methods同级 2、直接在孙子组件中设置inject:[saveFun], inject data同级 剩下的就是直接调用saveFun这个方法了...

认识并安装WSL
认识并安装WSL(基于Windows的Linux子系统) 什么是WSL WSL(Windows Subsystem for Linux),这是在windows平台运行的linux子系统。也就是说可是不用安装虚拟机的情况下获得相对完整的linux系统体验。 WSL相比于虚拟机(eg:VMware、Virtualbox) 优点:轻量化,最大程度减少…...

Spring Boot Admin2 AdminServerAutoConfiguration详解
其他相关文章: Spring Boot Admin 参考指南SpringBoot Admin服务离线、不显示健康信息的问题Spring Boot Admin2 EnableAdminServer的加载 前面已经分析了EnableAdminServer的作用,唯一的功能是将AdminServerMarkerConfiguration.Marker类加载到Spring中…...

oracle19c切换PDB服务器
之前在linux上进行了Oracle19c的安装以及数据库初始化,那个教程中初始化的是CDB数据库,我们平时使用的是PDB,所以要进行切换。关于PDB和CDB也是有区别的,Oracle 12c 开始有了CDB和PDB CDB与PDB是Oracle 12C引入的新特性࿰…...
pdo Mysql
1、什么是PDO? PDO是PHP data Object 提供了PHP操作多种数据库的统一的借口。2、为什么要使用PDO? 更换其他数据库的时候无需更换代码,提高了程序运行效率 3、PDO的特点是什么? (1)、编码的一致性 (2)、灵活性 (3)、面向对象…...

2646-61-9, 脯氨酰内肽酶(PEP)底物: Z-GPLGP-OH
编号: 160473中文名称: 脯氨酰内肽酶(PEP)底物:Z-Gly-Pro-Leu-Gly-ProCAS号: 2646-61-9单字母: Z-GPLGP-OH三字母: Cbz-Gly-Pro-Leu-Gly-Pro-COOH氨基酸个数: 5分子式: C28H39O8N5平均分子量: 573.64精确分子量: 573.28等电点(PI): -pH7.0时的…...

pdo连接mysql_php PDO连接mysql
如今你已经通过PDO建立了连接。在部署查询之前你必须搞明确PDO是如何管理事务的。假设你曾经从未遇到过事务处理,(如今简介一下:)它们提供了4个基本的特性:原子性,一致性,独立性和持久性(Atomicity, Consistency, Isol…...
php pdo drivers no supported,pdo_snowflake
PHP PDO driver for SnowflakePrivate Preview. Linux Only. No PHP 5 support. PHP 7 only.Configuring EnvironmentPHP Versions and ExtensionsPHP 7.0 is supported. The following extensions are required:pdojsonApplication Server (Optional)If the PHP is used alon...

mysql pdo教程_(唯一合适) PDO 教程
PDO是什么首先思考, 为什么选择PDOPDO 是一个数据访问抽象层(Database Access Abstraction Layer). 抽象是双重的: 一个是众所周知但不太重要的. 另一个是模糊的但是是最重要的.众所周知 PDO 为不同的数据库提供了统一的接口. 虽然这个功能本身很庞大, 但是对于固定程序来说不是…...

php pdo 遍历,PHP PDO操作总结
0x01:测试PDO是否安装成功运行如下代码,如果提示参数错误,说明PDO已经安装,如果说明对象不存在,则修改PHP配置文件php.ini,取消php_pdo_yourssqlserverhere.extis前面的注释。$testnew PDO();0x02ÿ…...

SpringBoot+Vue高校学生评教系统java教学质量评估系统
高校学生评教系统主要包括三大功能模块,即用户功能模块和管理员功能模块、教师用户模块。 (1)管理员模块:系统中的核心用户是管理员,管理员登录后,通过管理员来管理后台系统。主要功能有:首页、…...

基于JAVA的个人博客论坛系统的设计与实现参考【数据库设计、源码、开题报告】
在学校开发搭建一个什么项目最有成就感,那肯定就是搭建「个人博客」呀,然后把自己平时的学习笔记写到博客里,这时你的笔记就是**云笔记**,就再也不会出现因为本地文件丢失而感到痛心的事情。 而且,还可以把你的个人博客…...
PDO简介及其基本使用
一、基本知识1、什么是PDO?PDO就是PHP data Object 提供了PHP操作多种数据库的统一的接口2、为什么要使用PDO?PDO是PHP5新加入的一个重大功能,我们的数据库服务器为MySQL,所有的程序代码的数据库操作全是一mysql()或者…...

mysql pdo_数据库PDO简介
php简介,php历史,php后端工程师职业前景,php技术方向,php后端工程师职业体系介绍。php是世界上使用最广泛的web开发语言,是超文本预处理器,是一种通用的开源脚本语言,语法吸收了c语言࿰…...

Linux 学习总结(84)—— 回顾下正则表达式
什么是正则表达式 正则表达式就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。简单的一个例子:用字符串 ”a” 来验证字符串 s 是否是 ”a”,形如 s.match(“a”)。概括来说有以下作用: 验证字符串是否符合指定特征,比如验证是否是合法…...

类与对象
K.类的应用11 Time Limit: 1000 MSMemory Limit: 32768 KTotal Submit: 91 (73 users)Total Accepted: 74 (73 users)Special Judge: NoDescription给定多个立方体的长、宽、高数据,计算并按照表面积由小到大的顺序依次输出每个立方体的长、宽、高数据及其表面积和体…...

初探WebSocket
初探WebSocket 文章目录初探WebSocket什么是WebSocketWebSocket的特点WebSocket的优点WebSocket 的握手请求与响应报文Sec-WebSocket-Key/Accept的作用双端交互流程数据收发流程保持连接和关闭连接🌰WebSocketWebSocket APIdemo跨平台的WebSocket通信库socket.io长轮…...
前端flex布局
Flex布局又称弹性布局,在小程序开发中比较适用。因此将Flex布局相关属性整理如下,搞清楚了这个布局,小程序开发的页面布局就不在话下了。 布局的传统解决方案,基于盒状模型,依赖 display属性 position属性 float属性…...

SpringMVC 7 统一结果封装 7.2 表现层与前端数据传输协议实现
SpringMVC 【黑马程序员2022新版SSM框架教程_SpringSpringMVCMaven高级SpringBootMyBatisPlus企业实用开发技术】 7 统一结果封装 文章目录SpringMVC7 统一结果封装7.2 表现层与前端数据传输协议实现7.2.1 环境准备7.2.2 结果封装7.2 表现层与前端数据传输协议实现 7.2.1 环…...

Java的JSTL
一JSTL概述L JSTL是Java中的一个定制标记库集。JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。…...

Unity 导入原神人物模型
原神人物模型官方下载地址: 一、https://ys.biligame.com/gczj/ 二、http://ys.biligame.com/pjdkx/ 三、https://ys.biligame.com/beyel 四、 https://ys.biligame.com/ysl 五、https://www.bilibili.com/blackboard/activity-raop07Ymhm.html 六、https://www.bi…...

魔兽世界服务器维护掉线,《魔兽世界怀旧服》老是掉线怎么办 老是掉线解决办法...
导读最近,自从开放黑翼之巢bwl以来,相信很多玩家都有非常感同身受的一点,就是:这是什么垃圾服务器?怎么排队的人这么多?怎么排队这么慢?服务器怎么这么卡?怎么我老是掉线?小编也不例外,这段时间,这些问…...

技术分享 | OceanBase 4.X 最小化单机部署
作者:杨涛涛 资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课…...

全电子计算机联锁厂家,全电子计算机联锁工程设计
全电子计算机联锁工程设计介绍全电子计算机联锁工程设(本文共3页)阅读全文>>本系统是针对全电子计算机联锁系统工程设计而研制开发的计算机辅助设计(CAD)软件。系统将在国内外普遍采用的AutoCAD...(本文共3页)阅读全文>>通过介绍全电子执行模块中的道岔模块、轨道电…...

利用深度学习框架实现点云配准(以PointNetLK项目为例)
1.前言 之前已经介绍过了基于BnB算法的点云配准应用。熟悉点云配准近年来发展趋势的同学应该知道,目前CVPR,ICCV这些会议,比较主流的方法还是基于深度学习来建立点云的对应关系,尤其以基于PointNet变种网络的方法居多。所以如果要…...
如何辨别梭织、针织和无纺面料?
如何辨别梭织、针织和无纺面料? 梭织面料 两系统(或方向)的纱线互相垂直,并按一定的规律交织而形成的织物为梭织物(也称机织物)。 梭织与针织的原理区别 基本组织是各类组织中最简单、最基本的组织&…...

学习OpenFOAM Tutorial snappyHexMesh
OpenFOAM v8 SnappyHexMesh一、SnappyHexMesh是什么?二、使用SnappyHexMesh生成网格1.snappyHexMesh的网格生成过程2.使用SnappyHexMesh创建的网格设置和运行稳态瞬态案例总结一、SnappyHexMesh是什么? snappyHexMesh,从曲面几何图形、tri-s…...
5分钟搞定100%正确的产品工艺单
5分钟搞定100%正确的产品工艺单 产品工艺单: 所需要的工具: 剪刀、打火机、分析针、尺子、水笔。 检测步骤: 正反面鉴别经纬向鉴别测经纬纱的密度织物组织分析原料的鉴别织造缩率(根据具体情况而定)经纬纱规格的分析…...

jsp是什么药_JSP中主要包含哪几种指令标识?它们的作用及语法格式是什么?
【填空题】玩具雨伞【填空题】纯涤纶变形长丝制机织印花布【填空题】纯羊毛纤维制手工结织栽绒地毯(块状)【填空题】色织机织物,按重量及含有棉50%,醋酸纤维长丝25%,涤纶长丝25%,幅宽110厘米【填空题】黏胶单丝(截面直径为1.2毫米,细度为90分特)【填空题】蓝色涤纶针织布(纬编,…...
定型车间秘籍宝典
印染厂定型车间秘籍宝典,能懂这些,走遍天下无敌手! 定型的定义:定型是后整理的主要工序。针织物通过定型机的机械作用以及化学试剂的防缩、增软、增硬等作用,使织物达到一定的缩水、密度、手感,并能达到门…...
针织面料大全
针织面料大全 利用织针,将一根或多根由纬向喂入的纱线依次弯曲成一系列的线圈,再将此次生成的新线圈与前次生成的旧线圈相互串套,就构成了针织织物。成圈(K)、集圈(T)、浮线(W)。 1. 基本面料 汗布(Jersey)、单珠地&…...

Html百分比设宽偏差大,近几年东华大学_纺织材料学_试题及_答案
近几年东华大学纺织材料学试题及答案2001年一、名词解释(30分)1、织物的舒适性织物服用性能之一,是指人们在穿着时的感觉性能。狭义的舒适性是指在环境-服装-人体系列中,通过服装织物的热湿传递作用,经常维持人体舒适满意的热湿传递性能。隔热…...

帘子布检验新项目
帘子布检验新项目 缺陷检验,第三方检测,附胶量检验,单线疲惫检验,剪切强度检验,抗拉强度检验,拉断抗压强度检验,固层黏合抗压强度检验,抗张强度检验,硬度检验࿰…...

win32com操作word 第二集:ApplicationDocuments接口
本课程《win32com操作word API精讲&项目实战》以视频为主,文字教程为辅,公众号:一灯编程 先回答一个网友私信问题: win32com和微软的word接口文档有什么关系 win32com的底层调用的是word的接口,理论上,想查看win32…...

针织毛衫的概念及设计
从20世纪70年代开始针织服装在整个世界范围内日益受到了人们的青睐,世界服装领域呈现出向针织服装发展的趋势。近十年来,随着国内外市场对针织服装需求的不断扩大,我国针织服装行业得到了迅猛发展。在加工方面甚至超过了国外,但与…...
常见针织面料
常见针织面料 针织面料即是利用织针将纱线弯曲成圈并相互串套而形成的织物。针织面料分为纬编面料(weft knitted fabric)和经编面料(warp knitted fabric)。 纬编针织布基本结构 经编针织布基本结构 纬编针织物首先它是横向(Widthwise)织出来的,而且是由一条纱线连…...

面料经纬向、正反面判别方法
面料经纬向、正反面判别方法 面料经纬向判别方法 如被鉴别的面料是有布边的,则与布边平行的纱线方向便是经向,另一方是纬向。上浆的是经纱的方向,不上浆的是纬纱的方向。一般织品密度大的一主是经向,密度小的一方是纬向。筘痕明…...

科学家通过碳纳米管研发神奇“纱线” 可为物联网传感器提供方便电能
日前,《科学》杂志刊文介绍了一种名为“Twistron”的神奇“纱线”,只要拉伸或扭转就能实现自发电。这一新材料有望在物联网传感器、可穿戴医疗设备、海水发电等领域广泛应用,并帮助人类减少对化石能源的依赖。 美国得克萨斯大学达拉斯校区、韩…...

UWB定位技术在高铁装备制造业的应用
随着《新时代交通强国铁路先行规划纲要》的提出,“铁路强国”,既是改善人们出行的重要举措,也是实现铁路事业高质量发展的要求。因此,高铁装备制造利用新技术实现数字化智能升级,也是工业4.0时代下的产业必由之路。EHI…...

骑摩托车出行防水防雾小技巧
新交规实施以后,机车出行的时候,头盔已经成了不得不佩戴的装备。 头盔从之前的可有可无,变成了现在的必不可少,相信大家也和我一样戴上头盔以后会感到很不习惯,特别是视野问题,视野再也没有不戴头盔那样开…...

双十一运动装备推荐指南,健身爱好者必备装备分享
作为一名资深的健身运动爱好者,我这次对常用的运动装备仔细了解了一遍,发现这次双十一确实优惠力度是比较大的,所以我也打算趁着这次双十一多入手一些运动装备,下面我就从实用角度聊一聊这些好用的健身装备,看看有没有…...

python基于PHP旅游网站的设计与开发
在经济高速发展的现在,人们的工作越来越繁重,生活节奏越来越快,生活工作压力也越来越大。反而留给自己休息,享受旅游生活的时间越来越少,缺少对周边旅游信息的了解,无法与兴趣一致的户外旅友进行交流。这则会导致人们会花更多的时间去寻找旅游地点,并进行路线规划,花费的时间在…...

锐界机器人_“小”温柔“大”智慧 锐界领移动智能出行
不论是最近刷爆朋友圈,引发无数“自来水”热潮的男神孙大圣,还是《超能陆战队》里温柔呆萌的机器人大白,都以自己的全能表现,征服了冒险旅途中的所有艰险“他们”更以独特的“温柔”对待着身边的人。在出行时,你是否也…...

运动需要用到哪些东西,双十一好用的运动装备分享
如今全民运动已经成为势不可挡的趋势了,越来越多人开始关注并投入到运动事业中来。同时,我们在选择运动装备时必须要考虑的就是装备便携性的问题。如果没有选择正确的运动装备,很有可能使我们的运动适得其反,在增加自身负担的同时…...

户外装备配备表
个人穿着用品: 一、服装篇 1、冲锋衣裤(户外活动必备,防风、防水、透气、耐磨……); 2、抓绒衣(含WINDSTOPPER,主要是防风、保暖); 3、排汗内衣(户外运动后保持身体干燥);…...

五一出行必备好搭档、适合户外运动使用的运动耳机
五一小长假来袭,户外运动健身装备你准备好了吗?对于爱好运动的人来说,那么在运动的时候有一副好的耳机播放律动的音乐,才能使运动更有仪式感,才会更有动力,不然肯定觉得运动很乏味,也根本坚持不…...

户外运动基本装备大全
户外运动基本装备大全个人穿着用品: 一、服装篇 1、冲锋衣裤(户外活动必备,防风、防水、透气、耐磨……); 2、抓绒衣(含WINDSTOPPER,主要是防风、保暖);3、排汗内衣(户外运动后保持身体干燥); 4、快…...

跑步装备推荐,双十一跑步运动装备分享
跑步作为最简单易行的运动,备受大家的喜爱。在享受社交健身的同时,跑遍街头巷尾,发现无限的未知和惊喜,作为一个跑者,在进行运动的时候想要跑得久,跑得舒服,都不应该忽略我们最重要的东西——跑…...

夏日出行好伴侣,华为FreeBuds 4堪称清凉好装备
这个端午假期,不知道大家过得怎么样?虽说现在户外温度居高不下,但我依旧我按计划去上海找朋友玩了一圈。毕竟我有“舒适降噪恰如其妙”的华为FreeBuds 4无线耳机,既然“逃”出了家和公司的两点一线,又能在炎炎夏日感受到其清凉感受,作为测评博主的我准备看看旅行环境下,它的表…...

八种必备户外装备包你踏遍地球
作为驴友,我们喜欢靠自己的双脚去踏遍祖国的万里河山,喜欢用自己的双眼去搜寻遗留在城市各个角落的美好事物,喜欢用心灵去感受大自然带给我们的生命力。总结一下驴友们出行都有哪些必须装备,以供准备出行的朋友们参考。 必备户外装…...

关于navicat连接mysql时报错问题
删除MySql 停止MySQL 1添加删除程序中卸载MySQL 2到安装目录删除MySQL 3删除:C:\Documents and Settings\All Users\Application Data\MySQL C:\ProgramData\MySQL 4查看注册表: regedit HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services HKEY_LOC…...

基尔霍夫定律小作业
...

基尔霍夫电压定律解析
一、还是先看定义 在电路沿任一回路 ,电势降低等用于电势升高 如上图,我们选取点A点,它经过过R2,电压降低了U2(因为电流是从高电势往低电势流的),在经过R1,电压又降低U1,那么最终又回到从负极回到A点&…...

仿真软件测试基尔霍夫定律,标签:基尔霍夫定律
根据基尔霍夫定律:节点上∑i0和回路中∑u0这两个公式,无论是在正旋稳态下还是在暂稳态电路中表达网络变量间的关系时都只取决于网络的布局即节点和支路的相互关系,而与支路的特性即支路由那些元件组成及其参数的量值都没有关系。因此当我们根…...

仿真软件测试基尔霍夫定律,实验三 基尔霍夫定律的验证(仿真实验)
产生的速度实验三 基尔霍夫定律的验证(仿真实验)一、实验目的1. 验证基尔霍夫定律的正确性,加深对基尔霍夫定律的理解。 2. 学会使用电流表、电压表测量各支路电流和各元件电压的方法。 3. 学会使用EWB仿真软件。二、实验原理基尔霍夫定律是集总电路的基本定律&…...

Docker常用命令操作
文章目录docker官方镜像搜索:https://hub.docker.com/Docker常用命令卸载Dockerdocker下载慢配置下载源docker官方镜像搜索:https://hub.docker.com/ Docker常用命令 # 进入docker容器命令 docker exec -it 容器名称 /bin/bash# 启动/停止/重启docker s…...

电路中的基尔霍夫定律理解与使用
在电路中,首先要理解几个基本概念: (1)支路:由一个或几个元件首尾相接构成的无分支电路叫支路。在同一支路中,流过各元件的电流相等。如右图中,有三条支路,R1和E1构成一条支路&#…...
电路-基尔霍夫定理
基尔霍夫电流定律KCL :电路中任一瞬间,流入任一结点的电流等于流出该结点的电流。(流入该节点的电流 代数和恒等于零) 其表达式可表示为: 基尔霍夫电压定律KVL :在任一瞬间,从回路中任一点出发&…...

Java 套接字(Socket)详解
套接字(socket)为两台计算机之间的通信提供了一种机制,在JamesGosling注意到Java语言之前,套接字就早已赫赫有名。该语言只是让您不必了解底层操作系统的细节就能有效地使用套接字。 1 客户机/服务器模型 在饭店里,…...

Windows注册表修改实例完全手册-5
(10)检查非注册表部分首先检查启动文件和磁盘引导扇区。对于Windows 9x/Me,启动文件是启动盘目录下的IO.sys和Command.com文件。同时,还包括Autoexec.bat文件中定义的程序文件,以及Config.sys文件中装载的程序文件。对于Windows NT/2000/XP&a…...

Java 套接字(Socket)
套接字(socket)为两台计算机之间的通信提供了一种机制,在JamesGosling注意到Java语言之前,套接字就早已赫赫有名。该语言只是让您不必了解底层操作系统的细节就能有效地使用套接字。 1、客户机/服务器模型 在饭店里,…...

Samba-HOWTO-Collection中文翻译版(2.20)
概要 本文档汇集了Samba文档历年来的HOWTOs。我试图确保所有内容都是最新的,但有时一个人维护不了这么大的项目。你可以在http://www.samba.org/ 的“Documentation”找到这份文档的最新版本,有更新的话寄给jerrysamba.org 。 干杯,jerry …...

Java Socket 详解
套接字(socket)为两台计算机之间的通信提供了一种机制,在James Gosling注意到Java 语言之前,套接字就早已赫赫有名。该语言只是让您不必了解底层操作系统的细节就能有效地使用套接字。1 客户机/服务器模型 …...

JAVA 选择题
单选题: 1) :在Java 语言中,不允许使用指针体现出的Java 特性是( ) A. 可移植 B.解释执行 C.健壮性 D.安全性 2) 下面哪些变量名在Java语言中是合法的? A.persons$ …...

《深入浅出计算机组成原理》学习笔记 Day1
文章目录1. 学习计算机组成原理的意义2. 性能的概念3. 性能的提升途径3.1 “堆硬件”3.2 加速大概率事件3.3 通过流水线提升性能3.4 通过预测提升性能1. 学习计算机组成原理的意义 理解计算机是怎么运作的,以及为什么要这么运作。 一方面,整个组成乃至体…...

Socket详解(转)
Java Socket全套资料 套接字(socket)为两台计算机之间的通信提供了一种机制,在James Gosling注意到Java 语言之前,套接字就早已赫赫有名。该语言只是让您不必了解底层操作系统的细节就能有效地使用套接字。 1 客户机/服务器模型 在…...

用Java Socket开发小型服务器,支持上千个并发
Java Socket套接字(socket)为两台计算机之间的通信提供了一种机制,在James Gosling注意到Java 语言之前,套接字就早已赫赫有名。该语言只是让您不必了解底层操作系统的细节就能有效地使用套接字。1 客户机/服务器模型在饭店里&…...
TCP/IP网络协议深入
网络协议就是网络之间沟通、交流的桥梁,只有相同网络协议的计算机才能进行信息的沟通与交流。这就好比人与人之间交流所使用的各种语言一样,只有使用相同语言才能正常、顺利地进行交流。从专业角度定义,网络协议是计算机在网络中实现通信时必…...

深入剖析“网上邻居”、UNC路径网络访问故障 .
关于网上邻居、UNC路径访问故障的问题,在论坛上常被问起。答案纷杂,一直没有一个比较全面细致的回答,本文将由浅入深全面深入地来剖析一下。 首先要和大家明确一条简单实用的原则:无论是何种访问故障问题,都应该首先…...

Python学习笔记-PyQt6对话框
对话框是界面编程中重要的窗体,一般用于提示或者一些其他特定操作。一、使用QDialog显示通用消息框直接使用QDialog类,可以及通过对话框进行通用对话框显示,亦可以通过自定义设置自己需要的对话框。# _*_ coding:utf-8 _*_import sysfrom PyQ…...

linux_查看当前安装语言包
1 yum list | grep fonts...

R语言包——tinytex的安装
R语言的tinytex包安装方法: 1、windows下,R版本为3.6,latex环境已经装好的情况下,输入下列语句即可成功: install.packages(‘tinytex’) tinytex::install_tinytex() 2、linux下,R版本为3.4.4,…...

TortoiseSVN 官网 中文语言包位置
中文语言包下载链接 https://osdn.net/projects/tortoisesvn/storage/1.13.1/Language%20Packs/LanguagePack_1.13.1.28686-x64-zh_CN.msi/ windows版本下载链接 https://osdn.net/projects/tortoisesvn/storage/1.13.1/Application/TortoiseSVN-1.13.1.28686-x64-svn-1.13.…...

Laravel中的信息验证 和 语言包
首先,谈下语言包的问题 1、安装语言包,通过composer进行安装composer require "overtrue/laravel-lang:dev-master"2、安装成功后,要到config/app.php中修改一下配置,Illuminate\Translation\TranslationServiceProvide…...
如何为opencart安装中文语言包
安装完opencart后,有的小伙伴觉得都是英文看不懂(我也看不懂。。。),所以,我们可以为他安装一个中文语言包 在安装之前我们需要先去下载中文语言包,目前好像还没有对应2.2.0.0以上版本的语言包 下载地址:https://www…...

centos8添加中文语言包
centos8添加中文语言包 系统:centos8 通过docker pull的centos:lastest, 发现是centos8. [rootdocker-desktop activity]# locale -a locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_MESSAGES to …...

事务(transaction)
事务(重点 五颗星 ***** 必须理解 必须掌握) 1、什么是事务: 一个事务其实就是一个完整的业务逻辑。 假设转账,从A账户向B账户转账10000.将A账户的钱减去10000(update语句),将B账 户的钱增加100…...

虹科案例 | 2016年 Komatsu 138US负载下发动机抖动
您可能会认为,对于建筑类机器,发动机越小越容易进行工作,但这与事实相去甚远!越小的发动机通常越难以施工。这台小的Komatsu的14T也不例外 我受托来看这一台2016年的Komatsu 138US,客户抱怨当机器启用油压负载…...

一文详细介绍文件系统与磁盘的基本原理
1.文件系统 文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构,即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统&…...

前端搬运工:零基础的前端开发初学者应如何系统地学习?前端掌握技能的学习路线
前端小伙伴们:【刚入门,但迷茫人群】,请认真读完 下面的 淘宝web 大神总结,如果你对前端是真爱的话,并且坚信可以作为职业去改变你的生活,慢慢日积月累,按这个来吧,真的!…...

加油吧,数字化转型@Nutanix企业云为西安国际医学数据中心保驾护航
看什么看,快点蓝字关注我!在中国,医疗资源分布不均衡、医患资源不匹配是当前医疗健康行业面临的普遍难题,也是全社会关注的热点。随着数字化时代的到来,传统医疗行业也面临转型,新技术在给传统就医模式带来…...

陶泓达:3.27最新黄金原油白银走势分析及操作策略!
【黄金行情走势分析】 上周五,黄金收盘1975附近,周K十字阴K收盘!在上周五的日内点评之中,李呈金说过,周五要防止下跌,修正,因此,持续做空思路为主。最后的修正还是走出来了。 所以&a…...

SOLIDWORKS案例 | 无缝协作方式降低成本
时间、成本和返工均减少 50%——SOLIDWORKS为发明家提供了经济实惠的产品开发服务 前情介绍 在当前的“创客”和技术孵化器开始流行之前,MAKO Design Invent 早在 1999 年就开始了创新,其使命是让发明家、初创企业和小型企业将他们的创意从概念转变为…...

目标检测:FP(误检)和FN(漏检)统计
1. 介绍 目标检测,检测结果分为三类:TP(正确检测),FP(误检),FN(漏检), 尤其是针对复杂场景或者小目标检测场景中,会存在一些FP(误检),FN(漏检)。 如何对检测的效果进行可视化,以帮助我们改进模型,提高模型recall值。 步骤 (1): 数据需要准备为yolo格式(2) 训练数据获得…...

2023年全国最新安全员精选真题及答案34
百分百题库提供安全员考试试题、建筑安全员考试预测题、建筑安全员ABC考试真题、安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 11.(单选题)物料提升机附墙架设置要符合设计要求,但…...

access2022(microsoft365)实战(5)-语言基础(3)
目录For Each...NextFor...Next 语句sub使用数组命名参数可选参数对象的当前实例For Each…Next For Each element In group [ statements ] [ Exit For ] [ statements ] Next [ element ]element 必填。 用于循环访问集合或数组的变量。 对于集合, 元素 只能是…...

UDP、TCP三次握手和四次挥手
-----UDP与TCP----- 相同点 tcp、udp都是工作在传输层进行数据传输(二进制标识文本或者视频或者图片) 不同点 tcp基于连接,保障传输的安全udp基于非连接,保障传输的速度 -----TCP的三次握手----- 过程 为什么不是两次握手&a…...

Camel Quartz Component创建QuartzScheduler的过程
Camel Quartz Component创建QuartzScheduler的过程QuartzScheduler的创建通过Spring配置文件调整Quartz配置参考QuartzScheduler的创建 在QuartzComponent启动时会对QuartzScheduler进行初始化。 org.apache.camel.component.quartz.QuartzComponent#doStart 在创建QuartzSc…...

MySQL InnoDB存储引擎性能调优
CPU 在InnoDB存储引擎的设计架构上看,其主要的后台操作都是在一个单独的master thread中完成的,因此并不能很好地支持多核应用。当然,开源社区已经通过多种方法来改变这种局面。如果你的CPU是多核,可以通过修改参数innodb_read_i…...

spring参数校验@Validated及嵌套校验
本文介绍项目中校验Validated的使用,主要分参数对象属性校验,嵌套校验,集合在对象属性中校验,集合作为参数校验。对象属性校验controller层RestController Slf4j RequestMapping("/api/test") public class TestControl…...

【数据结构刷题集】链表经典习题
😽PREFACE🎁欢迎各位→点赞👍 收藏⭐ 评论📝📢系列专栏:数据结构刷题集🔊本专栏涉及到题目是数据结构专栏的补充与应用,只更新相关题目,旨在帮助提高代码熟练度&#x…...

自然语言处理——句法分析和语义分析实验
实验要求: 输入医学影像报告描述“气管环清晰,粘膜正常,管腔完全阻塞。”,基于句法分析实现结构化信息抽取,输出结构化键值对如下: <气管环, 清晰> <粘膜, 正常> <管腔, 阻塞> 实验代码: # 输入医学影像报…...
Wayland中跨进程调用过程
1、基本概念 Wayland协议主要提供了Client端应用与Server端Compositor的通信机制,Weston是Server端Compositor的一个参考实现。Wayland协议中最基础的是提供了一种面向对象的跨进程过程调用的功能。在Wayland中Client和Server底层通过domain socket进行连接。domai…...

大前端05-用vue轻量级第三方组件库快速创建个画板,可以支持画板、直线、圆形等输入,可以撤回,改变颜色
第三方组件介绍: 1. vue-whiteboard vue-whiteboard 是一个基于Vue.js的轻量级画板组件库。 GitHub仓库: https://github.com/craynic/vue-whiteboard 优势: 轻量级支持基本绘图功能,如画线、圆等支持橡皮擦功能支持清空画布 劣势&…...
MarkDown示例
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...

ABeam News | 南昌大学拜访ABeam旗下德硕管理咨询(深圳),校企合作互利共赢
ABeam News近日,南昌大学一行领导莅临德硕管理咨询(深圳)有限公司进行拜访。ABeam大中华区董事长兼总经理中野洋辅先生、德硕管理咨询(深圳)人事经理汪婷婷女士与校方领导就校企合作和人才培养等多方面进行了深入交流与…...

AF染料试剂Alexa fluor 680 PEG Biotin,AF680 PEG Biotin,荧光强度稳定利于多种荧光标记
文章关键词:AF染料试剂,AF680,PE-Biotin衍生物Alexa fluor 680 PEG Biotin,AF680 PEG Biotin | Alexa fluor 680-PEG-生物素| CAS:N/A | 纯度:95%试剂参数信息: CAS:N/A 外观&am…...

java面试准备9
内存溢出和内存泄露的区别 内存溢出(Out of Memory):是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer;但给它存了long才能存下的数,那就…...

理解信号的
在日常生活中我们也经常面临许多的信号,手机通知、过红绿灯。。。这些信号在没有发生之前我们就知道这种信号产生我们需要干什么,那Linux里信号产生后,又怎么知道要做什么呢? -- 那当然是由程序员自己去设置啊 由于我们的用户空间…...

计算机知识——知识点整理
1、 字符的编码表示 ⭐️⭐️⭐️ 1、计算机处理数据中,除了数值型数据以外,还有字符、图形等的非数值型数据。非数值型数据还包括英文字母、符号、汉字等。 2、西文字符编码最常用的是ASCII字符编码 3、计算机的内部存储与操作常以字节为单位&#x…...

一文带你读懂程序员发展怎么样
2023年,随着互联网产业的蓬勃发展,程序员作为一个自带“高薪多金”标签的热门群体,被越来越多的人所关注。 图片 图片 一、现在进入IT行业当程序员还有前景吗? 图片 从自媒体端抖音视频号等短视频内容的火爆,到直播…...

Cmake 的构建结构
Cmake 构建结构I. 介绍A. CMake的作用和优势B. CMake的基本概念C. CMake的安装和环境配置CMake的下载和安装CMake的环境变量配置CMake的路径配置CMake的版本管理和更新II. CMake的构建结构A. 构建项的概念和作用B. 内置构建文件的结构和作用C. 依赖项的概念和作用D. 构建原理和…...

人工智能项目管理软件使用的全面指南
人工智能可以非常强大,而且已经在多个行业中使用。现在有不少人工智能项目管理软件可用,但它们是如何工作的,哪些工具提供了人工智能的好处?这篇文章将涵盖你需要考虑的关键因素,帮助你找到最合适的解决方案。 什么是…...

AI制药 - AlphaFold Multimer 的 MSA Pairing 源码
目前最新版本是v2.3.1,2023.1.12 AlphaFold multimer v1 于 2021 年 7 月发布,同时发表了一篇描述其方法和结果的论文。AlphaFold multimer v1 使用了与 AlphaFold 单体相同的模型结构和训练方法,但增加了一些特征和损失函数来处理多条链。Al…...

断网演练中遇到的问题及总结
一、背景 断网演练就是模拟单个数据中心完全不可用,但业务部门需要保证断网过程中的业务"零感知"。本次是我们系统参与的第六轮断网演练,在断网前,我们也做了充足的准备,如:域名分机房垂直部署,数…...

ceph cache tiering
缓存层模式 后端存储无论是erasure-coded或者经济性的存储层。ceph objecter控制对象的存储位置,tiering agent控制什么时间将对象从缓存层刷入到后端存储。管理员配置不同的缓存模式及 writeback ceph客户端将数据写入缓存层并从缓存层获取相应的ACK。之后数据会…...

C/C++获取文件名的方法(__FILE__,__builtin_FILE(),__BASE_FILE__)
目录标题C/C获取文件名的方法__FILE__宏避免__FILE__宏的错误慎用$(subst $(dir $<),,$<)\"")来重定义__BASE_FILE__宏__builtin_FILE()函数Windows API函数GetModuleFileName()getenv()使用cmake中的变量重定义__FILE__宏的CMake示例C/C获取文件名的方法 使用…...

【建议收藏】Android初级开发者怎样快速提高开发技能?这20个开源APP能帮到你
学习的最佳方式就是阅读,对程序员来说也是如此。如果你想成为一个更优秀的程序员,你必须阅读更多的代码,就是这么简单。书籍,博客,论坛在某种程度上都是有益的,但是没有什么能替代功能完善、代码详细的开源…...

【显卡】一文搞懂显卡
【显卡】一文搞懂显卡 文章目录【显卡】一文搞懂显卡1. 前言介绍1.1 CPU和显卡的区别1.1.1 作用不同1.1.2 结构不同1.1.3 应用场景不同1.2 三个著名的显卡公司2. 显卡的工作原理3. 显卡的分类3.1 集成显卡3.2 独立显卡3.3 核芯显卡4. 结构 & 总线接口类型4.1 显卡的结构4.2…...

01-死磕QNX someip
1. vsomeip3.1.20版本 环境配置 export COMMONAPI_CONFIG/etc/commonapi.ini export LD_LIBRARY_PATH/sdcard/someip:$LD_LIBRARY_PATH export VSOMEIP_CONFIGURATION/etc/vsomeip-service.json export VSOMEIP_APPLICATION_NAMEHelloWorldSomeIPService sysctl -w net.ine…...

《计算机网络原理》第三章 数据通信技术
3.1 概述 3.2 数据通信理论基础 主要内容 信号在通信信道上传输时的数学表示及其所受到的限制。传输介质是利用电压、电流、光信号等物理量的变化来传送二进制位流可将电压、电流等表示称为时间的单值函数f(t)这样就可以用数学的方法来描述信号的变化,并对其进行数…...

Java NIO学习之RandomAccessFile
文章目录一、 RandomAccessFile简介二、RandomAccessFile中的方法1. RandomAccessFile的构造函数2. 重要方法三、RandomAccessFile的使用一、 RandomAccessFile简介 RandomAccessFile既可以读取文件内容,也可以向文件输出数据。同时,RandomAccessFile支持…...

React 超详细入门教程
文章目录一,React简介1.什么是React2.React工作原理3.React历史4.React的特点5. React 高效的原因6.React 官方网站二,React基本使用1.基础代码2.相关js库3.创建虚拟DOM的两种方式4.虚拟DOM与真实DOM5. 虚拟DO M与真实DOM区别三,jsx的使用1.什…...

Codeforces Round 860 (Div. 2) (A-D)
文章目录A.Showstopper【贪心,模拟】B.Three Sevens【STL(邻接表)、倒着贪心】C.Candy Store【整除问题,贪心】D.Shocking Arrangement【结论题、数学】传送门A.Showstopper【贪心,模拟】 分析 考虑保证最大值的最大性…...

【Java】new Object()那些事
文章目录 内存分布字节码指令重排谈谈new Object() 内存分布 jvm32位、64位代表寻址空间能力 对象头分为:markworld、类型指针、实例数据、对齐(被8整除)。 如何体现: issavior@issavior ~ % java -version java version "17.0.5" 2022-10-18 LTS Java...

python实战:分析网站的m3u8文件下载ts文件并解密
前言 这个文章默认读者已了解m3u8的相关知识,包括如何在浏览器中查找m3u8文件的url和ts文件的下载地址; 代码实战 使用到的模块有: os,requests, re,Crypto 主要模块Crypto在安装时执行命令如下: pip install pycryptodome 实现逻辑: 在浏览器里找到m3u8文件的额url 解…...

基于springboot的java学习平台
092-springbootjava学习平台演示录像2022开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件ÿ…...

Spring Boot 基础学习之(四)页面通过自定义LocaleResolver组件实现网页页面的的中英文转换
在前端网页,是不是看见过这样的功能 基础网页:中文表示 点击下面的English 按钮网页显示文字开始切换 通过功能性按钮实现中英文切换,在浏览器中,都带着一个功能叫翻译功能,但是这种功能并不是所有的网页都能进行转换…...

Windows和Linux中Rabbitmq的安装和使用
Windows中Rabbitmq的安装Erlang的安装和环境变量的配置Rabbitmq像java一样他需要运行环境,这里需要首先下载Erlang然后配置相应的环境变量Erlang下载地址:Downloads - Erlang/OTP安装Erlang:然后配置Erlang的环境变量:打开系统命令…...

易基因:肠道菌群:早产儿出生后不同时间点肠道微生物定植的动态变化|项目文章
易基因微生物组学测序分析成果见刊《Front Microbiol》 2023年02月17日,中国农业科学院深圳农业基因组研究所Adnan Khan、云南省第一人民医院米弘瑛为共同第一作者,中山大学附属第六医院郝虎/李思涛、南方医科大学附属佛山市妇幼保健院戴怡蘅为论文共同…...

基于springboot垃圾分类网站(文档+程序+数据库)026
大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里为大家分享优质的实战项目,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路…...

Nginx的管理以及升级操作
Nginx的管理以及升级操作 如果Nginx启动了,可以使用nginx的命令来进行管理 查看进程:ps -ef | grep nginx平滑启动:nginx -s reload–>不停止nginx的情况下,无痕重启; 或者是:kill -HUP 单引号&#x…...

web前端面试题之代码题
1.获取最大值 方法一 方法二 const arr [6, 4, 1, 8, 2, 11, 23]; console.log(Math.max(...arr)) 1.去重 // 传统方式 function unique(arr) {const res []arr.forEach(item > {if (res.indexOf(item) < 0) {res.push(item)}})return res } 数组或者字符串去重 …...

【JeecgBoot-Vue3】第6节 低代码平台如何快速生成代码(上)
目录 一、场景 二、代码介绍 1. 后端 1.1 online代码生成器 1.2 数据库配置 1.3 代码生成配置 三、单表CRUD Step 1:新增表 Step 2:填写 表名 > 表描述,其它默认 Step 3:新增字段 > 数据库属性 Step 4࿱…...

【深入浅出 Yarn 架构与实现】5-3 Yarn 调度器资源抢占模型
本篇将对 Yarn 调度器中的资源抢占方式进行探究。分析当集群资源不足时,占用量资源少的队列,是如何从其他队列中抢夺资源的。我们将深入源码,一步步分析抢夺资源的具体逻辑。 一、简介 在资源调度器中,以 CapacityScheduler 为例…...

桐乡学电商淘宝
电商淘宝 课程名称:淘宝美工、淘宝运营综合班 招生对象: (1)有意向但无基础或有一些基础想继续提升,并准备从事该专业方向,希望能自己完成店铺的日常维护、装修、经营等工作。 (2)针对零基础想开…...

大模型爆火,AI行业人才紧缺,尤其是这三个方向
上周gpt-4和文心一言陆续发布,热搜上挂了好几天,话题量暴涨。体验了一下,学姐觉得,文心一言虽然还是有一定的差距,但百度这么多年一直持续在相关领域深耕技术,在这么短的时间内就推出了类ChatGPT产品&#…...

现在转行IT还有机会吗?
其实大部分所谓的机会都是建立在我们准备好的基础上的,因为大多数的企业并不会启用一个零基础毫无经验,或者没有企业所需要特质的人员。作为普通人而言,只有当你准备好之后,你才会看到机会,在这之前,你只会…...

Kruise Rollout v0.3.0:手把手教你实战操作Deployment 分批发布和流量灰度
helm3 安装 kubectl版本:v1.20.9 heml版本:v3.1.2 [rootk8smaster peishunwu] wget https://get.helm.sh/helm-v3.1.2-linux-amd64.tar.gz tar zxvf helm-v3.1.2-linux-amd64.tar.gz cd linux-amd64 cp helm /usr/bin/helm helm version version.Bu…...

Linux编译器-gcc/g++ 使用
在介绍gcc/g的使用前我们先了解一下两者的不同 gcc时主要编译c语言,而g主要编译c的,但是两者的选项是相同的,因此我们以gcc和c语言为例来讲解。背景知识 gcc和g都是编译器其核心作用将文本类文件翻译成二进制可执行 那么其过程是怎样的&…...

vue中名词解释
No名称略写作用应用场景其他1 单页面应用 (Single-page application) SPA 1,控制整个页面 2,抓取更新数据 3,无需加载,进行页面切换 丰富的交互,复杂的业务逻辑的web前端一般要求后端提供api数据…...

ChatGPT的多种用法(持续更新中。。。)
指南 写小说 “写一本拥有出人意料结局的推理小说。” “写一个让读者参与其中的交互小说。” “为孩子们写一本激励他们勇敢面对挑战的小说。” “编写一个有关科技创新的未来世界的小说。” “创造一个让读者感到沉浸其中的幻想故事。” 充当 Linux 终端 我想让你充当…...

DateTimePicker 日期时间选择器时间格式处理
//时间选择器格式处理timeChange(e) {var that thisvar date new Date(e);var y date.getFullYear(); // 年var m date.getMonth() 1; // 月m m < 10 ? (0 m) : m;var d date.getDate(); // 日d d < 10 ? (0 d) : d;var h date.getHours(); // 时h h < …...

FITC-PEG-OH荧光素-聚乙二醇-羟基用以标记生物分子,例如蛋白质,抗体,肽等
结构式: 中文名称:荧光素-聚乙二醇-羟基 英文名称:FITC-PEG-OH 激发/发射波长:515nm-520nm 性状:固体或粉末 溶剂:溶于DMSO,DMF,DCM,溶于水 分子量:400、600、1000、2000、3400…...

Java JDK详细安装配置(详细备忘版本)
目录概览一、下载安装二、环境配置三、常见问题一、下载安装 官方下载地址:点我去官网 java20 、java17如下: java8、java11如下 jre8 如下 以 java8 下载为例: 按步骤输入账号密码 之后就会跳出下载显示框 得到了文件名为 jdk-8u361-win…...

Spring Security 6.0系列【3】源码篇之基于过滤器的基本原理
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.0.4 本系列Spring Security 版本 6.0.2 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo 文章目录前言过滤器(Filter&am…...

H7-TOOL发布固件V2.21, 增加RTT快捷面板功能,脱机烧录增加英飞凌,Qorvo以及NXP,普冉,华大,灵动微等新系列(2023-03-26)
H7-TOOL所有资源汇总(含操作手册): H7-TOOL开发工具,1拖4/16脱机烧录,高速DAPLINK,RTOS Trace,CAN/串口助手, 示波器, RTT等,支持WiFi,以太网,高速USB和手持…...

Python采集商品数据信息,做数据可视化分析,又是对数据分析上心的一天
前言 环境使用 在开始之前,安装好我们的代码编辑器和环境是非常重要的 Python 3.8pycharm --> 编辑器jupyter notebook --> 数据分析编辑器 模块使用 requests >>> pip install requests 数据请求parsel >>> pip install parsel 数据解…...

[N1CTF 2018]eating_cms_
目录 信息收集 代码审计 parse_url解析漏洞 信息收集 进入即是登录页面,抓包一看应该是SQL注入,但是空格、%、|等等啥的都被waf了,不太好注入,先信息收集一波 花一分钟扫下目录,发现一个viminfo和register.php Viminfo文件…...

比较合规的分销模式有哪一些
梦龙商业案例分析,带你了解商业背后的秘密 首先肯定是一级分销的,有人说不是二级分销也可以吗? 其实二级分销也是有点悬的哦,因为严格来讲平台也算一级,如果做普通的二级,有可能会被定义成三级分销&#…...

【CSAPP】异常控制流 | 异常表 | 异常类别 | 同步异常 | 异步异常
💭 写在前面:本文将学习《深入理解计算机系统》的第六章 - 关于异常控制流和系统级 I/O 。CSAPP 是计算机科学经典教材《Computer Systems: A Programmers Perspective》的缩写,该教材由Randal E. Bryant和David R. OHallaron 合著。 本…...