动手学深度学习V2每日笔记(模型选择+过拟合和欠拟合)

news2024/11/16 20:59:35

本文主要参考沐神的视频教程 https://www.bilibili.com/video/BV1K64y1Q7wu/?spm_id_from=333.788.recommend_more_video.0&vd_source=c7bfc6ce0ea0cbe43aa288ba2713e56d
文档教程 https://zh-v2.d2l.ai/

本文的主要内容对沐神提供的代码中个人不太理解的内容进行笔记记录,内容不会特别严谨仅供参考。

1.函数目录

1.1 numpy

numpy位置
zeros4.1
array4.1
np.random.normal4.1
np.random.shuffle4.1
np.power4.1

1.2 torch.Tensor

Tensor位置
sum4.2
numel4.2

1.3 pandas

pandas位置
DataFrame4.2

1.4 matplotlib.pyplot

plt位置
figure4.3
subplot4.3
plot4.3
legend4.3
xlabel or ylabel4.3
show4.3

2.模型选择

2.1训练误差和泛化误差

  • 训练误差:模型在训练数据上的误差
  • 泛化误差:模型在新数据上的误差
    我们关心的是泛化误差

2.2 验证数据集和测试数据集

  • 验证数据集:一个用来评估模型好坏的数据集。
    1.拿出50%的训练数据。
    2.不要跟训练数据混在一起。
    3.验证数据集也有可能是虚高的,并不代表你在新数据集上的泛化能力。
  • 测试数据集:**只用一次的数据集。**例如
    1.未来的考试。
    2.我出价的房子的实际成交价。
    3.用在Kaggle私有排行榜中的数据集。

2.3 K-则交叉验证

  • 在没有足够多数据时使用(这是常态)
  • 算法:
    1.将训练数据分成K块
    2.For i=i,…,K
    使用第i块作为验证数据集,其余的作为训练数据集
    3.报告K个验证集误差的平均
  • 常用:K=5或10

3. 过拟合和欠拟合

3.1 模型容量

  • 拟合各种函数的能力
  • 低容量的模型难以你和训练数据
  • 高容量的模型可以记住所有的训练数据
    在这里插入图片描述
    在这里插入图片描述

3.2 估计模型容量

  • 难以在不同的种类算法之间比较
    例如树模型和神经网络
  • 给定一个模型种类,将有两个主要因素
    1.参数个数
    2.参数值的选择范围
线性模型单隐藏层感知机
d+1(d+1)m+(m+1)k

在这里插入图片描述

3.2 数据复杂度

  • 多个重要因素
  • 样本个数
  • 每个样本的元素个数
  • 时间、空间结构
  • 多样性

4. 多项式回归

4.1 生成数据集

4.1.1 np.zeros

返回给定形状和类型的新数组,并填充零。

def zeros(shape, dtype=None, order='C', *args, **kwargs):
  • 参数
  • shape:int或者int元组
  • dtype:数据类型,可选项
import math
import numpy as np
import torch
from torch import nn
from d2l import torch as d2l

max_degree = 20
n_train, n_test = 100, 100
true_w = np.zeros(max_degree)
print(true_w)
#输入为
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

4.1.2 array

np.array()用于将输入数据(如列表、元组等)转换为 NumPy 数据库的函数。

def array(p_object, dtype=None, *args, **kwargs):
  • 参数
  • p_object:输入的数据(例如列表、元组)

4.1.3 np.random.normal

np.random.normal() 用于生成服从指定均值和标准差的正态分布的随机数,可以生成单个随机数,也可以生成多维数组形式的随机数。

# 默认均值为0,方差为1
numpy.random.normal(loc=0.0, scale=1.0, size=None)
  • 参数
  • loc:浮点数或数组,表示正态分布的均值(默认值为 0.0)。
  • scale:浮点数或数组,表示正态分布的标准差(默认值为 1.0)。
  • size:整数或元组,表示输出的形状。如果是整数,则返回指定数量的随机数。如果是元组,则返回相应形状的数组。
  • 返回值
  • 返回一个或多个服从指定正态分布的随机数。

4.1.4 np.random.shuffle

np.random.shuffle() 是 NumPy 库中的一个函数,用于对数组中的元素进行就地随机打乱(shuffle)。它可以作用于一维数组,也可以沿着指定的轴对多维数组进行打乱。

numpy.random.shuffle(x)
  • 参数
  • x:需要打乱顺序的数组。
  • 返回值
  • np.random.shuffle() 不返回任何值,因为它是就地操作,直接修改输入数组 x。

4.1.5 np.power

np.power() 是 NumPy 库中的一个函数,用于逐元素地计算两个数组的幂次。它返回一个数组,其中每个元素是对应输入数组元素的幂次结果。这个函数可以处理标量和数组作为输入。

numpy.power(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
  • 参数
  • x1:数组或标量,表示底数。
  • x2:数组或标量,表示指数。
  • out(可选):输出数组,保存结果。如果提供,该数组的形状必须与输入数组的形状相同。
  • where(可选):数组或条件,可选,用于指定计算位置,默认为 True。
  • casting(可选):字符串,用于指定数组的类型转换规则。
  • order(可选):指定输出数组的存储顺序。
  • dtype(可选):指定输出数组的数据类型。
  • subok(可选):布尔值,表示是否使用子类进行输出。
  • 返回值
  • 返回一个数组,其中每个元素是 x1 中对应元素的 x2 次幂。
a = np.array([1, 2, 3, 4])
b = np.power(a, np.arange(len(a)))
print(b)
# [ 1  2  9 64]

4.1.6 np.arange

np.arange 是 NumPy 库中的一个函数,用于生成一个包含等差序列的数组。它类似于 Python 内置的 range 函数,但返回的是一个 NumPy 数组,而不是列表。

numpy.arange([start, ]stop, [step, ]dtype=None, *, like=None)
  • 参数
  • start(可选):序列的起始值。默认为 0。
  • stop:序列的终止值(不包含在内)。
  • step(可选):序列的步长。默认为 1。
  • dtype(可选):输出数组的数据类型。如果未指定,则推断数据类型以最小化内存消耗。
  • like(可选):参考数组。如果提供,结果将与该数组具有相同的类型和属性。
  • 返回值
  • 返回一个包含等差序列的 NumPy 数组。
max_degree = 20
n_train, n_test = 100, 100
true_w = np.zeros(max_degree)
true_w[0:4] = np.array([5.0, 1.2, -3.4, 5.6])

features = np.random.normal(size=(n_test+n_train, 1))#features的shape为(200,1)
np.random.shuffle(features)
poly_features = np.power(features, np.arange(max_degree).reshape(1, -1))#poly_features的shape为(200,20)
for i in range(max_degree):
    poly_features[:, i] /= math.gamma(i+1)
labels = np.dot(poly_features, true_w)
labels += np.random.normal(scale=0.1, size=labels.shape)
true_w, features, poly_features, labels = [torch.tensor(x, dtype=torch.float32) for x in [true_w, features, poly_features, labels]]
print(features[:2])
print(poly_features[:2,:])
print(labels[:2])

4.2 对模型进行训练和测试

4.2.1 Tensor.sum()

Tensor.sum() 是 PyTorch 中用于计算张量所有元素的总和的函数。它有多个参数,可以灵活地应用于不同维度,或根据需要返回标量或张量。

sum(dim=None, keepdim=False, dtype=None) → Tensor
  • 参数说明
  • dim (int or tuple of ints, optional): 指定沿哪个维度计算总和。如果不指定,则计算所有元素的总和。
  • keepdim (bool, optional): 如果为 True,则保留原来的维度。默认值为 False。
  • dtype (torch.dtype, optional): 指定输出的数据类型。如果不指定,则与输入张量的数据类型相同。
x = torch.tensor([[1, 2, 3], [4, 5, 6]])

sum_dim0 = x.sum(dim=0)
print(sum_dim0)  # 输出: tensor([5, 7, 9])

sum_dim1 = x.sum(dim=1)
print(sum_dim1)  # 输出: tensor([ 6, 15])

sum_keepdim = x.sum(dim=0, keepdim=True)
print(sum_keepdim)  # 输出: tensor([[5, 7, 9]])

4.2.2 Tensor.numel()

返回输入张量中元素的总数。

a = torch.randn(1, 2, 3, 4, 5)
a.numel() #输出为120

4.2.3 pandas.DataFrame()

pd.DataFrame() 是 pandas 库中用于创建 DataFrame 对象的函数。DataFrame 是一种二维的、带标签的数据结构,可以看作是共享相同索引的 Series 的集合,类似于数据库中的表或 Excel 表格。

class pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=None)
  • 参数说明
  • data:数据,支持多种格式,例如字典、列表、NumPy 数组等。
  • index:索引标签,用于指定行标签。如果不指定,默认使用 RangeIndex (从 0 开始)。
  • columns:列标签,用于指定列标签。如果不指定,从数据中推断。
  • dtype:数据类型,用于指定 DataFrame 的数据类型。如果不指定,从数据中推断。
  • copy:布尔值,默认为 False。如果为 True,则复制输入数据。
    1. 从字典创建 DataFrame
import pandas as pd

data = {
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 30, 35],
    'city': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)
print(df)

在这里插入图片描述
2. 从列表创建 DataFrame

data = [
    ['Alice', 25, 'New York'],
    ['Bob', 30, 'Los Angeles'],
    ['Charlie', 35, 'Chicago']
]
df = pd.DataFrame(data, columns=['name', 'age', 'city'])
print(df)

3. 从 NumPy 数组创建 DataFrame

import numpy as np

data = np.array([
    ['Alice', 25, 'New York'],
    ['Bob', 30, 'Los Angeles'],
    ['Charlie', 35, 'Chicago']
])
df = pd.DataFrame(data, columns=['name', 'age', 'city'])
print(df)

计算损失

def evaluate_loss(net, data_iter, loss):
    metric = d2l.Accumulator(2)
    for X,y in data_iter:
        out = net(X)
        y = y.reshape(out.shape)
        l = loss(out, y)
        #l.sum():用于累加当前批量的总损失。
        #l.numel():用于累加当前批量的样本数量。
        metric.add(l.sum(), l.numel())
    return metric[0] / metric[1]

单轮训练

def train_epoch_ch3(net, train_iter, loss, trainer):#@save
    if isinstance(net, nn.Module):
        net.train()
    metric = d2l.Accumulator(3)
    for X, y in train_iter:
        y_hat = net(X)
        l = loss(y_hat, y)
        if isinstance(trainer,torch.optim.Optimizer):
            # 将梯度初始化为0
            trainer.zero_grad()
            # 反向传播计算
            l.mean().backward()
            # 根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值的作用
            trainer.step()
        else:
            l.sum().backward()
            trainer(X.shape[0])
        metric.add(float(l.sum()), d2l.accuracy(y_hat,y), y.numel())
    return metric[0]/metric[2], metric[1]/metric[2]

多轮训练

def train(train_features, test_features, train_labels, test_labels, num_epochs=400):
    loss = nn.MSELoss(reduction='none')
    input_shape = train_features.shape[-1]
    # 不设置偏置,因为我们已经在多项式中实现了它
    net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))
    batch_size = min(10, train_labels.shape[0])
    train_iter = d2l.load_array((train_features, train_labels.reshape(-1,1)),
                                batch_size)
    test_iter = d2l.load_array((test_features, test_labels.reshape(-1,1)),
                               batch_size, is_train=False)
    trainer = torch.optim.SGD(net.parameters(), lr=0.01)
    # 训练集损失列表
    train_loss_all = []
    # 验证集损失列表
    val_loss_all = []
    for epoch in range(num_epochs):
        train_loss, _ = train_epoch_ch3(net, train_iter, loss, trainer)
        test_loss = evaluate_loss(net, test_iter, loss)
        train_loss_all.append(train_loss)
        val_loss_all.append(test_loss)
        if epoch==0 or ((epoch+1)%20)==0:
            print(f"第{epoch + 1}轮训练集中的损失为{train_loss}")
            print(f"第{epoch + 1}轮验证集中的损失为{test_loss}")

    train_process = pd.DataFrame(data={"epoch": range(num_epochs),
                                       "train_loss_all": train_loss_all,
                                       "val_loss_all": val_loss_all,
                                        })
    return train_process

4.3 图形显示

4.3.1 plt.figure

plt.figure() 是 matplotlib 库中用于创建一个新的绘图窗口(figure)的函数。它提供了多种参数来定制绘图窗口的属性,包括大小、分辨率和背景颜色等。下面是 plt.figure() 的详细作用和用法。

matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, *, facecolor=None, edgecolor=None, frameon=True, 
FigureClass=<class 'matplotlib.figure.Figure'>, clear=False, **kwargs)[source]
  • 参数说明
  • num:int 或 str,默认为 None
    如果传递一个整数,将设置该 figure 的 ID。如果该 ID 已存在,则选择该 figure,而不创建新的。如果传递一个字符串,将该字符串作为 figure 的标题。
  • figsize:tuple,默认为 None
    指定 figure 的大小,格式为 (宽, 高),单位为英寸。
  • dpi:int,默认为 100
    指定 figure 的分辨率(每英寸的点数)。
  • facecolor:color,默认为 ‘white’
    指定 figure 的背景颜色。
  • edgecolor:color,默认为 ‘white’
    指定 figure 的边框颜色。
  • frameon:bool,默认为 True
    指定是否绘制 figure 的边框。
  • tight_layout:bool 或 dict,默认为 None
    如果为 True 或传递一个字典,将自动调整子图参数以适合 figure 区域。
  • constrained_layout:bool,默认为 None
    如果为 True,将自动调整子图参数以适合 figure 区域,并且不会重叠。
fig = plt.figure(facecolor='lightgray', edgecolor='blue')  # 背景颜色为浅灰色,边框颜色为蓝色
plt.plot([1, 2, 3], [4, 5, 6])
plt.show()

在这里插入图片描述

4.3.2 plt.subplot

plt.subplot() 是 Matplotlib 中用于在一个绘图窗口中创建多个子图的函数。它允许你在一个窗口中排列多个图表,使得可以在同一个图形中比较不同的数据或视图。下面是 plt.subplot() 的详细用法和作用。

plt.subplot(nrows, ncols, index)
  • nrows:子图的行数。
  • ncols:子图的列数。
  • index:子图的位置,从 1 开始计数,从左到右,从上到下排列。
plt.subplot(2, 2, 1)  # 2行2列的网格,选择第1个子图
plt.plot([1, 2, 3], [4, 5, 6])
plt.title('Subplot 1')

plt.subplot(2, 2, 2)  # 2行2列的网格,选择第2个子图
plt.plot([1, 2, 3], [6, 5, 4])
plt.title('Subplot 2')

plt.subplot(2, 2, 3)  # 2行2列的网格,选择第3个子图
plt.plot([1, 2, 3], [5, 6, 7])
plt.title('Subplot 3')

plt.subplot(2, 2, 4)  # 2行2列的网格,选择第4个子图
plt.plot([1, 2, 3], [7, 6, 5])
plt.title('Subplot 4')

plt.tight_layout()  # 自动调整子图参数,使之填充整个图像区域
plt.show()

在这里插入图片描述

4.3.3 plt.plot()

plt.plot() 是 Matplotlib 中用于绘制二维线图的基本函数。它可以绘制各种类型的线图,包括折线图、散点图、曲线图等。

import matplotlib.pyplot as plt

plt.plot(x, y, fmt, **kwargs)
  • x:x轴数据,可以是列表、数组或类似的序列。
  • y:y轴数据,可以是列表、数组或类似的序列。
  • fmt:可选,指定线条的格式字符串。
  • kwargs:可选,其他绘图参数。
    1. 使用格式字符串
    格式字符串可以包含颜色、线型和标记类型的简写。
颜色线型标记
b(蓝色)-(实线).(点)
g(绿色)–(虚线),(像素点)
r(红色)-.(点划线)v(上三角)
c(青色):(点线)^(下三角)
m(品红)s(正方形)
y(黄色)*(星号)
k(黑色)1(下三瓣叶)
w(白色)D(菱形)

标记:‘.’(点),‘,’(像素点),‘o’(圆圈),‘v’(下三角),‘^’(上三角),‘<’(左三角),‘>’(右三角),‘1’(下三瓣叶),‘2’(上三瓣叶),‘3’(左三瓣叶),‘4’(右三瓣叶),‘s’(正方形),‘p’(五边形),‘*’(星号),‘h’(六边形1),‘H’(六边形2),‘+’(加号),‘x’(x号),‘D’(菱形),‘d’(薄菱形),‘|’(竖直线),‘_’(水平线)

2. 使用关键字参数

plt.plot(x, y, color='green', linestyle='dashed', marker='o', markerfacecolor='blue', markersize=12)
plt.show()

常见的关键字参数:

  • color 或 c:指定线条颜色。
  • linestyle 或 ls:指定线型。
  • linewidth 或 lw:指定线宽。
  • marker:指定标记类型。
  • markersize 或 ms:指定标记大小。
  • markerfacecolor 或 mfc:指定标记填充颜色。
  • markeredgecolor 或 mec:指定标记边缘颜色
plt.subplot(2, 2, 1)  # 2行2列的网格,选择第1个子图
plt.plot([1, 2, 3], [4, 5, 6],'gs--')
plt.title('Subplot 1')

plt.subplot(2, 2, 2)  # 2行2列的网格,选择第2个子图
plt.plot([1, 2, 3], [6, 5, 4],'ro-.')
plt.title('Subplot 2')

plt.subplot(2, 2, 3)  # 2行2列的网格,选择第3个子图
plt.plot([1, 2, 3], [5, 6, 7],'ch-')
plt.title('Subplot 3')

plt.subplot(2, 2, 4)  # 2行2列的网格,选择第4个子图
plt.plot([1, 2, 3], [7, 6, 5],'yp:')
plt.title('Subplot 4')

plt.tight_layout()  # 自动调整子图参数,使之填充整个图像区域
plt.show()

在这里插入图片描述

4.3.4 plt.legend()

plt.legend() 是 Matplotlib 中用于添加图例(legend)的函数。图例是显示在图形上的一个区域,用于解释不同数据系列(如线条、点、柱等)的含义。通过图例,读者可以更容易地理解图表中的各个元素。
1.自动检测图例中要显示的元素
当不传入任何额外的参数时,绘图会自动确定要添加元素到图例中 。

import matplotlib.pyplot as plt

# 绘制多条线
plt.plot([1, 2, 3], [4, 5, 6], label='Line 1')
plt.plot([1, 2, 3], [6, 5, 4], label='Line 2')

# 添加图例
plt.legend()
plt.show()

在这里插入图片描述

4.3.5 plt.xlabel() or plt.ylabel()

plt.xlabel() 设置x轴标签。
plt.ylabel() 设置y轴标签。

4.3.6 plt.show()

显示当前图像窗口的所有内容。

 matplot_acc_loss(train_process):
    # 显示每一次迭代后的训练集和验证集的损失函数和准确率
    plt.figure(figsize=(12, 4))
    plt.subplot(1, 1, 1)
    plt.plot(train_process['epoch'], train_process.train_loss_all, "ro-", label="Train loss")
    plt.plot(train_process['epoch'], train_process.val_loss_all, "bs-", label="Val loss")
    plt.legend()
    plt.xlabel("epoch")
    plt.ylabel("Loss")
    plt.show()

5.完整代码

import math
import numpy as np
import pandas as pd
import torch
import matplotlib.pyplot as plt
from torch import nn
from d2l import torch as d2l

max_degree = 20
n_train, n_test = 100, 100
true_w = np.zeros(max_degree)
true_w[0:4] = np.array([5.0, 1.2, -3.4, 5.6])

features = np.random.normal(size=(n_test+n_train, 1))#features的shape为(200,1)
np.random.shuffle(features)
poly_features = np.power(features, np.arange(max_degree).reshape(1, -1))#poly_features的shape为(200,20)
for i in range(max_degree):
    poly_features[:, i] /= math.gamma(i+1)
labels = np.dot(poly_features, true_w)
labels += np.random.normal(scale=0.1, size=labels.shape)
true_w, features, poly_features, labels = [torch.tensor(x, dtype=torch.float32) for x in [true_w, features, poly_features, labels]]
print(features[:2])
print(poly_features[:2,:])
print(labels[:2])
# 对模型进行训练和测试
def evaluate_loss(net, data_iter, loss):
    metric = d2l.Accumulator(2)
    for X,y in data_iter:
        out = net(X)
        y = y.reshape(out.shape)
        l = loss(out, y)
        #l.sum():用于累加当前批量的总损失。
        #l.numel():用于累加当前批量的样本数量。
        metric.add(l.sum(), l.numel())
    return metric[0] / metric[1]

def train_epoch_ch3(net, train_iter, loss, trainer):#@save
    if isinstance(net, nn.Module):
        net.train()
    metric = d2l.Accumulator(3)
    for X, y in train_iter:
        y_hat = net(X)
        l = loss(y_hat, y)
        if isinstance(trainer,torch.optim.Optimizer):
            # 将梯度初始化为0
            trainer.zero_grad()
            # 反向传播计算
            l.mean().backward()
            # 根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值的作用
            trainer.step()
        else:
            l.sum().backward()
            trainer(X.shape[0])
        metric.add(float(l.sum()), d2l.accuracy(y_hat,y), y.numel())
    return metric[0]/metric[2], metric[1]/metric[2]

def train(train_features, test_features, train_labels, test_labels, num_epochs=400):
    loss = nn.MSELoss(reduction='none')
    input_shape = train_features.shape[-1]
    # 不设置偏置,因为我们已经在多项式中实现了它
    net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))
    batch_size = min(10, train_labels.shape[0])
    train_iter = d2l.load_array((train_features, train_labels.reshape(-1,1)),
                                batch_size)
    test_iter = d2l.load_array((test_features, test_labels.reshape(-1,1)),
                               batch_size, is_train=False)
    trainer = torch.optim.SGD(net.parameters(), lr=0.01)
    # 训练集损失函数
    # 训练集损失列表
    train_loss_all = []
    # 验证集损失列表
    val_loss_all = []
    for epoch in range(num_epochs):
        train_loss, _ = train_epoch_ch3(net, train_iter, loss, trainer)
        test_loss = evaluate_loss(net, test_iter, loss)
        train_loss_all.append(train_loss)
        val_loss_all.append(test_loss)
        if epoch==0 or ((epoch+1)%20)==0:
            print(f"第{epoch + 1}轮训练集中的损失为{train_loss}")
            print(f"第{epoch + 1}轮验证集中的损失为{test_loss}")

    train_process = pd.DataFrame(data={"epoch": range(num_epochs),
                                       "train_loss_all": train_loss_all,
                                       "val_loss_all": val_loss_all,
                                        })
    return train_process

def matplot_acc_loss(train_process):
    # 显示每一次迭代后的训练集和验证集的损失函数和准确率
    plt.figure(figsize=(12, 4))
    plt.subplot(1, 1, 1)
    plt.plot(train_process['epoch'], train_process.train_loss_all, "ro-", label="Train loss")
    plt.plot(train_process['epoch'], train_process.val_loss_all, "bs-", label="Val loss")
    plt.legend()
    plt.xlabel("epoch")
    plt.ylabel("Loss")
    plt.show()

# 从多项式特征中选择前4个维度,即1,x,x^2/2!,x^3/3!
train_process =train(poly_features[:n_train, :4], poly_features[n_train:, :4],labels[:n_train], labels[n_train:])
matplot_acc_loss(train_process)

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

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

相关文章

Java之归并排序

归并排序 归并排序(Merge Sort)算法&#xff0c;使用的是分治思想。分治&#xff0c;顾名思义&#xff0c;就是分而治之&#xff0c;将一个大问题分解成小的子问题来解决。小的子问题解决了&#xff0c;大问题也就解决了。 核心源码: mergeSort(m->n) merge(mergeSort(m-&g…

对于500强企业来说,有比FTP好用的传输工具吗?

500强企业在进行文件传输时&#xff0c;会根据其业务需求、数据安全性要求以及技术架构的不同&#xff0c;选择多种文件传输方式&#xff0c;最常见的便是FTP。然而FTP在使用却存在较多的问题&#xff1a; 1&#xff09;安全性问题 缺乏安全策略&#xff1a;FTP本身不提供加密…

「百年孤独」

引言 《百年孤独》是加西亚马尔克斯创作的魔幻现实主义经典小说&#xff0c;刻画了布恩迪亚家族七代人的跌宕起伏和马孔多小镇的兴衰。是拉丁美洲文学中一部不朽的杰作。 故事概述 小说从布恩迪亚家族的始祖荷塞阿卡迪奥布恩迪亚和妻子乌尔苏拉开始&#xff0c;讲述了七代人…

DeiT III(Meta)论文解读

paper&#xff1a;DeiT III: Revenge of the ViT official implementation&#xff1a;https://github.com/facebookresearch/deit 出发点 本研究旨在重新审视ViT的监督训练方法&#xff0c;并提出一种基于ResNet-50训练方法的简化版新训练策略。与现有的自动数据增强方法不…

C++从入门到起飞之——友元内部类匿名对象对象拷贝时的编译器优化 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1、友元 2、内部类 3、 匿名对象 4、对象拷⻉时的编译器优化 5、完结散花 1、友元 • 友元提供…

springAOP理解及事务

AOP&#xff1a; springAOP是什么&#xff1a; AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程、面向方面编程&#xff09;&#xff0c;其实就是面向特定方法编程。 使用场景&#xff1a; 比如你想统计业务中每个方法的执行耗时&#xff0c;那我们最…

基于bert的自动对对联系统

目录 概述 演示效果 核心逻辑 使用方式 1.裁剪数据集 根据自己的需要选择 2.用couplet数据集训练模型 模型存储在model文件夹中 3.将模型转换为ONNX格式 4.打开index.html就可以在前端使用此自动对对联系统了。 本文所涉及所有资源均在传知代码平台可获取。 概述 这个生成器利用…

什么是婚恋聊天交友源码?今天大家讲解一下。源码交付,支持二开,可打包APP小程序H5。

婚恋交友APP开发前景 对于现代的年轻人来说&#xff0c;社恐已经是深入骨子里不可别除的&#xff0c;除了每天上班下班&#xff0c;许多人宁愿宅在家里&#xff0c;面对线下的相亲机构&#xff0c;家里长辈介绍的会都是饭度抗柜的。而这几年疫情的影响更是大大的限制了正常的社…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

7. 运行时数据区-栈

栈的分类 栈分为Java虚拟机栈还有本地方法栈&#xff1a; Java虚拟机栈&#xff1a;用于保存Java中的方法相关的内容本地方法栈&#xff1a;用于保存在Java中使用native 标记的用C来实现方法 由于hotspot的作者发现使用一个栈就可以保存以上两个部分的内容&#xff0c;所以在…

图像生成中图像质量评估指标—PSNR的详细介绍

文章目录 1. 背景介绍2. 实际应用3. 总结和讨论 1. 背景介绍 峰值信噪比&#xff08;Peak Signal-to-Noise Ratio&#xff0c;简称PSNR&#xff09;是一种广泛应用于图像和视频处理领域的客观图像质量评价指标。它主要用于衡量图像的噪声水平和图像质量&#xff0c;可以用来评…

HttpClient初学

介绍&#xff1a; HttpClient 是Apache Jakarta Common 下的子项目&#xff0c;可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新的版本和建议。 这里阿里云的oss依赖底层是httpclient&#xff0c;所以这里不再重…

用f-string+sys.stdout.write定制“自己的writer”

f-stringsys.stdout.write&#xff0c;在python中“随意”我的输出。 (笔记模板由python脚本于2024年07月29日 08:09:35创建&#xff0c;本篇笔记适合喜欢python并有一定基础的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&am…

dotnet开发编译之争:Ahead-of-Time(AOT) vs Just-in-Time(JIT)谁才是未来最佳编译选择?

1. 前言 编译技术的选择对于现代应用程序的性能至关重要。在.Net开发平台下&#xff0c;选择合适的编译策略对于提升应用程序的响应速度、资源利用率以及最终用户体验有着不可忽视的影响。其中&#xff0c;Ahead-of-Time (AOT) 编译和 Just-in-Time (JIT) 编译是两种广泛采用的…

【编程工具使用技巧】VS如何显示行号

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《编程工具与技巧探索》 期待您的关注 目录 引言 一、VS编译器行号显示的基本步骤 1.打开VS与项目 2.进入选项设置 3.找到并…

Open3D 计算点到平面的距离

目录 一、概述 1.1原理 1.2实现步骤 1.3原理 二、代码实现 1.1关键函数 1.2完整代码 三、实现效果 3.1原始点云 3.2计算距离后赋色的点云 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#…

【更新2022】省级农业科技活动人员数测算 2009-2022无缺失

省级农业科技活动人员数测算数据在农业经济学、政策研究和农村发展规划等领域的论文研究中具有重要应用价值。首先&#xff0c;这些数据可用于分析省级农业科技活动的规模和结构变化&#xff0c;揭示不同地区在农业科技投入和产出方面的差异&#xff0c;为政府制定农业发展政策…

锅总浅析系统设计

如何进行系统设计&#xff1f;系统设计最佳实践有哪些&#xff1f;系统设计和软件工程有何区别&#xff1f;如何避免过度设计&#xff1f;学习书籍及软件工具推荐有哪些&#xff1f;前后端语言选型有哪些原则&#xff1f;考虑政策因素的系统设计步骤是怎样的&#xff1f; 带着这…

三维推:二维码生成与修改、加logo、设置有效期

进入后台&#xff0c;找到【二维码工具】下的【二维码在线生成】&#xff0c;可以看到&#xff0c;三维推支持网址、图片、音频、视频、文件以及模板生成二维码。 这里&#xff0c;我们以网址生成二维码为例来演示下&#xff0c;如何给二维码加logo、更改颜色等。 首先&#x…