新手小白的pytorch学习第五弹-----pytorch的工作流

我们之前学习了 pytorch 中的基本数据 tensor
今天我们要开始学习 pytorch 的简单工作流程了

数据 -> 构建或选择一个预训练的模型 -> 使得模型适应数据并能够进行预测 -> 评估模型 -> 通过实验提升性能 -> 保存并重新加载你训练的模型

机器学习和深度学习的关键是从过去获得的数据中,创建算法来发现数据中的模式,接着用我们所发现的模式来预测将来。
接下来我们就尝试使用pytorch创建一个模型,主要是一个线性模型

what_were_covering = { 1:"data(preparing and loading)",2:"build model",3:"fitting the model to data(training)",4:"making predictions and evaluating a model (inference)",5:"saving and loading a model",6:"putting it all together"
}

1 data(preparing and loading)

首先,我们导入必须要的包,同时查看一下pytorch的版本

import torch
import matplotlib.pyplot as plt
import torch.nn as nntorch.__version__

‘2.3.1+cu118’

机器学习就像一个包含两个方面的游戏:
1 将你的数据(图像、音频、视频、文本等)进行数学的表征
2 创建或者选择模型尽可能好地来学习这些表征

weights = 0.7
bias = 0.3
start = 0
end = 1
step = 0.02# 之前我们学习过, unsqueeze(dim=1)就是在列上增加单维度,这样我们的每个数据外面就有一个方括号了
# 这里 dim = 1, 大家可以自己试一试,可以把 unsqueeze(dim=1) 删除看看是什么形状
X = torch.arange(start, end, step).unsqueeze(dim = 1)
y = weights * X + biasprint(X[:10], y[:10])print(len(X))
print(len(y))

tensor([[0.0000],
[0.0200],
[0.0400],
[0.0600],
[0.0800],
[0.1000],
[0.1200],
[0.1400],
[0.1600],
[0.1800]]) tensor([[0.3000],
[0.3140],
[0.3280],
[0.3420],
[0.3560],
[0.3700],
[0.3840],
[0.3980],
[0.4120],
[0.4260]])
50
50

将我们的数据划分为训练集和测试集

一般训练集占数据的 60%~80%,测试集占 20%~40%

注意:当我们处理真实世界的数据集时,在项目的开始我们就需要划分数据,(测试数据集应该要一直和其他数据集分开),以使得我们的模型在测试集上进行测试,促进模型在它没有遇到过的数据上有更好的泛化性能

# 划分训练集和测试集
train_split = int (0.8 * len(X))
X_train, y_train = X[:train_split], y[:train_split]
X_test, y_test = X[train_split:], y[train_split:]len(X_train), len(y_train), len(X_test), len(y_test)

(40, 40, 10, 10)

我们刚开始学习东西搞不明白,最好是将我们学习的内容进行可视化,那让我们来具体看一看这些数据究竟是什么形态的吧!
唔,我还发现优秀的开发者,都比较喜欢把这些功能啥的函数话,那我们也来搞一个函数,功能就是绘画出我们的训练数据、真实值、预测值的函数

# 我刚开始学东西搞不懂,也喜欢把东西可视化,让我们具体来看看这些数据是什么形态的
# 我还发现优秀的代码编写者都喜欢把一件事情搞成一个函数来进行def plot_predictions(train_data=X_train,train_labels=y_train,test_data=X_test,test_labels=y_test,predictions=None):'''plots training data, test data and compares predictions.'''plt.figure(figsize=(10, 7))# 用蓝色来描绘训练数据, s是size的意思,可以试试其他的值还挺有意思的plt.scatter(train_data, train_labels, c="b", s=4, label="Traing data")# 用绿色来描绘测试数据plt.scatter(test_data, test_labels, c="g", s=4, label="Testing data")if predictions is not None:# 用红色来描绘预测数据plt.scatter(test_data, predictions, c="r", s=4, label="prediction data")# 展示标签plt.legend(prop={"size":14})
plot_predictions()

在这里插入图片描述

2 build model (创建模型)

import torch.nn as nn
import torchclass LinearRegressionModel(nn.Module):def __init__(self):super().__init__()self.weights = nn.Parameter(torch.randn(1,dtype=torch.float),requires_grad=True)self.bias = nn.Parameter(torch.randn(1,dtype=torch.float),requires_grad=True)def forward(self, x):return self.weights * x + self.bias
pytorch有四个比较基础且重要的模块,基本都要用到:

torch.nn
torch.optim
torch.utils.data.Dataset
torch.utils.data.DataLoader

(1) torch.nn 包含了计算图的所有构建块(本质上是一系列以特定方式执行的计算)
(2) torch.nn.Module 神经网络模块的基本类,如果使用pytorch创建神经网路,你的模型必须是nn.Module的子类,同时需要实现forward(),我现在懂了,forward()表示前向传播,用数学实现往前传就可以
(3) torch.optim 优化,对梯度的改变进行优化,让它以一种更好的方式进行训练同时减少损失或者说是代价

接着,我们来看看如何查找pytorch模型中的参数内容

首先,我们需要创建一个模型,通过上述创建我们模型的方法,不难发现,我们参数是用 torch.randn()来创建的,是个随机数,因此我们在这里使用torch.manual_seed()使得结果能够复现

# 由于nn.Parameter是随机的,因此我们使用 manual_seed() 来复现实验
torch.manual_seed(42)# 创建一个模型实例
model_0 = LinearRegressionModel()# 查看模型的参数
# 这行代码报错,所以我们有了list
# model_0.parameters() 
# <generator object Module.parameters at 0x0000020AF1316C80>list(model_0.parameters())

[Parameter containing:
tensor([0.3367], requires_grad=True),
Parameter containing:
tensor([0.1288], requires_grad=True)]

我们也可以使用 .state_dict() 来获得模型的状态(这个模型包含什么内容、参数啥的)
# 列出 参数的名称和它的内容
model_0.state_dict()

OrderedDict([(‘weights’, tensor([0.3367])), (‘bias’, tensor([0.1288]))])

我感觉这个 .state_dict() 比 .parameters() 好一些,数据内涵和内容更加清晰

实际上,我们希望从随机参数开始,让模型更新她们,来适应我们数据的最佳参数,就是我们自己定义的 weights 和 bias 值。

使用 torch.inference_mode()进行预测

# 用模型进行预测
with torch.inference_mode():y_preds = model_0(X_test)
with torch.no_grad():y_preds = model_0(X_test)

这是个啥,就是说我们进行训练的时候需要使用梯度来更新我们的参数值,而预测的时候我们是不需要梯度的,少了这个梯度计算的过程能够减少计算,尤其是有大量数据的时候。

上文中的 torch.inference_mode() 和 torch.no_grad() 都是同样的作用,不过前者是后来更新的,能够更快更方便使用

# 让我们来进行预测吧
print(f"测试样本的数量:{len(X_test)}")
print(f"预测:{len(y_preds)}")
print(f"预测值:{y_preds}")

测试样本的数量:10
预测:10
预测值:tensor([[0.3982],
[0.4049],
[0.4116],
[0.4184],
[0.4251],
[0.4318],
[0.4386],
[0.4453],
[0.4520],
[0.4588]])

接下来让我们可视化的看一看吧,使用我们自己创建的函数捏
plot_predictions(predictions=y_preds)

在这里插入图片描述
很明显,我们希望预测值和真实值之间差距越小越好,越接近0越好,显然,咱们这个预测是相当不好的

为什么呢?很简单,我们的 weights 和 bias 都是随机的值,它并没有根据我们的训练集生成,所以理所当然的预测值很糟糕

3 训练模型 和 预测评估

大多数情况下,我们是不知道数据理想的参数的,事实上,我们需要写代码看看是否模型能够找到理性的参数值

创建损失函数和使用pytorch的优化器

如果需要更新我们的参数,那么我们就需要损失函数和优化器

loss function:损失函数,一个衡量我们模型的代价的函数,看看我们的模型到底有多差的一个函数。根据预测值和真实值之间的比较,越低越好哈。eg:torch.nn.L1Loss()Mean absolute error平均绝对误差;torch.nn.BCELoss() Binary cross entropy for binary classification进行二分类的

optimizer:优化器,告诉我们的模型如何去更新梯度,同时能更好的降低损失。 eg:Stochastic(随机) gradient desent,torch.optim.SGD(); Adam optimizer,torch.optim.Adam()

同时我们还需要 train 循环和 test 循环来帮助我们实现这个事情

import torch.optim as optim
loss_fn = nn.L1Loss()
optimizer = optim.SGD(model_0.parameters(), lr=0.01)
# 开始正式写我们的训练部分了
epochs = 100# 让我们定义一些容器来存储一些比较重要的内容,同时也可以方便我们画图和理解这些内涵
epoch_count = []
loss_train = []
loss_test_value = []for epoch in range(epochs):# 模型进入训练模式model_0.train()y_pred = model_0(X_train)loss = loss_fn(y_pred, y_train)# print(f"loss:{loss}")optimizer.zero_grad()loss.backward()optimizer.step()# print(f"parameters:{model_0.state_dict()}")# 模型进入评估模式model_0.eval()with torch.inference_mode():y_test_preds = model_0(X_test)loss_test = loss_fn(y_test_preds, y_test)if epoch % 10 == 0:epoch_count.append(epoch)loss_test_value.append(loss_test.detach().numpy())loss_train.append(loss.detach().numpy())print(f"Epoch:{epoch} | loss_test_value:{loss_test_value} | loss_train:{loss_train}")

一条结果我摘出来了,是这样的,方便大家观看和理解。

Epoch:0 | loss_test_value:[array(0.48106518, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32)]

Epoch:0 | loss_test_value:[array(0.48106518, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32)]
Epoch:10 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32)]
Epoch:20 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32), array(0.2172966, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32), array(0.08908726, dtype=float32)]
Epoch:30 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32), array(0.2172966, dtype=float32), array(0.14464018, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32), array(0.08908726, dtype=float32), array(0.05314853, dtype=float32)]
Epoch:40 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32), array(0.2172966, dtype=float32), array(0.14464018, dtype=float32), array(0.11360953, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32), array(0.08908726, dtype=float32), array(0.05314853, dtype=float32), array(0.04543797, dtype=float32)]
Epoch:50 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32), array(0.2172966, dtype=float32), array(0.14464018, dtype=float32), array(0.11360953, dtype=float32), array(0.09919948, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32), array(0.08908726, dtype=float32), array(0.05314853, dtype=float32), array(0.04543797, dtype=float32), array(0.04167863, dtype=float32)]
Epoch:60 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32), array(0.2172966, dtype=float32), array(0.14464018, dtype=float32), array(0.11360953, dtype=float32), array(0.09919948, dtype=float32), array(0.08886633, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32), array(0.08908726, dtype=float32), array(0.05314853, dtype=float32), array(0.04543797, dtype=float32), array(0.04167863, dtype=float32), array(0.03818933, dtype=float32)]
Epoch:70 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32), array(0.2172966, dtype=float32), array(0.14464018, dtype=float32), array(0.11360953, dtype=float32), array(0.09919948, dtype=float32), array(0.08886633, dtype=float32), array(0.08059376, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32), array(0.08908726, dtype=float32), array(0.05314853, dtype=float32), array(0.04543797, dtype=float32), array(0.04167863, dtype=float32), array(0.03818933, dtype=float32), array(0.0347609, dtype=float32)]
Epoch:80 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32), array(0.2172966, dtype=float32), array(0.14464018, dtype=float32), array(0.11360953, dtype=float32), array(0.09919948, dtype=float32), array(0.08886633, dtype=float32), array(0.08059376, dtype=float32), array(0.07232123, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32), array(0.08908726, dtype=float32), array(0.05314853, dtype=float32), array(0.04543797, dtype=float32), array(0.04167863, dtype=float32), array(0.03818933, dtype=float32), array(0.0347609, dtype=float32), array(0.03132383, dtype=float32)]
Epoch:90 | loss_test_value:[array(0.48106518, dtype=float32), array(0.3463552, dtype=float32), array(0.2172966, dtype=float32), array(0.14464018, dtype=float32), array(0.11360953, dtype=float32), array(0.09919948, dtype=float32), array(0.08886633, dtype=float32), array(0.08059376, dtype=float32), array(0.07232123, dtype=float32), array(0.06473556, dtype=float32)] | loss_train:[array(0.31288138, dtype=float32), array(0.19767132, dtype=float32), array(0.08908726, dtype=float32), array(0.05314853, dtype=float32), array(0.04543797, dtype=float32), array(0.04167863, dtype=float32), array(0.03818933, dtype=float32), array(0.0347609, dtype=float32), array(0.03132383, dtype=float32), array(0.0278874, dtype=float32)]

大家也可以把epochs先设置为1单独看看每一次的loss和模型的参数值,我是自己试过的,可以看到loss一直在变小,模型的参数在逐渐往真实值靠近,还蛮有趣的。

注意到这里有个zero_grad(),我刚开始也不知道它到底有什么作用,现在知道了,由于这是一个循环,那每次循环我们优化器中梯度就会累加,这样很明显是不利于我们进行参数学习的,因此我们使用**zero_grad()**对优化器的梯度进行一个清零的作用。

plot_predictions(predictions=y_test_preds)

在这里插入图片描述
哇哦,epochs=100,也就是说训练100次,我们的预测值就非常的接近真实值了,让我们来看看模型的参数是什么,是不是很接近真实值

print(f"model_0的参数:{model_0.state_dict()}")
print(f"实际的真实参数值:weights={weights}, bias={bias}")

model_0的参数:OrderedDict([(‘weights’, tensor([0.5784])), (‘bias’, tensor([0.3513]))])
实际的真实参数值:weights=0.7, bias=0.3

可以看出来,已经在慢慢接近了,证明方向是正确的,让咱们再来100次看看。再运行一次训练部分的代码即可。

# 开始正式写我们的训练部分了
epochs = 100# 让我们定义一些容器来存储一些比较重要的内容,同时也可以方便我们画图和理解这些内涵
epoch_count = []
train_loss_values = []
test_loss_values = []for epoch in range(epochs):# 模型进入训练模式model_0.train()y_pred = model_0(X_train)loss = loss_fn(y_pred, y_train)# print(f"loss:{loss}")optimizer.zero_grad()loss.backward()optimizer.step()# print(f"parameters:{model_0.state_dict()}")# 模型进入评估模式model_0.eval()with torch.inference_mode():test_pred = model_0(X_test)test_loss = loss_fn(test_pred, y_test.type(torch.float))if epoch % 10 == 0:epoch_count.append(epoch)test_loss_values.append(test_loss.detach().numpy())train_loss_values.append(loss.detach().numpy())print(f"Epoch:{epoch} | loss_test_value:{test_loss_values} | loss_train:{train_loss_values}")

Epoch:0 | loss_test_value:[array(0.05646304, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32)]
Epoch:10 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32)]
Epoch:20 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32), array(0.04060482, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32), array(0.01758547, dtype=float32)]
Epoch:30 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32), array(0.04060482, dtype=float32), array(0.03233228, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32), array(0.01758547, dtype=float32), array(0.01415539, dtype=float32)]
Epoch:40 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32), array(0.04060482, dtype=float32), array(0.03233228, dtype=float32), array(0.02405975, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32), array(0.01758547, dtype=float32), array(0.01415539, dtype=float32), array(0.01071659, dtype=float32)]
Epoch:50 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32), array(0.04060482, dtype=float32), array(0.03233228, dtype=float32), array(0.02405975, dtype=float32), array(0.01647409, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32), array(0.01758547, dtype=float32), array(0.01415539, dtype=float32), array(0.01071659, dtype=float32), array(0.00728353, dtype=float32)]
Epoch:60 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32), array(0.04060482, dtype=float32), array(0.03233228, dtype=float32), array(0.02405975, dtype=float32), array(0.01647409, dtype=float32), array(0.00820156, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32), array(0.01758547, dtype=float32), array(0.01415539, dtype=float32), array(0.01071659, dtype=float32), array(0.00728353, dtype=float32), array(0.00385178, dtype=float32)]
Epoch:70 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32), array(0.04060482, dtype=float32), array(0.03233228, dtype=float32), array(0.02405975, dtype=float32), array(0.01647409, dtype=float32), array(0.00820156, dtype=float32), array(0.00502309, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32), array(0.01758547, dtype=float32), array(0.01415539, dtype=float32), array(0.01071659, dtype=float32), array(0.00728353, dtype=float32), array(0.00385178, dtype=float32), array(0.00893248, dtype=float32)]
Epoch:80 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32), array(0.04060482, dtype=float32), array(0.03233228, dtype=float32), array(0.02405975, dtype=float32), array(0.01647409, dtype=float32), array(0.00820156, dtype=float32), array(0.00502309, dtype=float32), array(0.00502309, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32), array(0.01758547, dtype=float32), array(0.01415539, dtype=float32), array(0.01071659, dtype=float32), array(0.00728353, dtype=float32), array(0.00385178, dtype=float32), array(0.00893248, dtype=float32), array(0.00893248, dtype=float32)]
Epoch:90 | loss_test_value:[array(0.05646304, dtype=float32), array(0.0481905, dtype=float32), array(0.04060482, dtype=float32), array(0.03233228, dtype=float32), array(0.02405975, dtype=float32), array(0.01647409, dtype=float32), array(0.00820156, dtype=float32), array(0.00502309, dtype=float32), array(0.00502309, dtype=float32), array(0.00502309, dtype=float32)] | loss_train:[array(0.02445896, dtype=float32), array(0.02102021, dtype=float32), array(0.01758547, dtype=float32), array(0.01415539, dtype=float32), array(0.01071659, dtype=float32), array(0.00728353, dtype=float32), array(0.00385178, dtype=float32), array(0.00893248, dtype=float32), array(0.00893248, dtype=float32), array(0.00893248, dtype=float32)]

再运行一下这段代码就可以继续绘图了

plot_predictions(predictions=y_test_preds)

在这里插入图片描述
哇,oh my god!又更加的接近了。再看看咱们的参数呢

print(f"model_0的参数:{model_0.state_dict()}")
print(f"实际的真实参数值:weights={weights}, bias={bias}")

model_0的参数:OrderedDict([(‘weights’, tensor([0.6990])), (‘bias’, tensor([0.3093]))])
实际的真实参数值:weights=0.7, bias=0.3

very close,非常接近了,BB们,兴不兴奋!
我们刚刚添加了测试的循环的代码,从model_0.eval()开始就是测试循环的代码啦!

现在我们开始尝试着绘画出损失函数的图像吧。

plt.plot(epoch_count, train_loss_values, label="Train loss")
plt.plot(epoch_count, test_loss_values, label="Test loss")
plt.title("Training and test loss curves")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.legend()

在这里插入图片描述
这是运行100次的损失图像,
运行200次的损失图像如下,真的很奇怪,希望以后能懂得为什么会这个样子吧
在这里插入图片描述

好,今天真是收获满满,基本上是训练和测试过了一遍,而且咱们还进行了可视化,更加地了解我们的数据了

今天教二年级的小孩英语,他真的是不听,尊嘟快把我结节都气出来了。不生气不生气,人生就像一场戏

BB啊,我跟你说,今天中午吃的紫苏牛蛙,嘎嘎好吃,辣椒炒肉也很好吃,都吃撑了,很开心很开心

BB啊,如果我的文档对你有帮助的话,记得给俺点个赞呐~

靴靴,谢谢!

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

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

相关文章

解决mysql,Navicat for MySQL,IntelliJ IDEA之间中文乱码

使用软件版本 jdk-8u171-windows-x64 ideaIU-2021.1.3 mysql-essential-5.0.87-win32 navicat8_mysql_cs 这个问题我调试了好久&#xff0c;网上的方法基本上都试过了&#xff0c;终于是解决了。 三个地方结果都不一样。 方法一 首先大家可以尝试下面这种方法&#xff1a…

Github 2024-07-15 开源项目周报 Top15

根据Github Trendings的统计,本周(2024-07-15统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目5非开发语言项目4JavaScript项目3TypeScript项目2Go项目1Solidity项目1Java项目1Rust项目1免费编程学习平台:freeCodeCamp.org 创建…

数据库系统概论:数据库完整性

引言 数据库是现代信息系统的心脏&#xff0c;数据的准确性和一致性对于业务流程至关重要。数据库完整性是确保数据质量的基石&#xff0c;它涵盖了数据的正确性、相容性和一致性&#xff0c;是数据安全与业务连续性的保障。 数据库完整性是指数据的精确性、可靠性和逻辑一致…

选择项目进度系统的10大必知软件

国内外主流的10款项目进度软件对比&#xff1a;PingCode、Worktile、蓝凌EIS智慧工作平台、Teambition、Tapd、Tower、Monday.com、ClickUp、Asana、Jira。 在选择项目进度系统时&#xff0c;你是否感到困惑或不确定如何挑选最适合自己团队的工具&#xff1f;市场上的众多选项和…

Uncaught (in promise) TypeError: Object(...) is not a function at eval

踩坑: Uncaught (in promise) TypeError: Object(...) is not a function at eval_at object.eval [as fullvalidate] (eval at <anonymo-CSDN博客 又新添一个错误的出现方式&#xff0c;后台启动没问题&#xff0c;但是我的数据库是无法自行启动的&#xff0c;这就导致在查…

Redis-布隆过滤器(Bloom Filter)详解

文章目录 什么是布隆过滤器 布隆过滤器的优点&#xff1a;布隆过滤器的缺点&#xff1a;其他问题 布隆过滤器适合的场景布隆过滤器原理 数据结构增加元素查询元素删除元素 如何使用布隆过滤器 Google开源的Guava自带布隆过滤器Redis实现布隆过滤器 Redis中配置布隆过滤器Redis…

MYSQL 四、mysql进阶 9(数据库的设计规范)

一、为什么需要数据库设计 二、范 式 2.1 范式简介 在关系型数据库中&#xff0c;关于数据表设计的基本原则、规则就称为范式。 可以理解为&#xff0c;一张数据表的设计结 构需要满足的某种设计标准的 级别 。要想设计一个结构合理的关系型数据库&#xff0c;必须满足一定的…

品牌出海“掘金”的王牌账号:亚马逊VC——WAYLI威利跨境助力商家

在全球化的大潮中&#xff0c;B2B模式已然成为品牌出海“掘金”的王牌账号&#xff0c;特别是在亚马逊VC这一强大平台的加持下。亚马逊VC不仅是企业间贸易的桥梁&#xff0c;更是品牌国际化的加速器。 亚马逊VC&#xff0c;为企业提供了直接进入亚马逊全球供应链的机遇。这不仅…

神经网络中如何优化模型和超参数调优(案例为tensor的预测)

总结&#xff1a; 初级&#xff1a;简单修改一下超参数&#xff0c;效果一般般但是够用&#xff0c;有时候甚至直接不够用 中级&#xff1a;optuna得出最好的超参数之后&#xff0c;再多一些epoch让train和testloss整体下降&#xff0c;然后结果就很不错。 高级&#xff1a;…

盛夏畅饮狂欢,肆拾玖坊肆玖嘿哈精酿白啤陪你嗨啤!

盛夏的炎热,犹如烈火燃烧,让人无法抵挡那股渴望畅饮的冲动。在这个时节,你是否也期待着与亲朋好友欢聚一堂,聚餐畅饮,共度清凉惬意的时光?快来!肆拾玖坊的肆玖嘿哈喊你一起嗨啤了! 提及啤酒,想必大家都不会陌生。这个古老的饮品,自公元前3世纪起便与人类相伴,穿越历史的长河,时…

【ProtoBuf】proto 3 语法 -- 详解

这个部分会对通讯录进行多次升级&#xff0c;使用 2.x 表示升级的版本&#xff0c;最终将会升级如下内容&#xff1a; 不再打印联系人的序列化结果&#xff0c;而是将通讯录序列化后并写入文件中。 从文件中将通讯录解析出来&#xff0c;并进行打印。 新增联系人属性&#xff…

常用指标和损失总结

损失 回归问题 L1损失 L1 损失是最小化模型参数的绝对值之和。 倾向于使模型参数接近零&#xff0c;导致模型变得更加稀疏。这意味着一些特征的权重可能变为零&#xff0c;从而被模型忽略。 对异常值非常敏感。异常值会导致参数权重绝对值增大&#xff0c;从而影响模型的整…

2024年【电工(高级)】考试报名及电工(高级)模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 电工&#xff08;高级&#xff09;考试报名参考答案及电工&#xff08;高级&#xff09;考试试题解析是安全生产模拟考试一点通题库老师及电工&#xff08;高级&#xff09;操作证已考过的学员汇总&#xff0c;相对有…

【Charles】-雷电模拟器-抓HTTPS包

写在前面 之前的文章我们写过如何通过Charles来抓取IOS手机上的HTTPS包以及遇到的坑。说一个场景&#xff0c;如果你的手机是IOS&#xff0c;但是团队提供的APP安装包是Android&#xff0c;这种情况下你还想抓包&#xff0c;怎么办&#xff1f; 不要慌&#xff0c;我们可以安装…

Elasticsearch 批量更新

Elasticsearch 批量更新 准备条件查询数据批量更新 准备条件 以下查询操作都基于索引crm_flow_info来操作&#xff0c;索引已经建过了&#xff0c;本文主要讲Elasticsearch批量更新指定字段语句&#xff0c;下面开始写更新语句执行更新啦&#xff01; 查询数据 查询指定shif…

Java基础 —— 项目一:ATM存取款系统

目录 一、系统架构搭建 二、系统欢迎页设计 三、用户开户功能 卡号去重复 根据卡号查找账户 四、用户登录功能 展示用户登录后的操作页面 查询账户信息 存款 取款 转账 销户 修改密码 五、整体代码 1.账户类Account 2.银行系统类ATM 3.测试类Test 运行结果 他人之得&#xff0c…

什么是AGI?以及AGI最新技术如何?

首先&#xff0c;AGI是Artificial General Intelligence的缩写&#xff0c;意为人工通用智能。AGI指的是一种拥有与人类相当智能水平的人工智能系统&#xff0c;能够在各种不同的任务和环境中进行智能决策和问题解决。与目前大多数人工智能系统只能在特定领域下执行特定任务不同…

上线 Airflow 官方!DolphinDB 带来数据管理新体验

在数据驱动的商业时代&#xff0c;企业对数据的实时处理和分析能力提出了更高的要求。同时&#xff0c;自动化地管理及优化数据处理流程&#xff0c;以提升效率和精准度&#xff0c;始终是企业不断追求的目标。 近期&#xff0c; DolphinDB 正式登陆 Apache Airflow 官方&…

悠律Ringbud pro开放式耳机:双奖设计,开放式畅听的舒适体验

悠律Ringbud pro凝声环开放式耳机 凭借其潮酷的外观&#xff0c;轻奢的体验&#xff0c;斩获2024红点设计奖&#xff1a;德国红点奖设立于1955年&#xff0c;被公认为国际性创意和设计的认可标志&#xff1b;而且还获得美国MUSE设计金奖&#xff1a;美国MUSE设计奖是最具代表性…

语法错误检测工具哪个好用?5个工具一键扫除错别字

在撰写文章或编辑文档的过程中&#xff0c;你是否曾为了寻找并修正那些细微的语法错误而耗费大量时间&#xff1f; 想象一下&#xff0c;如果有一个便捷的工具&#xff0c;能够即时在线帮你捕捉并修正这些错误&#xff0c;是不是既高效又省心&#xff1f;这正是“语法错误检测…