Pytorch的讲解及实战·MNIST数据集手写数字识别

目录

一、前言与pytorch的下载

1、前言

2、下载pytorch

①创建虚拟环境

②下载pytorch(cpu版)

③测试pytorch是否下载成功

④使用jupyter notebook 但是使用不了torch的解决方法

二、pytorch的使用

1、Tensor的数据类型

①torch.FloatTensor

②torch.IntTensor

③torch.rand

④torch.randn

⑤torch.range

⑥torch.zeros

⑦torch.ones

2、Tensor的运算

①torch.abs

②torch.add

③torch.clamp

④torch.div

⑤torch.mul

⑥torch.pow

⑦torch.mm

3、tensor的自动梯度

4、torch搭建神经网络层次

①torch.nn.Sequential:

②torch.nn.Conv2d

③ torch.nn.MaxPool2d

④ torch.nn.Dropout

⑤torch.nn.Linear

⑥torch.nn.ReLU

⑦torch.optim

5、损失函数

①torch.nn.MSELoss

②torch.nn.L1Loss

③torch.nn.CrossEntropyLoss

6、torchvision.transforms

①torchvision.transforms.Resize

②torchvision.transforms.Scale

③torchvision.transforms.CenterCrop

④torchvision.transforms.RandomCrop

⑤torchvision.transforms.RandomHorizontalFlip

⑥torchvision.transforms.RandomVerticalFlip

⑦torchvision.transforms.ToTensor

⑧torchvision.transforms.ToPILImage

⑨torchvision.transforms.Normalize

三、实际操作

1、导入库

2、导入pytorch中的mnist数据集

3、展示数据集规模及些许图片

4、构建模型

5、训练

6、测试


一、前言与pytorch的下载

1、前言

对于神经网络的相关知识大家可以先学习学习小编的这篇博客:

数学建模之神经网络相关理论知识_神经网络误差建模-CSDN博客

2、下载pytorch

①创建虚拟环境

打开anaconda prompt,输入以下指令,创建虚拟环境

conda create -n pytorch #虚拟环境名字为pytorch
conda activate pytorch  #激活pytorch环境

②下载pytorch(cpu版)

进入pytorch官网https://pytorch.org/

复制Run this Command右边的这句话,再pytorch环境下运行,不过这样下载太慢了,建议换成清华镜像源或者豆瓣镜像源下载

③测试pytorch是否下载成功

在终端上输入:

python
import torch
torch.__version__

④使用jupyter notebook 但是使用不了torch的解决方法

conda install nb_conda

随后jupyter notebook的目录变成这样了,多一个“conda”

二、pytorch的使用

1、Tensor的数据类型

①torch.FloatTensor

用于生成数据类型为float型的tensor

②torch.IntTensor

torch.IntTensor用于生成数据类型为整型的Tensor

③torch.rand

用于生成数据类型为浮点型且维度指定的随机Tensor,和在NumPy中使用numpy.rand生成随机数的方法类似,随机生成的浮点数据在0~1区间均匀分布。

④torch.randn

用于生成数据类型为浮点型且维度指定的随机Tensor,和在NumPy中使用numpy.randn生成随机数的方法类似,随机生成的浮点数据符合标准正太分布。

⑤torch.range

用于生成数据类型为浮点型且起始范围和结束范围的Tensor,所以传递给torch.range的参数有三个,分别为起始值,结束值,步长,其中步长用于指定从起始值到结束值每步的数据间隔。

⑥torch.zeros

用于生成数据类型为浮点型且维度指定的Tensor,不过这个浮点型的Tensor中的元素值全部为0。

⑦torch.ones

用于生成数据类型为浮点型且维度指定的Tensor,不过这个浮点型的Tensor中的元素值全部为1。

2、Tensor的运算

①torch.abs

将参数传递到torch.abs后返回输入参数的绝对值作为输出,输入参数必须是一个Tensor数据类型的变量。

②torch.add

将参数传递到 torch.add后返回输入参数的求和结 果作为输出,输入参数既可以全部是Tensor数据类型的变量,也可以一 个是Tensor数据类型的变量,另一个是标量。

③torch.clamp

对输入参数按照自定义的范围进行裁剪,最后将参数裁剪的结果作为输出。所以输入参数一共有三个,分别是需要进行裁剪的Tensor数据类型的变量、裁剪的上边界和裁剪的下边界,具体的裁剪过程是:使用变量中的每个元素分别和裁剪的上边界及裁剪的下边界的值进行比较,如果元素的值小于裁剪的下边界的值,该元素就被重写成裁剪的下边界的值;同理,如果元素的值大于裁剪的上边界的值,该元素就被重写成裁剪的上边界。

④torch.div

将参数传递到torch.div后返回输入参数的求商结果作为输出,同样,参与运算的参数可以全部是Tensor数据类型的变量, 也可以是Tensor数据类型的变量和标量的组合。

⑤torch.mul

将参数传递到 torch.mul后返回输入参数求积的结 果作为输出,参与运算的参数可以全部是Tensor数据类型的变量,也可 以是Tensor数据类型的变量和标量的组合。

⑥torch.pow

将参数传递到torch.pow后返回输入参数的求幂结果作为输出,参与运算的参数可以全部是Tensor数据类型的变量,也可以是Tensor数据类型的变量和标量(几次方)的组合。

⑦torch.mm

将参数传递到 torch.mm后返回输入参数的求积结果作为输出,不过这个求积的方式和之前的torch.mul运算方式不太一样,torch.mm运用矩阵之间的乘法规则进行计算,所以被传入的参数会 被当作矩阵进行处理,参数的维度自然也要满足矩阵乘法的前提条件, 即前一个矩阵的行数必须和后一个矩阵的列数相等,否则不能进行计算。

3、tensor的自动梯度

torch.autograd包的主要功能是完成神经网络后向传播中的链式求 导,手动实现链式求导的代码会给我们带来很大的困扰,而 torch.autograd 包中丰富的类减少了这些不必要的麻烦。实现自动梯度功 能的过程大致为:先通过输入的Tensor数据类型的变量在神经网络的前 向传播过程中生成一张计算图,然后根据这个计算图和输出结果准确计 算出每个参数需要更新的梯度,并通过完成后向传播完成对参数的梯度更新。

在实践中完成自动梯度需要用到torch.autograd包中的Variable类对 我们定义的Tensor数据类型变量进行封装,在封装后,计算图中的各个节点就是一个Variable对象,这样才能应用自动梯度的功能。

4、torch搭建神经网络层次

①torch.nn.Sequential:

Sequential类是torch.nn中的一种序列容器,通过在容器中嵌套各种实现神经网络中具体功能相关的类,来完成对神经网络模型的搭建,并且参数会按照我们定义好的序列自动传递下去。我们可以将嵌套在容器中的各个部分看作各种不同的模块,这些模块可以自由组合。模块的加入 般有两种方式 种是 在以上代码中使用的直接嵌套,另种是以Orderdict 有序字典的方式进行传入,这两种方式的唯一的区别是,使用Orderdict搭建的模型的每个模块都有自定义的名字而Sequential默认使用从开始的数字序列作为每个模块的名字。

②torch.nn.Conv2d

用于搭建卷积神经网络的卷积层,主要参数是:输入通道数、输出通道数、卷积核大小、卷积核移动步长和padding的值(用于对边界像素的填充)

③ torch.nn.MaxPool2d

实现卷积神经网络的最大池化层,主要参数是:池化窗口的大小,池化窗口移动步长和padding的值。

④ torch.nn.Dropout

用于防止卷积神经网络在训练过程中发生过拟合,原理是以一定的随机概率将卷积神经网络模型的部分参数归零,以达到减少相邻两层神经连接的目的。

⑤torch.nn.Linear

torch.nn.Linear类用于定义模型的线性层, 即完成前面提到的不同的层之间的线性变换。torch.nn.Linear类接收的参 数有三个,分别是输入特征数、输出特征数和是否使用偏置,设置是否 使用偏置的参数是一个布尔值,默认为True,即使用偏置。在实际使用 的过程中,我们只需将输入的特征数和输出的特征数传递给 torch.nn.Linear类,就会自动生成对应维度的权重参数和偏置,对于生成 的权重参数和偏置,我们的模型默认使用了一种比之前的简单随机方式 更好的参数初始化方法。

⑥torch.nn.ReLU

torch.nn.ReLU类属于非线性激活分类,在定义时默认不需要传入参数。当然,在 torch.nn包中还有许多非线性激活 函数类可供选择,比如之前讲到的PReLU、LeakyReLU、Tanh、 Sigmoid、Softmax等。

⑦torch.optim

pytorch的torch.optim包中提供了非常多的可实现参数自动优化的类,比如SGD、AdaGrad、RMSProp、Adam等, 这些类都可以被直接调用,使用起来也非常方便。(例如:torch.optim.Adam类中输入的是被优化的参数和学习速率的初始值,如果没有输入学习速率的初始值,那么默认使用0.001 这个值。因为我们需要优化的是模型中的全部参数,所以传递给 torch.optim.Adam类的参数是models.parameters)

5、损失函数

没必要弄清楚下面集中损失函数到底是怎么构建的,只需要知道损失函数是什么就行了,可以看这篇博客了解一下:

损失函数(lossfunction)的全面介绍(简单易懂版)-CSDN博客

①torch.nn.MSELoss

torch.nn.MSELoss类使用均方误差函数对损失值进行计算,在定义类的对象时不用传入任何参数,但在使用实例 时需要输入两个维度一样的参数方可进行计算。

②torch.nn.L1Loss

torch.nn.L1Loss类使用平均绝对误差函数对 损失值进行计算,同样,在定义类的对象时不用传入任何参数,但在使 用实例时需要输入两个维度一样的参数进行计算。

③torch.nn.CrossEntropyLoss

torch.nn.CrossEntropyLoss类用 于计算交叉熵,在定义类的对象时不用传入任何参数,在使用实例时需要输入两个满足交叉熵的计算条件的参数

6、torchvision.transforms

①torchvision.transforms.Resize

用于对载入的图片数据按我 们需求的大小进行缩放。传递给这个类的参数可以是一个整型数据,也 可以是一个类似于(h,w)的序列,其中,h代表高度,w代表宽度,但 是如果使用的是一个整型数据,那么表示缩放的宽度和高度都是这个整 型数据的值。

②torchvision.transforms.Scale

用于对载入的图片数据按我们 需求的大小进行缩放,用法和torchvision.transforms.Resize类似。

③torchvision.transforms.CenterCrop

用于对载入的图片以图 片中心为参考点,按我们需要的大小进行裁剪。传递给这个类的参数可 以是一个整型数据,也可以是一个类似于(h,w)的序列。

④torchvision.transforms.RandomCrop

用于对载入的图片按我们需要的大小进行随机裁剪。传递给这个类的参数可以是一个整型数据,也可以是一个类似于(h,w)的序列。

⑤torchvision.transforms.RandomHorizontalFlip

用于对载入的图片按随机概率进行水平翻转。我们可以通过传递给这个类的参数自 定义随机概率,如果没有定义,则使用默认的概率值0.5。

⑥torchvision.transforms.RandomVerticalFlip

用于对载入的图片按随机概率进行垂直翻转。我们可以通过传递给这个类的参数自定义随机概率,如果没有定义,则使用默认的概率值0.5。

⑦torchvision.transforms.ToTensor

用于对载入的图片数据进行类型转换,将之前构成PIL图片的数据转换成Tensor数据类型的变量,让PyTorch能够对其进行计算和处理。

⑧torchvision.transforms.ToPILImage

用于将Tensor变量的数据转换成PIL图片数据,主要是为了方便图片内容的显示。

⑨torchvision.transforms.Normalize

用均值和标准差归一化张量图像,一般将std与mean均设置为[0.5,0.5,0.5]

三、实际操作

1、导入库

import torch 
from torchvision import datasets, transforms 
from torch.autograd import Variable
import torchvision
import matplotlib.pyplot as plt

2、导入pytorch中的mnist数据集

transform = transforms.Compose([
     transforms.ToTensor(),
     transforms.Lambda(lambda x: x.repeat(3,1,1)),
     transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))
 ])   
#ToTensor()能够把灰度范围从0-255变换到0-1之间,
# 而后面的transform.Normalize()则把0-1变换到(-1,1).
# 具体地说,对每个通道而言,Normalize执行以下操作:
# image=(image-mean)/std
# 其中mean和std分别通过(0.5,0.5,0.5)和(0.5,0.5,0.5)进行指定。原来的0-1最小值0则变成(0-#0.5)/0.5=-1,而最大值1则变成(1-0.5)/0.5=1.
data_train=datasets.MNIST(root="D:/jupyter_notebook/pytorch/train/",
                          train =True,
                          transform = transform,
                          download = True
                         )
data_test=datasets.MNIST(root="D:/jupyter_notebook/pytorch/test/",
                          train =False,
                          transform = transform,
                            download=True
                        )
data_loader_train =torch.utils.data.DataLoader(dataset = data_train,
                                         batch_size = 64,
                                         shuffle = True #打乱数据
                                         )
data_loader_test =torch.utils.data.DataLoader(dataset = data_test,
                                         batch_size = 64,
                                         shuffle = True #打乱数据
                                         )

3、展示数据集规模及些许图片

images,labels = next(iter(data_loader_train))
img = torchvision.utils.make_grid(images)

img = img.numpy().transpose(1,2,0)
std = [0.5,0.5,0.5]
mean = [0.5,0.5,0.5]
img = img*std + mean
print([labels[i] for i in range(64)] )
plt.imshow(img)
#展示数据集与测试集大小
print("train_data:",data_train.train_data.size())
print("train_labels:",data_train.train_labels.size())
print("test_data:",data_test.test_data.size())
print("test_labels:",data_test.test_labels.size())

规模大小如下图:

4、构建模型

class Model(torch.nn.Module): 
    def __init__ (self): 
        super(Model , self).__init__ () 
        self.convl=torch.nn.Sequential( 
            torch.nn.Conv2d (3,64,kernel_size=3,stride=1,padding=1) , 
            torch.nn.ReLU(), 
            torch.nn.Conv2d(64,128,kernel_size=3, stride=1,padding=1), 
            torch.nn.ReLU() , 
            torch.nn.MaxPool2d(stride=2,kernel_size=2)) 
        self.dense=torch.nn.Sequential( 
            torch.nn.Linear(14*14*128,1024), 
            torch.nn.ReLU(),
            torch.nn.Dropout(p= 0.5), 
            torch.nn.Linear(1024, 10)) 
    def forward(self, x) : 
        x = self.convl(x) 
        x = x . view(-1 , 14*14*128) 
        x = self. dense(x) 
        return x

model = Model() 
cost= torch.nn.CrossEntropyLoss() 
optimizer = torch.optim.Adam(model.parameters())
print(model)

该神经网络结构如下图:

为什么这样构建?我们来梳理一下:

先看conv1序列:

(0)conv2d卷积层用于特征提取,用一个模板去图像上寻找与它相似的区域,与卷积核模式越相似,激活值越高,从而实现特征提取

(1)激活函数对特征进行非线性变换,赋予多层神经网络具有深度的意义

(2)、(3)与上面类似

(4)池化层:经过池化后的图像基本上没什么差别,但是图像的尺寸减少了一半, 所以池化层是可以帮助我们剔除一些冗余像素或减少后面计算量。

再看dense序列

(0)Linear层即全连接层,起到概括图片局部高级特征的作用,输入一个25088*1的列向量,输出一个1024*1的列向量,可以这么理解它的作用:例如7可以拆分为上部分的“-”以及下部分的“1”,2可以拆分为上部分的弧与下部分的“-”,根据经过conv1处理后的图片,判断出图片有无这1024个局部高级特征,例如短横、小弯曲等等

(1)激活函数对特征进行非线性变换,赋予多层神经网络具有深度的意义

(2)Dropout用于防止卷积神经网络在训练过程中发生过拟合,原理是以一定的随机概率将卷积神经网络模型的部分参数归零,以达到减少相邻两层神经连接的目的

(3)Linear层:输入一个1024*1的列向量,输出一个10*1的列向量,分别代表了利用1024个局部高级特征,测算出训练或者测试时的图片对应数字0、1、2、3、4、5、6、7、8、9共十个数字下的得分函数,分值越高,可能性越大,那么需要左乘一个10*1024的权重矩阵。

5、训练

n_epochs = 5
for epoch in range (n_epochs):
    runnig_loss = 0.0
    running_correct = 0.0
    print("Epoch {}/{}".format(epoch,n_epochs))
    print("-"*10)
    i=0
    for data in data_loader_train:
        i=i+1
        X_train, y_train = data
        X_train, y_train = Variable(X_train), Variable(y_train)
        outputs = model(X_train)
        _,pred = torch.max(outputs.data, 1)
        optimizer.zero_grad()
        loss = cost(outputs, y_train)
        loss.backward()
        optimizer.step()
        runnnig_loss += loss.item()
        running_correct += torch.sum(pred == y_train.data)
        print("times:{}".format(i))
        
    testing_correct = 0
    for data in data_loader_test:
        X_test, y_test = data
        X_test, y_test = Variable(X_test), Variable(y_test)
        outputs = model(X_test)
        _, pred = torch.max(outputs.data,1)
        testing_correct += torch.sum(pred == y_test.data)

    print("Loss is:{:.4f},Train Accuracy is:{:.4f}%, Test Accuracy is:{:.4f}".format(runnig_loss/len(data_train),100*running_correct/len(data_train),100*testing_correct/len(data_test)))
        
        

第五个epoch训练结果如图:

准确率还有98.7%,属实是不错了

6、测试

data2_loader_test= torch.utils.data.DataLoader(dataset=data_test, 
                                                batch_size = 4 , 
                                                shuffle = True)
X_test2, y_test2= next (iter(data2_loader_test)) 
inputs = Variable(X_test2) 
pred = model(inputs) 
_,pred = torch.max(pred, 1) 
print ( "Predict Label is :",[i for i in pred.data]) 
print ("Real Label is :", [ i for i in y_test2]) 
img = torchvision.utils.make_grid(X_test2) 
img = img.numpy().transpose(1,2,0) 
std= [0.5,0.5,0.5] 
mean = [0.5,0.5,0.5] 
img = img*std+mean
plt.imshow (img)

测试结果如下图:

好的,本实验到此结束啦,实验的目的从来不只是为了识别这么几个数字,更重要的是,利用这个实验学会搭建出一个完整的神经网络,了解各个层的作用,了解pytorch各个函数的实际用途

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

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

相关文章

2023年,写博客带给我的收获与成长

文章目录 前言写博客的心路历程膜拜写博客大佬博客大佬带来的诱惑尝试写博客坚持写博客 决定写博客的原因2023年写博客的成就博客的创作粉丝的增长博客专家成就商务合作 2024年对技术写作的展望 前言 没错,我就是那个考试睡大觉、作文空白交卷的王二蛋。面对写作&a…

在matlab中对hsv进行均匀量化和非均匀量化

首先,进行非均匀量化,H,S,V三通道分别量化为16,4,4级,返回一个向量。量化依据如下表: function vec getHsvHist(Image) [M,N,O] size(Image); if O~ 3error(3 components are needed for histogram); end [h,s,v] rgb2hsv(Imag…

启明智显开源项目分享|基于Model 3c芯片的86中控面板ZX3D95CM20S-V11项目软硬件全开源

前言: 本文为4寸 480*480 RGB接口IPS全面触屏的86中控面板(RT-ThreadLVGL)软硬件开源干货内容,该项目是综合性非常强的RTOS系列项目!项目主控芯片使用 Model 3c,整体实现了简化版本的86中控面板的功能需求…

交换域系数的选择:图像处理与编码的关键策略

在图像处理和编码领域,选择适当的交换域系数对于实现高效的图像处理和编码至关重要。交换域系数是指在特定的数学变换下产生的频域系数。通过选择合适的交换域系数,可以实现图像的压缩、增强和重构。本文将深入探讨交换域系数的选择在图像处理和编码中的…

HPCC:高精度拥塞控制

HPCC:高精度拥塞控制 文章目录 HPCC:高精度拥塞控制摘要1 引言1.1 背景1.2 现有CC的局限性1.3 HPCC的提出 2 研究动机2.1 大型RDMA部署2.2 RDMA目标2.3 当前RDMA CC中的权衡DCQCNTIMELY 2.4 下一代高速CC 3 技术方案3.1 INT3.2 HPCC设计3.3 HPPC的参数 4…

改进YOLO系列 | YOLOv5/v7 引入高效的混合特征编码器 AIFI

论文地址:https://arxiv.org/abs/2304.08069 代码地址:https://github.com/PaddlePaddle/PaddleDetection 中文翻译:https://blog.csdn.net/weixin_43694096/article/details/131353118 注意!这个模块需要 torch>=1.9 才能使用 源代码 import torch import torch.nn …

深入探究Protostuff枚举类型的序列化

背景: 有一天突然被一个群组排查线上问题,说是一个场景划线价和商品原价一模一样。看到问题时,我的内心毫无波澜,因为经常处理线上类似的问题,但了解业务后发现是上个版本经我手对接的新客弹窗商品算价,内心…

C# MVC +Layui侧边导航栏的收缩及展开

目录 1、头部代码 2、侧边栏&#xff08;例子只写了一级导航&#xff0c;需要多级可自行添加&#xff09; 3、body内容填充 4、 JS 1、头部代码 <div class"layui-layout layui-layout-admin"> <div class"layui-header"> …

MySQL 核心模块揭秘 |《发刊词》

1. 为什么要写专栏&#xff1f; 我还在做业务系统研发的时候&#xff0c;有一段时间&#xff0c;系统不稳定&#xff0c;慢 SQL 很多。我们团队花了很长时间持续优化 SQL。 我们有一个表格&#xff0c;从慢查询日志里整理出了很多慢 SQL。其中一些 SQL&#xff0c;按照我们的…

大华NVR和IPC通过主动注册协议方式接入AS-V1000视频监控平台的步骤

最近有人经常用到有的型号的大华网路摄像机&#xff0c;不支持国标GB28181标准&#xff0c;问我们能否接入到在公网的AS-V1000平台 &#xff1f; 我们早期就开发了大华的主动注册协议SDK&#xff0c;能够支持大华的NVR和IPC接入到AS-V1000平台。 今天就直接讲解如何一步步的把局…

人工智能 机器学习 深度学习:概念,关系,及区别说明

如果过去几年&#xff0c;您读过科技主题的文章&#xff0c;您可能会遇到一些新词汇&#xff0c;如人工智能&#xff08;Artificial Intelligence&#xff09;、机器学习&#xff08;Machine Learning&#xff09;和深度学习&#xff08;Deep Learning&#xff09;等。这三个词…

关于使用Selenium获取网页控制台的数据

背景&#xff1a; 需要获取网页的控制台的数据&#xff0c;如下图 在此文章将使用到 Pycharm 和 Selenium4 Pycharm安装 Selenium安装 from selenium import webdriver from selenium.webdriver.common.by import By import time# 创建浏览器对象 browser webdriver.Chro…

普中STM32-PZ6806L开发板(使用过程中的问题收集)

Keil使用ST-Link 报错 Internal command error 描述: 在某一次使用过程中&#xff0c;前面都是正常使用, Keil在烧录时报错Internal command error, 试了网上的诸多方式, 例如 升级固件;ST-Link Utility 清除;Keil升级到最新版本;甚至笔者板子的Micro头也换了&#xff0c;因为坏…

docker学习笔记02-安装mysql

1.安装mysql8 下载MySQL镜像 docker pull mysql:8.0创建并启动容器 docker run -itd --name mysqltest -p 9999:3306 -e MYSQL_ROOT_PASSWORD123456 mysql其中-it是交互界面 -d是后台执行 -name 指定容器名称 -p指定映射端口 -e设置环境变量 最后mysql是镜像名或者用镜像id如…

消防数据监测可视化大屏:守护城市安全的智慧之眼

在数字化时代&#xff0c;数据已经成为决策的关键。特别是在消防领域&#xff0c;快速、准确的数据分析对于及时应对火情、挽救生命财产具有不可估量的价值。为此&#xff0c;消防数据监测可视化大屏应运而生&#xff0c;成为城市安全的守护者。 一、什么是消防数据监测可视化大…

Qt 中使用 MySQL 数据库保姆级教程(下)

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 上篇中我们安装好了 MySQL 数据库和 Navicat 软件&#xff0c;下面在 Qt 中尝试使用数据库 1. 在 Qt 中连接 MySQL 数据库&#…

VuePress、VuePress-theme-hope 搭建个人博客 1【快速上手】 —— 防止踩坑篇

vuePress官网地址 &#x1f449; 首页 | VuePress 手动安装 这一章节会帮助你从头搭建一个简单的 VuePress 文档网站。如果你想在一个现有项目中使用 VuePress 管理文档&#xff0c;从步骤 3 开始。 步骤 1: 创建并进入一个新目录 mkdir vuepress-starter cd vuepress-star…

Unity 代码控制Text自适应文本高度

在使用代码给Text赋值时&#xff0c;且文本有多段&#xff0c;并需要根据实际文本高度适配Text组件的高度时&#xff0c;可以使用以下方法&#xff1a; //Text文本 public TextMeshProUGUI text;void Start() {//代码赋值文本text.text "好!\n很好!\n非常好!";//获…

加强->servlet->tomcat

0什么是servlet jsp也是servlet 细细体会 Servlet 是 JavaEE 的规范之一&#xff0c;通俗的来说就是 Java 接口&#xff0c;将来我们可以定义 Java 类来实现这个接口&#xff0c;并由 Web 服务器运行 Servlet &#xff0c;所以 TomCat 又被称作 Servlet 容器。 Servlet 提供了…

ebay如何发货到国外?ebay发货规则是什么?——站斧浏览器

​ebay如何发货到国外&#xff1f; 对于卖家来说&#xff0c;在eBay上向海外买家发货可能会面临一些额外的挑战。以下是一些建议&#xff0c;帮助卖家顺利地将商品发货给海外买家&#xff1a; 1、选择合适的物流服务&#xff1a;eBay合作的物流服务通常提供可靠和经济实惠的国…