动手学深度学习6.2 图像卷积-笔记练习(PyTorch)

news2024/9/20 22:41:30

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。

本节课程地址:卷积层_哔哩哔哩_bilibili 代码_哔哩哔哩_bilibili

本节教材地址:6.2. 图像卷积 — 动手学深度学习 2.0.0 documentation (d2l.ai)

本节开源代码:...>d2l-zh>pytorch>chapter_multilayer-perceptrons>conv-layer.ipynb


图像卷积

上节我们解析了卷积层的原理,现在我们看看它的实际应用。由于卷积神经网络的设计是用于探索图像数据,本节我们将以图像为例。

互相关运算

严格来说,卷积层是个错误的叫法,因为它所表达的运算其实是互相关运算(cross-correlation),而不是卷积运算。 根据 6.1节 中的描述,在卷积层中,输入张量和核张量通过(互相关运算)产生输出张量。

首先,我们暂时忽略通道(第三维)这一情况,看看如何处理二维图像数据和隐藏表示。在 下图 中,输入是高度为3、宽度为3的二维张量(即形状为3 × 3)。卷积核的高度和宽度都是2,而卷积核窗口(或卷积窗口)的形状由内核的高度和宽度决定(即2 × 2)。

在二维互相关运算中,卷积窗口从输入张量的左上角开始,从左到右、从上到下滑动。 当卷积窗口滑动到新一个位置时,包含在该窗口中的部分张量与卷积核张量进行按元素相乘,得到的张量再求和得到一个单一的标量值,由此我们得出了这一位置的输出张量值。 在如上例子中,输出张量的四个元素由二维互相关运算得到,这个输出高度为2、宽度为2,如下所示:

0×0+1×1+3×2+4×3=19,1×0+2×1+4×2+5×3=25,3×0+4×1+6×2+7×3=37,4×0+5×1+7×2+8×3=43.

注意,输出大小略小于输入大小。这是因为卷积核的宽度和高度大于1, 而卷积核只与图像中每个大小完全适合的位置进行互相关运算。 所以,输出大小等于输入大小 n_h \times n_w 减去卷积核大小 k_h \times k_w ,即:

(n_h-k_h+1) \times (n_w-k_w+1).

这是因为我们需要足够的空间在图像上“移动”卷积核。稍后,我们将看到如何通过在图像边界周围填充零来保证有足够的空间移动卷积核,从而保持输出大小不变。 接下来,我们在corr2d函数中实现如上过程,该函数接受输入张量X和卷积核张量K,并返回输出张量Y

二维卷积层

  • 输入 \mathbf{X}: n_h \times n_w
  • 核 \mathbf{W}: k_h \times k_w
  • 偏差 b \in \mathbf{R}
  • 输出 c\mathbf{Y}: (n_h - k_h + 1) \times (n_w - k_w + 1)
  • \mathbf{Y} = \mathbf{X} * \mathbf{W} + b
  • \mathbf{W} 和 b 是可学习的参数
import torch
from torch import nn
from d2l import torch as d2l
def corr2d(X, K):  #@save
    """计算二维互相关运算"""
    h, w = K.shape #获取卷积核的长&宽
    Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
    return Y

通过 上图 的输入张量X和卷积核张量K,我们来[验证上述二维互相关运算的输出]。

X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
corr2d(X, K)

输出结果:

tensor([[19., 25.],
[37., 43.]])

卷积层

卷积层对输入和卷积核权重进行互相关运算,并在添加标量偏置之后产生输出。 所以,卷积层中的两个被训练的参数是卷积核权重和标量偏置。 就像我们之前随机初始化全连接层一样,在训练基于卷积层的模型时,我们也随机初始化卷积核权重。

基于上面定义的corr2d函数[实现二维卷积层]。在__init__构造函数中,将weightbias声明为两个模型参数。前向传播函数调用corr2d函数并添加偏置。

class Conv2D(nn.Module):
    def __init__(self, kernel_size):
        super().__init__()
        self.weight = nn.Parameter(torch.rand(kernel_size))
        self.bias = nn.Parameter(torch.zeros(1))

    def forward(self, x):
        return corr2d(x, self.weight) + self.bias

高度和宽度分别为 h 和 w 的卷积核可以被称为 h \times w 卷积或 h \times w 卷积核。 我们也将带有 h \times w 卷积核的卷积层称为 h \times w 卷积层。

图像中目标的边缘检测

如下是[卷积层的一个简单应用:]通过找到像素变化的位置,来(检测图像中不同颜色的边缘)。 首先,我们构造一个 6 × 8像素的黑白图像。中间四列为黑色(0),其余像素为白色(1)。

X = torch.ones((6, 8))
X[:, 2:6] = 0
X

输出结果:
tensor([[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.]])

接下来,我们构造一个高度为1、宽度为2的卷积核K。当进行互相关运算时,如果水平相邻的两元素相同,则输出为零,否则输出为非零。

K = torch.tensor([[1.0, -1.0]])

现在,我们对参数X(输入)和K(卷积核)执行互相关运算。 如下所示,[输出Y中的1代表从白色到黑色的边缘,-1代表从黑色到白色的边缘],其他情况的输出为0。

Y = corr2d(X, K)
Y

输出结果:
tensor([[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.]])

现在我们将输入的二维图像转置,再进行如上的互相关运算。 其输出如下,之前检测到的垂直边缘消失了。 不出所料,这个[卷积核K只可以检测垂直边缘],无法检测水平边缘。

corr2d(X.t(), K)

输出结果:

tensor([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])

补充

学习卷积核

如果我们只需寻找黑白边缘,那么以上[1, -1]的边缘检测器足以。然而,当有了更复杂数值的卷积核,或者连续的卷积层时,我们不可能手动设计滤波器。那么我们是否可以[学习由X生成Y的卷积核]呢?

现在让我们看看是否可以通过仅查看“输入-输出”对来学习由X生成Y的卷积核。 我们先构造一个卷积层,并将其卷积核初始化为随机张量。接下来,在每次迭代中,我们比较Y与卷积层输出的平方误差,然后计算梯度来更新卷积核。为了简单起见,我们在此使用内置的二维卷积层,并忽略偏置。

# 构造一个二维卷积层,它具有1个输出通道和形状为(1,2)的卷积核
conv2d = nn.Conv2d(1,1, kernel_size=(1, 2), bias=False)

# 这个二维卷积层使用四维输入和输出格式(批量大小、通道、高度、宽度),
# 其中批量大小和通道数都为1
X = X.reshape((1, 1, 6, 8))
Y = Y.reshape((1, 1, 6, 7))
lr = 3e-2  # 学习率

for i in range(10):
    Y_hat = conv2d(X)
    l = (Y_hat - Y) ** 2
    conv2d.zero_grad()
    l.sum().backward()
    # 迭代卷积核
    conv2d.weight.data[:] -= lr * conv2d.weight.grad
    if (i + 1) % 2 == 0:
        print(f'epoch {i+1}, loss {l.sum():.3f}')

输出结果:
epoch 2, loss 4.114
epoch 4, loss 0.798
epoch 6, loss 0.178
epoch 8, loss 0.048
epoch 10, loss 0.016

在10 次迭代之后,误差已经降到足够低。现在我们来看看我们[所学的卷积核的权重张量]。

conv2d.weight.data.reshape((1, 2))

输出结果:
tensor([[ 1.0016, -0.9785]])

细心的读者一定会发现,我们学习到的卷积核权重非常接近我们之前定义的卷积核K

互相关和卷积

回想一下我们在 6.1节 中观察到的互相关和卷积运算之间的对应关系。 为了得到正式的卷积运算输出,我们需要执行 (6.1.6)中定义的严格卷积运算,而不是互相关运算。 幸运的是,它们差别不大,我们只需水平和垂直翻转二维卷积核张量,然后对输入张量执行互相关运算。

值得注意的是,由于卷积核是从数据中学习到的,因此无论这些层执行严格的卷积运算还是互相关运算,卷积层的输出都不会受到影响。 为了说明这一点,假设卷积层执行互相关运算并学习 上图 中的卷积核,该卷积核在这里由矩阵 \mathbf{K} 表示。 假设其他条件不变,当这个层执行严格的卷积时,学习的卷积核 \mathbf{K}' 在水平和垂直翻转之后将与 \mathbf{K} 相同。 也就是说,当卷积层对 上图 中的输入和 \mathbf{K}' 执行严格卷积运算时,将得到与互相关运算 上图中相同的输出。

为了与深度学习文献中的标准术语保持一致,我们将继续把“互相关运算”称为卷积运算,尽管严格地说,它们略有不同。 此外,对于卷积核张量上的权重,我们称其为元素

补充:

  • 二维互相关

y_{i,j} = \sum_{a = 1}^{h} \sum_{b = 1}^{w}w_{a,b}x_{i+a,i+b}

  • 二维卷积

y_{i,j} = \sum_{a = 1}^{h} \sum_{b = 1}^{w}w_{-a,-b}x_{i+a,i+b}

  • 由于对称性,在实际使用中没有区别

一维和三维互相关

  • 一维:文本、语言、时序序列(音频)

y_i = \sum_{a=1}^h w_a x_{i+a}

  • 三维:视频、医学图像、气象地图

y_{i,j,k} = \sum_{a=1}^h \sum_{b=1}^w \sum_{c=1}^d w_{a,b,c} x_{i+a,j+b,k+c}

特征映射和感受野

如在 6.1.4.1节 中所述, 上图 中输出的卷积层有时被称为特征映射(feature map),因为它可以被视为一个输入映射到下一层的空间维度的转换器。 在卷积神经网络中,对于某一层的任意元素 x ,其感受野(receptive field)是指在前向传播期间可能影响 x 计算的所有元素(来自所有先前层)。

请注意,感受野可能大于输入的实际大小。让我们用 上图 为例来解释感受野: 给定 2×2 卷积核,阴影输出元素值19的感受野是输入阴影部分的四个元素。 假设之前输出为 \mathbf{Y} ,其大小为 2×2,现在我们在其后附加一个卷积层,该卷积层以 \mathbf{Y} 为输入,输出单个元素 z 。 在这种情况下,\mathbf{Y} 上的 z 的感受野包括 \mathbf{Y} 的所有四个元素,而输入的感受野包括最初所有九个输入元素。 因此,当一个特征图中的任意元素需要检测更广区域的输入特征时,我们可以构建一个更深的网络。

小结

  • 二维卷积层的核心计算是二维互相关运算。最简单的形式是,对二维输入数据和卷积核执行互相关操作,然后添加一个偏置。
  • 我们可以设计一个卷积核来检测图像的边缘。
  • 我们可以从数据中学习卷积核的参数。
  • 学习卷积核时,无论用严格卷积运算或互相关运算,卷积层的输出不会受太大影响。
  • 当需要检测输入特征中更广区域时,我们可以构建一个更深的卷积网络。

练习

1. 构建一个具有对角线边缘的图像X

1)如果将本节中举例的卷积核K应用于X,会发生什么情况?

2)如果转置X会发生什么?

3)如果转置K会发生什么?

解:
代码如下:

X = torch.ones((5, 5))
for i in range(X.shape[0]):
    for j in range(X.shape[1]):
        if i == j:
            X[i,j] = 0
X

输出结果:
tensor([[0., 1., 1., 1., 1.],
[1., 0., 1., 1., 1.],
[1., 1., 0., 1., 1.],
[1., 1., 1., 0., 1.],
[1., 1., 1., 1., 0.]])

K = torch.tensor([[1.0, -1.0]])
corr2d(X, K)
# 输出形状为(5,4),检测对角线边缘,对角线上为-1,下为1

输出结果:
tensor([[-1., 0., 0., 0.],
[ 1., -1., 0., 0.],
[ 0., 1., -1., 0.],
[ 0., 0., 1., -1.],
[ 0., 0., 0., 1.]])

corr2d(X.t(), K)
# X转置后结果不变

输出结果:
tensor([[-1., 0., 0., 0.],
[ 1., -1., 0., 0.],
[ 0., 1., -1., 0.],
[ 0., 0., 1., -1.],
[ 0., 0., 0., 1.]])

corr2d(X, K.t())
# 输出形状变成(4,5),检测对角线边缘,对角线上为1,下为-1

输出结果:
tensor([[-1., 1., 0., 0., 0.],
[ 0., -1., 1., 0., 0.],
[ 0., 0., -1., 1., 0.],
[ 0., 0., 0., -1., 1.]])

2. 在我们创建的Conv2D自动求导时,有什么错误消息?

解:
报错:维度不匹配。因为输入和输出格式是四维的,包括批量大小、通道、高和宽,但自定义的Conv2D仅包含二维信息,即高和宽。
将输入和输出的批量大小和通道去掉,或者创建卷积层时增加批量大小和通道,均可解决该问题。

conv2d = Conv2D((1,2))
Y_hat = conv2d(X)
l = (Y_hat - Y) ** 2
conv2d.zero_grad()
l.sum().backward()
conv2d.weight.data[:] -= lr * conv2d.weight.grad

输出结果:

---------------------------------------------------------------------------

RuntimeError Traceback (most recent call last)

Cell In[24], line 3
1 conv2d = Conv2D((1,2))
2 Y_hat = conv2d(X)
----> 3 l = (Y_hat - Y) ** 2
4 conv2d.zero_grad()
5 l.sum().backward()


RuntimeError: The size of tensor a (4) must match the size of tensor b (7) at non-singleton dimension 3

3. 如何通过改变输入张量和卷积核张量,将互相关运算表示为矩阵乘法?

解:
核心思想是,将输入张量中每个与卷积核做互相关运算的元素展成一行,

比如将本节举例的X转变为: [0134124534674578]

再与reshape成列向量的卷积核K做矩阵乘法: [0134124534674578][0123]=[19253743]

再将结果reshape成输出Y的尺寸即可。

def corr2d_matmul(X, K): 
    h, w = K.shape
    # 将输入X中每次与卷积核做互相关运算的元素展平成一行
    # X_reshaped的每一行元素均为与卷积核做互相关的元素
    X_reshaped = torch.zeros((X.shape[0] - h + 1)*(X.shape[1] - w + 1), h*w)
    k = 0
    for i in range(X.shape[0] - h + 1):
        for j in range(X.shape[1] - w + 1):
            X_reshaped[k,:] = X[i:i + h, j:j + w].reshape(1,-1)
            k += 1
    # 将卷积核K转为列向量,并与X_reshaped做矩阵乘法,再reshape成输出尺寸即可
    Y = X_reshaped@K.view(-1)
    return Y.reshape(X.shape[0] - h + 1, X.shape[1] - w + 1)
X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
Y = corr2d_matmul(X, K)
Y

输出结果:
tensor([[19., 25.],
[37., 43.]])

4.手工设计一些卷积核。

1)二阶导数的核的形式是什么?

2)积分的核的形式是什么?

3)得到 𝑑 次导数的最小核的大小是多少?

解:

1)

  • 对于一阶导数:
    f^\prime(x) \approx \lim_{h \rightarrow 0}\frac{f(x+h)-f(x-h)}{2h}= \frac{f(x+1)-f(x-1)}{2}

对应的一阶导数卷积核为 \left[\begin{matrix} -1 & 0 & 1 \end{matrix}\right]

扩展至二维,对应的一阶导数水平卷积核为 \left[\begin{matrix} 0 & 0 & 0 \\ -1 & 0 & 1 \\ 0 & 0 & 0 \end{matrix}\right] 或者 \left[\begin{matrix} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \end{matrix}\right]

对应的一阶导数垂直卷积核为\left[\begin{matrix} 0 & -1 & 0 \\ 0 & 0 & 0 \\ 0 & 1 & 0 \end{matrix}\right] 或者 \left[\begin{matrix} -1 & -1 & -1 \\ 0 & 0 & 0 \\ 1 & 1 & 1 \end{matrix}\right]

  • 进一步地,对于二阶导数: f^{\prime\prime}(x) \approx \lim_{h \rightarrow 0}\frac{f(x+h)-2f(x)+f(x-h)}{h^2} = f(x+1)-2f(x)+f(x-1)

对应的二阶导数卷积核为 \left[\begin{matrix} 1 & -2 & 1 \end{matrix}\right]

扩展至二维, \frac{\partial^2 f}{\partial^2 x}(x,y) \approx f(x+1,y)-2f(x,y)+f(x-1,y)\frac{\partial^2 f}{\partial^2 y}(x,y) \approx f(x,y+1)-2f(x,y)+f(x,y-1)

对应的二阶导数水平卷积核为 \left[\begin{matrix} 0 & 0 & 0 \\ 1 & -2 & 1 \\ 0 & 0 & 0 \end{matrix}\right] 或者 \left[\begin{matrix} 1 & -2 & 1 \\ 1 & -2 & 1 \\ 1 & -2 & 1 \end{matrix}\right]

二阶导数垂直卷积核为 \left[\begin{matrix} 0 & 1 & 0 \\ 0 & -2 & 0 \\ 0 & 1 & 0 \end{matrix}\right] 或者 \left[\begin{matrix} 1 & 1 & 1 \\ -2 & -2 & -2 \\ 1 & 1 & 1 \end{matrix}\right]

二阶导数叠加卷积核为 \left[\begin{matrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{matrix}\right]

2)

  • 一维积分核--平均滤波器: K = \frac{1}{N} \left[ \begin{matrix} 1 & 1 & \ldots & 1 \end{matrix} \right] 其中, N 是 K 中的元素数量。
  • 二维积分核: 积分核可以是平均滤波器,也称为均值滤波器,其形式如下:
    二维平均滤波器 (也称为盒式滤波器或均质滤波器):

K = \frac{1}{M \times N} \begin{bmatrix} 1 & 1 & \ldots & 1 \\ 1 & 1 & \ldots & 1 \\ \vdots & \vdots & \ddots & \vdots \\ 1 & 1 & \ldots & 1 \end{bmatrix} 其中, M 和 N 分别是 N 的高度和宽度。

高斯积分核: 在空间域具有高斯形状,用于实现平滑效果,如下:

K = \frac{1}{\sigma \sqrt{2\pi}} \begin{bmatrix} e^{-\frac{x_1^2 + y_1^2}{2\sigma^2}} & \ldots & e^{-\frac{x_1^2 + y_N^2}{2\sigma^2}} \\ \vdots & \ddots & \vdots \\ e^{-\frac{x_M^2 + y_1^2}{2\sigma^2}} & \ldots & e^{-\frac{x_M^2 + y_N^2}{2\sigma^2}} \end{bmatrix}

其中, \sigma 是高斯分布的标准差, (x_i, y_j) 是滤波器中每个元素的坐标。

双边滤波器核:结合了空间域的高斯权重和强度域的高斯权重,用于在保持边缘的同时实现平滑,如下: K(i, j) = \frac{1}{W} \frac{1}{2\pi \sigma_s \sigma_r^2} e^{-\frac{(i - x)^2}{2\sigma_s^2}} e^{-\frac{(r - I(x,y))^2}{2\sigma_r^2}}

其中, W 是归一化因子,确保核的总权重为 1, \sigma_s 是空间域的标准差, \sigma_r 是强度域的标准差, 𝐼(𝑥,𝑦) 是图像在点 (x, y) 的强度, r 是中心像素的强度。

3)结合第一小问的解答,

  • 对于一阶导数,最小核的大小是3(一个3点中心差分近似)。
  • 对于二阶导数,在一维情况下,最小核的大小是3(一个3点中心差分近似)。在二维情况下,一个简单的近似可能是一个3×3的核。
  • 对于更高阶的导数,核的大小至少应与导数的阶数d相匹配,但这通常不足以提供良好的近似。实际使用的核会更大,以确保足够的平滑性和减少误差。

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

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

相关文章

【CSS01】CSS概述,使用样式的必要性,CSS语法及选择器

文章目录 一、什么是样式二、使用样式的必要性三、使用样式的几种方式四、CSS基本语法:五、CSS的注释六、CSS选择器——重点相关单词 一、什么是样式 概念: Cascade [kˈskeɪd] Style Sheet [ʃiːt] 级联样式单/表,层叠样式表 CSS有化腐…

使用C++实现ATM系统,谈谈思路及代码实现

🏆本文收录于「Bug调优」专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&…

权限维持-Linux-内核加载 LKM-Rootkit 后门

免责声明:本文仅做技术交流与学习... 目录 权限维持-Linux-内核加载 LKM-Rootkit 后门 项目地址: 安装: 隐藏用法: 将 root 权限授予非特权用户 隐藏文件、目录和内核模块 隐藏进程 隐藏 TCP 和 UDP 连接 高级玩法(c/s) 攻击机上(客户端)安装: 设置连接配置 权限维持…

代码随想录算法训练营第四十七天|1143.最长公共子序列、 1035.不相交的线、53. 最大子序和、392.判断子序列

1143.最长公共子序列 题目链接:1143.最长公共子序列 文档讲解:代码随想录 状态:一开始没想明白为啥要 max(dp[i - 1][j], dp[i][j - 1]) 思路: 如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素&#xff…

【c语言】玩转文件操作

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C语言 目录 引言 一、文件的打开和关闭 1.流 2.标准流 3.文本文件和二进制文件 4.控制文件打开与关闭的函数 二、文件的顺序读写 三、文件的随机读写 1…

收银系统源码-次卡功能

智慧新零售收银系统是一套线下线上一体化收银系统,给门店提供了含线下收银称重、线上商城、精细化会员管理、ERP进销存、营销活动、移动店务助手等一体化行业解决方案! 详细功能见下文: 门店收银系统源码-CSDN博客文章浏览阅读2.6k次&#…

猫咪浮毛太多怎么处理?6年铲屎官最值得买的猫毛空气净化器分享

作为一位拥有6年铲屎经验的铲屎官,家中既有宝宝又有毛孩子的铲屎官家庭来说,空气中的宠物异味和猫毛不仅影响生活质量,更关乎家人的健康。普通空气净化器虽然能够提供基本的空气净化,但对于养猫家庭的特定需求,如去除宠…

PHP宝藏神器多功能投票系统源码小程序

🎉发现宝藏神器!一键解锁“多功能投票小程序”的无限可能✨ 🌈 开篇安利:告别繁琐,拥抱高效! Hey小伙伴们,是不是经常为组织活动、收集意见而头疼不已?🤯 今天就要给大…

融云入驻首个数字生态出海基地,加速构建数字经济出海创新生态

7 月 3 日,“2024 全球数字经济大会”重要专题论坛“2024 数字生态出海发展论坛”在北京国家会议中心举行。 论坛由全球数字经济大会组委会主办,北京市经济和信息化局、北京市政务服务和数据管理局、大兴区人民政府共同承办。来自阿联酋、日本、古巴、…

挖到宝了,一个可自动根据设定兴趣主题爬取实时信息的AI挖掘工具。

在这个信息爆炸的时代,我们每天都被海量的资讯淹没。 无论是工作需要还是个人兴趣,我们都希望能够及时获取到最新、最有价值的信息。然而,手动搜索、筛选这些信息不仅耗时耗力,还常常让人感到疲惫。 今天,我给大家推…

【Python】Python中TODO的用法解析

目录 一.Python中的TODO是什么 二.Python中什么时候使用TODO 三.Pycharm中关于TODO的使用方式 一.Python中的TODO是什么 在Python中, TODO 通常不是一个语言内置的关键字或功能,而是被用作一种注释约定,来标记代码中需要进一步实现或改进的…

【Linux】touch

我们在介绍ls这个命令时,提到每个文件在Linux下面都会记录许多的时间参数,其实是有三个主要的变动时间,那么三个时间的意义是什么? 修改时间(modification time,mtime):当该文件的【内容数据】…

mongoDB教程(五):命名规范

还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,ech…

香蕉云编+uniapp打包ios的开发包和生产包

登录香蕉云编,找到 云编-ios证书生成,新建CSR文件,并下载csr文件。 登录苹果开发者中心,进入证书页面。 1.创建一个证书,选择ios Distribution类型即可,这是个通用的证书,既能用来打正式包又能…

想要做好非标设备行业的项目管理,这篇指南请收好!

近年来,随着制造业的快速发展和产业升级的不断推进,非标设备行业迎来了广阔的发展前景。一方面,制造业的快速发展带来了对非标设备的旺盛需求,尤其是在汽车、电子、航空航天等高端制造业领域,非标自动化设备的应用越来…

协议转换网关的工作原理-天拓四方

在当今数字化和网络化的社会中,不同系统和设备之间的通信至关重要。然而,由于技术多样性、厂商差异以及应用需求的复杂性,不同的系统和设备常常采用不同的通信协议,这使得它们之间的直接通信变得困难。为了解决这一问题&#xff0…

解决线程不安全问题的几种方式

线程不安全问题 日常生活中我们会经常碰到在不同的平台上买各种票的问题,例如在App、线下售票窗口等购买火车票、电影票。这里面就存在着线程安全的问题,因为当多个线程访问同一个资源时,会导致数据出错,例如甲和乙两人同时看中了…

深度解析:当下流行的人工智能大模型生成逻辑

在过去的几年里,人工智能领域经历了前所未有的革新,其中最引人注目的就是大规模预训练模型的崛起。这些模型,如GPT系列、BERT、T5、DALLE和CLIP等,凭借其强大的语言理解和生成能力,已经在自然语言处理(NLP&…

ctfshow(web入门-信息搜集)

1.web1 直接F12查看即可 2.web2 根据提示使用抓包工具 3.web3 根据提示使用burp抓包,然后参数使用repeater模块进行发送 4.web4 根据提示先访问robots 5.web5 6.web6 使用dirsearch 即可www.zip 7.web7 8.web8 9.web9 10. web10 11.web11 12.web12 根据提示在底…

wordpress的restfull API使用教程,之如何用postman调试API,以便能使用vue等前端框架开发主题

文章目录 API开发手册在postman中调试这里以 post 一篇文章为例,讲解如何调试: 步骤 1:生成应用密码步骤 2:配置Postman步骤 3:创建文章 参考链接 API开发手册 官方API手册:https://developer.wordpress.o…