【基于 PyTorch 的 Python 深度学习】6 视觉处理基础:卷积神经网络(1)

前言

文章性质:学习笔记 📖

学习资料:吴茂贵《 Python 深度学习基于 PyTorch ( 第 2 版 ) 》【ISBN】978-7-111-71880-2

主要内容:根据学习资料撰写的学习笔记,该篇主要介绍了卷积神经网络的卷积层部分。

预:从全连接层到卷积层

使用多层感知机网络来处理图像存在的不足

1)把图像展平为向量,极易丢失图像的部分固有属性;

2)使用全连接层极易导致参数量呈指数级增长。

图像最具代表性的两个特征:

1)平移不变性:不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应。

2)局部性:神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远的区域的关系。最终,在后续神经网络中,整个图像级别上可以集成这些局部特征用于预测。

一、卷积神经网络

卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络,由一个或多个卷积层和顶端的全连接层组成,同时包括关联权重和池化层等。图 6-1 是一个典型的卷积神经网络架构。

import torch
import torch.nn as nn
import torch.nn.functional as F

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

class CNNNet(nn.Module):
    def __init__(self):
        super(CNNNet, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=5, stride=1)
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(in_channels=16, out_channels=36, kernel_size=3, stride=1)
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(1296, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2(x)))
        # print(x.shape)
        x = x.view(-1, 36*6*6)
        x = F.relu(self.fc2(F.relu(self.fc1(x))))
        return x

net = CNNNet().to(device)

二、卷积层

卷积层是卷积神经网络的核心层,而卷积又是卷积层的核心。卷积,直观理解就是两个函数的一种运算,也被称为 卷积运算

卷积核窗口从输入张量的左上角开始,从左到右、从上到下滑动。当卷积核窗口滑动到新的位置时,包含在该窗口中的部分张量与卷积核张量按元素相乘,再将得到的张量求和得到一个单一的标量值。 

说明:输入矩阵 \left ( X_{w}, X_{h} \right ) 与卷积核  \left ( K_{w}, K_{h} \right ) 运算后的输出矩阵的形状为 \left ( X_{w}-K_{w}+1, X_{h}-K_{h}+1 \right )

用 PyTorch 代码实现卷积运算过程:

import torch

"""定义卷积运算函数"""
def cust_conv2d(X, K):
    # 获取卷积核形状
    h, w = K.shape
    # 初始化输出值 Y
    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 = torch.tensor([[1.0, 1.0, 1.0, 0.0, 0.0], [0.0, 1.0, 1.0, 1.0, 0.0],
                  [0.0, 0.0, 1.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0, 0.0], [0.0, 1.0, 1.0, 0.0, 0.0]])
K = torch.tensor([[1.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 1.0]])

print(cust_conv2d(X, K))

1、卷积核

卷积核 也称为 过滤器 ,是整个卷积过程的核心,比较简单的卷积核有垂直卷积核 Horizontal Filter、水平卷积核 Vertical Filter、索贝尔卷积核 Sobel Filter 等。这些卷积核能够检测图像的水平边缘、垂直边缘,增强图像中心区域权重等。

卷积核的作用:检测垂直边缘,检测水平边缘,以及检测其他边缘特征。

关于如何确定卷积核:卷积核类似于标准神经网络中的权重矩阵 WW 需要通过梯度下降算法反复迭代所得。同样,在深度学习中,卷积核也需要通过模型训练所得。卷积神经网络的主要目的是计算出这些卷积核的数值。确定得到这些卷积核后,卷积神经网络的浅层网络也就实现了对图像所有边缘特征的检测。

【代码实操】取图 6-7 为例,给定输入 X 及 输出 Y ,根据卷积运算,通过多次迭代,可以得到卷积核的近似值。

import torch
from torch import nn

"""定义输入和输出"""
X = torch.tensor([[10., 10., 10., 0.0, 0.0, 0.0], [10., 10., 10., 0.0, 0.0, 0.0], [10., 10., 10., 0.0, 0.0, 0.0],
                  [10., 10., 10., 0.0, 0.0, 0.0], [10., 10., 10., 0.0, 0.0, 0.0], [10., 10., 10., 0.0, 0.0, 0.0]])
Y = torch.tensor([[0.0, 30., 30., 0.0], [0.0, 30., 30., 0.0], [0.0, 30., 30., 0.0], [0.0, 30., 30., 0.0]])

"""训练卷积层"""
conv2d = nn.Conv2d(1, 1, kernel_size=(3, 3), bias=False)
# 这个二维卷积层使用四维输入和输出格式(批量大小、通道、高度、宽度)
X = X.reshape((1, 1, 6, 6))
Y = Y.reshape((1, 1, 4, 4))
lr = 0.001

# 定义损失函数
loss_fn = nn.MSELoss()
for i in range(400):
    Y_pre = conv2d(X)
    loss = loss_fn(Y_pre, Y)
    conv2d.zero_grad()
    loss.backward()
    # 迭代卷积核
    conv2d.weight.data[:] -= lr * conv2d.weight.grad
    if (i+1) % 100 == 0:
        print(f'epoch {i+1}, loss: {loss.item():.4f}')

"""查看卷积核"""
print(conv2d.weight.data.reshape((3, 3)))

2、步幅

步幅 strides 就是卷积核在输入矩阵中每次移动的格数,在图像中就是跳过的像素个数。

在小窗口移动过程中,卷积核的值始终保持不变,即卷积核的值在整个过程中是共享的,称其为 共享变量 。卷积神经网络采用参数共享的方法大大降低了参数的数量。在用 PyTorch 实现时,strides 参数格式为单个整数或两个整数的元组。

3、填充

当输入图像与卷积核不匹配或卷积核超过图像边界时,可以采用边界填充的方法,即对图像尺寸进行扩展,扩展区域补零。补零填充 zero padding 对于图像边缘部分的特征提取是很有帮助的,可以防止信息丢失。

根据是否扩展可将填充方式分为 SameValid 两种。采用 Same 时,对图像扩展并补零;采用 Valid 时,不对图像进行扩展。在实际训练过程中,通常选择 Same 方式,因为使用这种方式不会丢失信息。

假设填充零的圈数为 p ,输入数据大小为 n ,卷积核大小为 f ,步幅大小为 s ,则有:p=\frac{f-1}{2},卷积后的大小:\frac{n+2p-f}{s}+1 。

4、多通道上的卷积

前面对卷积在输入数据、卷积核的维度上进行了扩展,但输入数据、卷积核都是单一的。从图像的角度来说,二者都是灰色的,没有考虑彩色图像的情况。在实际应用中,输入数据往往是多通道的,如彩色图像是 3 通道,即 R 、G 、B 通道。

(1)多输入通道

3 通道图像 的卷积运算和单通道图像的卷积运算基本一致,对于 3 通道的 RGB 图像,其对应的卷积核算子同样也是 3 通道的。例如图 6-14 中的输入图像是 3×5×5 的,3 个维度分别表示 通道数 channel高度 height宽度 width 。卷积过程就是将每个单通道与对应的卷积核进行卷积运算,然后将 3 通道的和相加,得到输出图像的一个像素值。

用 PyTorch 代码实现卷积运算过程:

import torch

"""定义卷积运算函数"""
def cust_conv2d(X, K):
    # 获取卷积核形状
    h, w = K.shape
    # 初始化输出值 Y
    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

"""定义多输入通道卷积运算函数"""
def conv2d_multi_in(X, K):
    h, w = K.shape[1], K.shape[2]
    value = torch.zeros(X.shape[0]-h+1, X.shape[1]-w+1)
    for x, k in zip(X, K):
        value = value + cust_conv2d(x, k)
    return value


"""定义输入数据"""
X = torch.tensor([[[1., 0., 1., 0., 2.], [1, 1, 3, 2, 1], [1, 1, 0, 1, 1], [2, 3, 2, 1, 3], [0, 2, 0, 1, 0]],
                  [[1., 0., 0., 1., 0.], [2, 0, 1, 2, 0], [3, 1, 1, 3, 0], [0, 3, 0, 3, 2], [1, 0, 3, 2, 1]],
                  [[2., 0., 1., 2., 1.], [3, 3, 1, 3, 2], [2, 1, 1, 1, 0], [3, 1, 3, 2, 0], [1, 1, 2, 1, 1]]])
K = torch.tensor([[[0., 1., 0.], [0, 0, 2], [0, 1, 0]],
                  [[2., 1., 0.], [0, 0, 0], [0, 3, 0]],
                  [[1., 0., 0.], [1, 0, 0], [0, 0, 2]]])

print(conv2d_multi_in(X, K))

(2)多输出通道

为了实现更多边缘检测,可以增加更多 卷积核组 。不同卷积核组卷积得到不同的输出,个数由卷积核组决定。

(3)1×1 卷积核

1×1 卷积核 在很多经典网络结构中都有使用,例如 Inception 网络、ResNet 网络、YOLO 网络和 Swin-Transformer 网络等。

在网络中增加 1×1 卷积核的主要作用:

增加或降低通道数:如果卷积的输入输出都只是一个二维数据,那么 1×1 卷积核意义不大,它完全不考虑像素与周边其他像素之间的关系。但如果卷积的输入输出是多维矩阵,则可以通过 1×1 卷积核不同的通道数,增加或降低卷积后的通道数。

增加非线性:1×1 卷积核利用后接的非线性激活函数,可以在保持特征图尺度不变的前提下大幅增加非线性特性,使网络更深,同时提升网络的表达能力。

跨通道信息交互:使用 1×1 卷积核可以增加或降低通道数,也可以组合来自不同通道的信息。

图 6-17 为通过 1×1 卷积核改变通道数的示例:

用 PyTorch 代码实现卷积运算过程:

import torch

"""生成输入及卷积核数据"""
X = torch.tensor([[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
                  [[1, 1, 1], [1, 1, 1], [1, 1, 1]],
                  [[2, 2, 2], [2, 2, 2], [2, 2, 2]]])
K = torch.tensor([[[[1]], [[2]], [[3]]],
                  [[[4]], [[1]], [[1]]],
                  [[[5]], [[3]], [[3]]]])

print(K.shape)  # torch.Size([3, 3, 1, 1])

"""定义卷积运算函数"""
def cust_conv2d(X, K):
    # 获取卷积核形状
    h, w = K.shape
    # 初始化输出值 Y
    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

"""定义多输入通道卷积运算函数"""
def conv2d_multi_in(X, K):
    h, w = K.shape[1], K.shape[2]
    value = torch.zeros(X.shape[0]-h+1, X.shape[1]-w+1)
    for x, k in zip(X, K):
        value = value + cust_conv2d(x, k)
    return value

"""定义卷积函数"""
def conv2d_multi_in_out(X, K):
    return torch.stack([conv2d_multi_in(X, k) for k in K])

print(conv2d_multi_in_out(X, K))

5、激活函数

卷积神经网络与标准的神经网络类似,为了保证非线性,也需要使用 激活函数 ,即在卷积运算后,把输出值另加偏移量输入激活函数,作为下一层的输入。

常用的激活函数有 torch.nn.functional.sigmoid、torch.nn.functional.relu、torch.nn.functional.softmax、torch.nn.functional.tanh、torch.nn.functional.dropout 等。类对象方式的激活函数有 torch.nn.Sigmoid、torch.nn.ReLU、torch.nn.Softmax、torch.nn.Tanh、torch.nn.Dropout 等。

6、卷积函数

卷积函数 是构建神经网络的重要支架,通常 PyTorch 的卷积运算是通过 nn.Conv2d 来完成的。

(1)nn.Conv2d 函数

nn.Conv2d (
    in_channels: int,
    out_channels: int,
    kernel_size: Union[int, Tuple[int, int]],
    stride: Union[int, Tuple[int, int]] = 1,
    padding: Union[int, Tuple[int, int]] = 0,
    dilation: Union[int, Tuple[int, int]] = 1,
    groups: int = 1,
    bias: bool = True,
    padding_mode: str = 'zeros',
)

 主要参数说明:

参数说明
in_channels(int)输入信号的通道
out_channels(int)卷积产生的通道
kernel_size(int or tuple)卷积核的尺寸
stride(int or tuple, optional)卷积步长
padding(int or tuple, optional)输入的每一条边补充 0 的层数
dilation(int or tuple, optional)卷积核元素之间的间距
groups(int, optional)控制输入和输出之间的连接
bias(bool, optional)如果 bias=True 则添加偏置
padding_mode可选模式:zeros、reflect、replicate、circular

说明:当 group=1 时,输出是所有的输入的卷积;当 group=2 时,相当于有并排的两个卷积层,每个卷积层计算输入通道的一半,并且产生的输出是输出通道的一半,随后将这两个输出连接起来。 在 bias 中,参数 kernel_size、stride、padding、dilation 可以是整型数值 int ,此时卷积的 height 和 width 值相同,也可以是 tuple 数组,第一维度表示 height 值,第二维度表示 width 值。

(2)输出形状

卷积函数 nn.Conv2d 参数中输出形状的计算公式:

Input:(N, C_{in}, H_{in}, W_{in})

Output:(N, C_{out}, H_{out}, W_{out})

H_{out}=\frac{H_{in}+2\times padding[0]-dilation[0]\times (kernel\, size[0]-1)-1}{stride[0]}+1

 W_{out}=\frac{W_{in}+2\times padding[1]-dilation[1]\times (kernel\, size[1]-1)-1}{stride[1]}+1

weight:(out_channels, in_channels/groups, kernel_size[0], kernel_size[1])

import torch
import torch.nn as nn

"""当 groups=1 时"""
conv = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=1, groups=1)
conv.weight.data.size()  # torch.Size([12, 6, 1, 1])
print(conv.weight.data.size())


"""当 groups=2 时"""
conv = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=1, groups=2)
conv.weight.data.size()  # torch.Size([12, 3, 1, 1])
print(conv.weight.data.size())

"""当 groups=3 时"""
conv = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=1, groups=3)
conv.weight.data.size()  # torch.Size([12, 2, 1, 1])
print(conv.weight.data.size())

7、转置卷积

转置卷积 Transposed Convolution 在某些文献中也称为反卷积 Deconvolution 或部分跨越卷积 Fractionally-strided Convolution 。

通过卷积的正向传播的图像通常会越来越小,类似于下采样。卷积的反向传播实际上就是一种转置卷积,类似于上采样。

我们先来简单回顾卷积的正向传播,假设卷积操作的输入大小 n 为 4 ,卷积核大小 f 为 3 ,步幅 s 为 1 ,填充 p 为 0 。 

对于上述卷积运算,我们将 3×3 卷积核展平为 [4,16] 的稀疏矩阵 C

我们再将 4×4 的输入特征展平为 [16,1] 的矩阵 X ,那么 Y = CX 将是 [4,1] 的输出特征矩阵,将其重新排列成 2×2 的输出特征。

那么反向传播时又会如何呢?假设损失函数为 L ,则反向传播时,可以利用链式法则得到对 L 关系的求导:

\frac{\partial L}{\partial x_{j}}=\sum_{i}\frac{\partial L}{\partial y_{i}}\frac{\partial y_{i}}{\partial x_{j}}=\sum_{i}\frac{\partial L}{\partial y_{i}}C_{i,j}=\frac{\partial L}{\partial y}C_{*,j}=C_{*,j}^{T}\frac{\partial L}{\partial y}

由此,可得 X=C^{T}Y ,即反卷积就是要对这个矩阵运算过程进行逆运算。转置卷积主要用于生成式对抗网络 GAN 。

PyTorch 中二维转置卷积的格式为:

torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, 
                         output_padding=0, groups=1, bias=True, dilation=1, padding_mode='zeros')

8、特征图与感受野

输出的卷积层有时被称为 特征图 Feature Map ,因为它可以被视为一个输入映射到下一层的空间维度的转换器。在 CNN 中,对于某一层的任意元 x ,其 感受野 Receptive Field 是指在正向传播期间可能影响 x 计算的所有元素(来自所有先前层)。

感受野的覆盖率可能大于某层输入的实际区域大小。感受野的定义是卷积神经网络每一层输出的特征图上的像素点在输入图像上映射的区域大小。再通俗点的解释是,感受野是特征图上的一个点对应输入图上的区域。

由图可知,经过几个卷积层后,特征图逐渐变小,一个特征所表示的信息量变多,如 s_{3} 表示了 x_{1} 、x_{2} 、x_{3}  、x_{4}  、x_{5} 的信息。

9、全卷积网络

利用卷积神经网络进行图像分类或回归任务时,我们通常会在卷积层之后接上若干个全连接层,将卷积层产生的特征图映射成一个固定长度的特征向量。因为最终都期望得到整个输入图像属于哪类对象的概率值,如图 6-22 所示,AlexNet 的 ImageNet 模型输出一个 1000 维的向量表示输入图像属于每一类的概率(经过 softmax 归一化)。

与通常用于分类或回归任务的卷积神经网络不同,全卷积网络 Fully Convolutional Network 可以接收任意尺寸的输入图像,将上图中的 3 个全连接层改成卷积核尺寸为 1×1,通道数为向量长度的卷积层。然后,采用转置卷积运算对最后一个卷积层的特征图进行上采样,使其恢复到与输入图像相同的尺寸,从而可以对每个像素都产生一个预测,同时保留原始输入图像中的空间信息。接着在上采样的特征图上进行逐像素分类,最后逐个像素计算分类的损失,相当于每一个像素对应一个训练样本。这样整个网络都使用卷积层,没有全连接层,这也许就是全卷积网络名称的由来。该网络的输出类别预测与输入图像在像素级别上具有一一对应关系,其通道维度的输出为该位置对应像素的类别预测,如图 6-23 所示。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机字符集产生的历史与乱码

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益: 了解大厂经验拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我! 文章目录 一…

halcon 2D模板匹配 3D

一、概述 模板匹配常用于定位和查找,有很多的方式,halcon 中就有灰度匹配 、形状匹配、变形匹配、缩放匹配等,其实最常用的还是两种第一个就是灰度匹配、还有就是形状匹配 二、金字塔概述 网上有很多关于金字塔的解释,我这里直…

JCR一区 | Matlab实现TTAO-CNN-BiLSTM-MATT多特征分类预测

JCR一区 | Matlab实现TTAO-CNN-BiLSTM-MATT多特征分类预测 目录 JCR一区 | Matlab实现TTAO-CNN-BiLSTM-MATT多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现TTAO-CNN-BiLSTM-MATT三角拓扑聚合优化器优化双向长短期记忆神经网络融合多头注意力…

智慧园区能耗管控系统,3D可视化开发都需要哪些技术栈?

数据可视化: 数据可视化是将数据通过图表、图形、地图等可视化方式展示,使得数据更加直观、易于理解和分析。在智慧园区能耗管控系统中,可以使用各种图表库(如Echarts、Highcharts)和可视化工具(如Tableau…

【LeetCode:2391. 收集垃圾的最少总时间 + 二分】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

【强化学习-深度强化学习DRL】什么问题可以用DRL解决?条件:场景固定数据廉价

引言:深度强化学习适用于满足场景固定、数据廉价这两个要求的问题求解。本节对场景固定进行详细的论述。术语:深度强化学习(DRL) 条件一:场景固定(两个分布一致) 场景固定指的是,保…

美股市场恒生指数冲刺19000点关口 地产股大涨

查查配5月10日电(中新财经记者 谢艺观)5月10日,港股现强势行情,恒生指数盘中一度冲至18993.28点,距离19000点关口仅一步之遥。 美港通证券以其专业的服务和较低的管理费用在市场中受到不少关注。该平台提供了实盘交易、止盈止损、仓位控制等功能,旨在为投资者提供更为全面的投…

HNCTF-PWN

1.ez_pwn 直接看危险函数,不能溢出,只能覆盖ebp。 后面紧接的又是leave,ret 很明显是栈迁移,通过printf打印出ebp,通过偏移计算出栈地址。 通过gdb调试,偏移是0x38 以下是payload: from pwn import * #i…

通过单总线实现单片机之间的数据传输

单总线、没有时钟线的通信时,不能使用简单的高低电平来通信,因为接收方不知道此时发送的数据是第几位数据,容易造成错乱。 因此在使用一根线对外传输数据时,需要自定义一个通信协议,它至少要包含格式头数据&#xff0c…

二维数组 和 变长数组

在上一期的内容中,为诸君讲解到了一维数组,在一维数组的基础上,C语言中还有着多维数组,其中,比较典型且运用较为广泛的就是我们今天的主角——二维数组 一 . 二维数组的概念 我们把单个或者多个元素组成的数组定义为一…

springboot项目打包部署

springboot打包的前提条件jdk必须17以后不然本地运行不来(我用的jdk是22) 查看自己电脑jdk版本可以参考(完美解决Windows10下-更换JDK环境变量后,在cmd下执行仍java -version然出现原来版本的JDK的问题-CSDN博客) 1、…

uniapp音乐播放整理

一、前置知识点 1.1 音频组件控制-uni.createInnerAudioContext() 创建并返回内部 audio 上下文 innerAudioContext 对象。 主要用于当前音乐播放; 1.1.1 innerAudioContext属性 属性类型说明只读平台差异说明srcString音频的数据链接,用于直接播放…

学浪app的课程怎么导出来

在这个知识如星辰般璀璨的时代,学浪app汇聚了无数智慧的火花,点亮了求知者的前行之路。你是否曾在学浪的海洋中遨游,汲取知识的甘露,却渴望将那些珍贵的课程内容,如同宝藏一般,从数字的海洋中提取出来&…

PY32F403系列单片机,32位M4内核MCU,主频最高144MHZ

PY32F403系列单片机是基于Arm Cortex-M4核的32位通用微控制器产品。内置的FPU和DSP功能支持浮点运算和全部DSP指令。通过平衡成本,性能,功耗来获得更好的用户体验。 PY32F403单片机典型工作频率可达144MHZ,内置高速存储器,丰富的…

Python-VBA函数之旅-str函数

目录 一、str函数的常见应用场景 二、str函数使用注意事项 三、如何用好str函数? 1、str函数: 1-1、Python: 1-2、VBA: 2、推荐阅读: 个人主页: https://myelsa1024.blog.csdn.net/ 一、str函数的常…

【C -> Cpp】由C迈向Cpp (5)

标题:【C -> Cpp】由C迈向Cpp(5) 水墨不写bug (图片来源于网络) 不抵制失败,携手失败,迈向成功 正文开始: (一)深入理解构造函数 在之前的讲解中&#x…

安装Ununtu后常见问题(无法远程连接、root密码等)

安装Ununtu后常见问题(无法远程连接、root密码、无法ifconfig等) 提示:安装完Ununtu系统后会遇到一些常见的问题,本文一次洗解决 文章目录 安装Ununtu后常见问题(无法远程连接、root密码、无法ifconfig等)一…

Linux(Ubuntu24.04) 安装 MinIO

本文所使用的 Ubuntu 系统版本是 Ubuntu 24.04 ! # 1、下载 MinIO wget https://dl.min.io/server/minio/release/linux-amd64/minio# 2、添加可执行权限 chmod x minio# 3、导出环境变量,用于设置账号密码,我设置的账号和密码都是 minioadmin export MI…

PyQt5中的QtDesigner窗口

文章目录 1. 简介2. QtDesigner的MainWindow2.1 创建MainWindow2.2 添加组件2.3 预览2.4 查看对应的Python代码2.5 保存窗口并命名为login.ui,如下所示2.6对ui文件进行转换得到.py原件 3. 窗口常用属性及说明3.1 设置对象名称3.2 改变标题名字3.3 修改窗口大小 4. 更…

PyCharm 集成 Git

目录 1、配置 Git 忽略文件 2、定位Git 3、使用pycharm本地提交 3.1、初始化本地库 3.2、添加到暂存区 3.3、提交到本地库 3.4、切换版本 4、分支操作 4.1、创建分支 4.2、切换分支 4.3、合并分支 5、解决冲突 1、配置 Git 忽略文件 作用:与项目的实际…