深度学习——现代卷积神经网络(七)

深度卷积神经网络

学习表征

  1. 观察图像特征的提取⽅法。
  2. 在合理地复杂性前提下,特征应该由多个共同学习的神经⽹络层组成,每个层都有可学习的参数。

当年缺少数据和硬件支持

AlexNet

  1. AlexNet⽐相对较⼩的LeNet5要深得多。 AlexNet由⼋层组成:五个卷积层、两个全连接隐藏层和⼀个全连接输出层。
  2. AlexNet使⽤ReLU⽽不是sigmoid作为其激活函数。

模型设计

在AlexNet的第⼀层,卷积窗⼝的形状是11×11。由于ImageNet中⼤多数图像的宽和⾼⽐MNIST图像的多10倍以上,因此,需要⼀个更⼤的卷积窗⼝来捕获⽬标。第⼆层中的卷积窗⼝形状被缩减为5× 5,然后是3× 3。此外,在第⼀层、第⼆层和第五层卷积层之后,加⼊窗⼝形状为3× 3、步幅为2的最⼤汇聚层。⽽且, AlexNet的卷积通道数⽬是LeNet的10倍。

激活函数

AlexNet将sigmoid激活函数改为更简单的ReLU激活函数。

  1. ReLU激活函数的计算更简单
  2. 当使⽤不同的参数初始化⽅法时, ReLU激活函 数使训练模型更加容易。

容量控制

AlexNet通过暂退法(4.6节)控制全连接层的模型复杂度,⽽LeNet只使⽤了权重衰减。为了进⼀步扩充数据, AlexNet在训练时增加了⼤量的图像增强数据,如翻转、裁切和变⾊。这使得模型更健壮,更⼤的样本量有效地减少了过拟合。

使用块的网络(VGG)

经典的卷积神经网络基本组成部分:

  1. 带填充以保持分辨率的卷积层;
  2. ⾮线性激活函数,如ReLU;
  3. 汇聚层,如最⼤汇聚层。

而⼀个VGG块与之类似,由⼀系列卷积层组成,后⾯再加上⽤于空间下采样的最⼤汇聚层。

VGG块

import torch
import torch.nn as nn 
import d2l.torch as d2l
# 卷积层的数量num_convs、输⼊通道的数量in_channels 和输出通道的数量out_channels.
def Vgg_block(num_convs, in_channels, out_channels):layers = []for _ in range(num_convs):layers.append(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1))layers.append(nn.ReLU())in_channels = out_channelslayers.append(nn.MaxPool2d(kernel_size=2, stride=2))return nn.Sequential(*layers)

VGG网络

# 超参数变量conv_arch。该变量指定了每个VGG块⾥卷积层个数和输出通道数。
conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
in_channels = 1
def VGG(in_channels, conv_arch):conv_blks = []for (num_convs, out_channels) in conv_arch:conv_blks.append(Vgg_block(num_convs, in_channels, out_channels))in_channels = out_channelsnet = nn.Sequential(*conv_blks, nn.Flatten(),nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),nn.Linear(4096, 10))return netnet = VGG(in_channels, conv_arch)
net

网络中的网络(NiN)

LeNet、 AlexNet和VGG都有⼀个共同的设计模式:通过⼀系列的卷积层与汇聚层来提取空间结构特征;然后通过全连接层对特征的表征进⾏处理。 AlexNet和VGG对LeNet的改进主要在于如何扩⼤和加深这两个模块。** **
卷积层的输⼊和输出由四维张量组成,张量的每个轴分别对应样本、通道、⾼度和宽度。 NiN的想法是在每个像素位置(针对每个⾼度和宽度)应⽤⼀个全连接层 ,

如果我们将权重连接到每个空间位置,我们可以将其视为1 × 1卷积层 。从另⼀个⻆度看,即将空间维度中的每个像素视为单个样本,将通道维度视为不同特征(feature)。
NiN块以⼀个普通卷积层开始,后⾯是两个1 × 1的卷积层。这两个1 × 1卷积层充当带有ReLU激活函数的逐像素全连接层。

import torch 
import torch.nn as nn
import d2l.torch as d2ldef nin_block(in_channels, out_channels, kernel_size, strides, padding):return nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding),nn.ReLU(),nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU(),nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU())net = nn.Sequential(nin_block(20, 96, kernel_size=11, strides=4, padding=0),nn.MaxPool2d(3, stride=2),nin_block(96, 256, kernel_size=5, strides=1, padding=2),nn.MaxPool2d(3, stride=2),nin_block(256, 384, kernel_size=3, strides=1, padding=1),nn.MaxPool2d(3, stride=2),nn.Dropout(0.5),# 标签类别数是10nin_block(384, 10, kernel_size=3, strides=1, padding=1),nn.AdaptiveAvgPool2d((1, 1)),# 将四维的输出转成⼆维的输出,其形状为(批量⼤⼩,10)nn.Flatten())X = torch.rand(size=(16, 20, 224, 224))
for layer in net:X = layer(X)print(layer.__class__.__name__,'output shape:\t', X.shape)lr, num_epochs, batch_size = 0.1, 10, 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

含并行连结的网络

inception块

在GoogLeNet中,基本的卷积块被称为Inception块(Inception block)。

import torch
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2lclass Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):super(Inception, self).__init__(**kwargs)# 线路1,单1x1卷积层self.p1_1 = nn.Conv2d(in_channels, c1, kernel_size=1)# 线路2, 1x1卷积层后接3x3卷积层self.p2_1 = nn.Conv2d(in_channels, c2[0], kernel_size=1)self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)# 线路3, 1x1卷积层后接5x5卷积层self.p3_1 = nn.Conv2d(in_channels, c3[0], kernel_size=1)self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)# 线路4, 3x3最⼤汇聚层后接1x1卷积层self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)self.p4_2 = nn.Conv2d(in_channels, c4, kernel_size=1)def forward(self, x):p1 = F.relu(self.p1_1(x))p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))p4 = F.relu(self.p4_2(self.p4_1(x)))# 在通道维度上连结输出return torch.cat((p1, p2, p3, p4), dim=1)

GoogLeNet模型

批量规范化

训练深层神经⽹络是⼗分困难的,特别是在较短的时间内使他们收敛更加棘⼿。本节将介绍批量规范化(batch normalization),这是⼀种流⾏且有效的技术,可持续加速深层⽹络的收敛速度。再结合后面将介绍的残差块,批量规范化使得研究⼈员能够训练100层以上的⽹络。

、训练深层网络

为什么要批量规范化?

  • ⾸先,数据预处理的⽅式通常会对最终结果产⽣巨⼤影响。
  • 第⼆,对于典型的多层感知机或卷积神经⽹络。当我们训练时,中间层中的变量(例如,多层感知机中的仿射变换输出)可能具有更⼴的变化范围:不论是沿着从输⼊到输出的层,跨同⼀层中的单元,或是随着时间的推移,模型参数的随着训练更新变幻莫测。
  • 第三,更深层的⽹络很复杂,容易过拟合。这意味着正则化变得更加重要。
    批量规范化应⽤于单个可选层(也可以应⽤到所有层),其原理如下:在每次训练迭代中,我们⾸先规范化输⼊,即通过减去其均值并除以其标准差,其中两者均基于当前⼩批量处理。接下来,我们应⽤⽐例系数和⽐例偏移。正是由于这个基于批量统计的标准化,才有了批量规范化的名称。


    注意:我们在⽅差估计值中添加⼀个⼩的常量ϵ > 0,以确保我们永远不会尝试除以零,即使在经验⽅差估计值可能消失的情况下也是如此。估计值µ^Bσ^ B通过使⽤平均值和⽅差的噪声(noise)估计来抵消缩放问题。乍看起来,这种噪声是⼀个问题,⽽事实上它是有益的。
  • 第四,批量规范化层在”训练模式“(通过⼩批量统计数据规范化)和“预测模式”(通过数据集统计规范化)中的功能不同。在训练过程中,我们⽆法得知使⽤整个数据集来估计平均值和⽅差,所以只能根据每个⼩批次的平均值和⽅差不断训练模型。⽽在预测模式下,可以根据整个数据集精确计算批量规范化所需的平均值和⽅差。

、批量规范化层

批量规范化和其他层之间的⼀个关键区别是,由于批量规范化在完整的⼩批量上运⾏,因此我们
不能像以前在引⼊其他层时那样忽略批量⼤⼩。

我们可以分为两种不同情况进行讨论:全连接层和卷积层

全连接层

我们将批量规范化层置于全连接层中的仿射变换和激活函数之间。设全连接层的输⼊为x,权重参数和偏置参数分别为Wb,激活函数为ϕ,批量规范化的运算符为BN。那么,使⽤批量规范化的全连接层的输出的计算详情如下:

卷积层

对于卷积层,我们可以在卷积层之后和⾮线性激活函数之前应⽤批量规范化。 当卷积有多个输出通道
时,我们需要对这些通道的“每个”输出执⾏批量规范化,每个通道都有⾃⼰的拉伸(scale)和偏移(shif)参数,这两个参数都是标量。

代码实现

# 1. 导入库
import torch
from torch import nn
from d2l import torch as d2l# 2. 批量规范化实现def batch_norm(x, gamma, beta, moving_mean, moving_var, eps, momentum):# 通过is_grad_enabled来判断当前模式是训练模式还是预测模式if not torch.is_grad_enabled():# 如果是在预测模式下,直接使⽤传⼊的移动平均所得的均值和⽅差X_hat = (x - moving_mean) / torch.sqrt(moving_var + eps)else:assert len(x.shape) in (2, 4)if len(x.shape) == 2:mean = x.mean(dim = 0)var = ((x - mean) ** 2).mean(dim=0)else:# 使⽤⼆维卷积层的情况,计算通道维上(axis=1)的均值和⽅差。# 这⾥我们需要保持X的形状以便后⾯可以做⼴播运算mean = x.mean(dim=(0, 2, 3), keepdim=True)var = ((x - mean) ** 2).mean(dim=(0, 2, 3), keepdim=True)# 训练模式下,⽤当前的均值和⽅差做标准化X_hat = (x - mean) / torch.sqrt(var + eps)# 更新移动平均的均值和⽅差moving_mean = momentum * moving_mean + (1.0 - momentum) * meanmoving_var = momentum * moving_var + (1.0 - momentum) * varY = gamma * X_hat + beta # 缩放和移位return Y, moving_mean.data, moving_var.data

BatchNorm层

这个层将保持适当的参数:拉伸gamma和偏移beta,这两个参数将在训练过程中更新

# BatchNorm层实现
class BatchNorm(nn.Module):# num_features:完全连接层的输出数量或卷积层的输出通道数。# num_dims: 2表⽰完全连接层, 4表⽰卷积层def __init__(self, num_features, num_dims):super().__init__()if num_dims == 2:shape = (1, num_features)else:shape = (1, num_features, 1, 1)# 参与求梯度和迭代的拉伸和偏移参数,分别初始化成1和0self.gamma = nn.Parameter(torch.ones(shape))self.beta = nn.Parameter(torch.zeros(shape))# ⾮模型参数的变量初始化为0和1self.moving_mean = torch.zeros(shape)self.moving_var = torch.ones(shape)def forward(self, x):# 如果X不在内存上,将moving_mean和moving_var# 复制到X所在显存上if self.moving_mean.device != x.device:self.moving_mean = self.moving_mean.to(x.device)self.moving_var = self.moving_var.to(x.device)# 保存更新过的moving_mean和moving_varY, self.moving_mean, self.moving_var = batch_norm(x, self.gamma, self.beta, self.moving_mean,self.moving_var, eps=1e-5, momentum=0.9)return Y

使⽤批量规范化层的 LeNet

import torch.nn as nn 
import d2l.torch as d2l
import torch
net = nn.Sequential(nn.Conv2d(1, 6, kernel_size=5), BatchNorm(6, num_dims=4), nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(6, 16,kernel_size=5), BatchNorm(16, num_dims=4), nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2), nn.Flatten(),nn.Linear(16 * 4 * 4, 120),BatchNorm(120, num_dims=2), nn.Sigmoid(),nn.Linear(120, 84),BatchNorm(84, num_dims=2), nn.Sigmoid(), nn.Linear(84, 10))
lr, num_epochs, batch_size = 1.0, 30, 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())print(net[1].gamma.reshape((-1,)), net[1].beta.reshape((-1,)))

残差神经网络(ResNet)

对于深度神经⽹络,如果我们能将新添加的层训练成恒等映射(identity function) f(x) = x,新模型和原模型将同样有效。同时,由于新模型可能得出更优的解来拟合训练数据集,因此添加层似乎更容易降低训练误差。
残差⽹络的核⼼思想是:每个附加层都应该更容易地包含原始函数作为其元素之⼀。

⽣成两种类型的⽹络:⼀种是当use_1x1conv=False时,应⽤ReLU⾮线性函数之前,将输⼊添加到输出。另⼀种是当use_1x1conv=True时,添加通过1 × 1卷积调整通道和分辨率

、残差块实现

# 残差块
import torch
import torch.nn as nn 
import d2l.torch as d2l
import torch.nn.functional as Fclass Residual(nn.Module):def __init__(self, input_channels,num_channels, use_1x1_conv = False, strides = 1):super().__init__()self.conv1 = nn.Conv2d(input_channels, num_channels, kernel_size=3,stride=strides, padding = 1)self.bn1 = nn.BatchNorm2d(num_channels)self.conv2 = nn.Conv2d(num_channels, num_channels, kernel_size=3,  padding = 1)self.bn2 = nn.BatchNorm2d(num_channels)if use_1x1_conv:self.conv3 = nn.Conv2d(input_channels, num_channels,kernel_size=3, stride=strides, padding=1)else:self.conv3 = Nonedef forward(self, X):Y = F.relu(self.bn1(self.conv1(X)))Y = self.bn2(self.conv2(Y))if self.conv3:X = self.conv3(X)Y += Xreturn F.relu(Y)

残差神经网络模型

  • ResNet-18

import torch
import torch.nn as nn def res_block(input_channels, num_channels, num_residuals, first_block = False):blk = []for i in range(num_residuals):if i == 0 and not first_block:blk.append(Residual(input_channels, num_channels, use_1x1_conv=True, strides=2))else:blk.append(Residual(input_channels=input_channels, num_channels=num_channels))return blk# 1. 卷积层
b1 = nn.Sequential(nn.Conv2d(1, 64,kernel_size=7,stride=2, padding=3),nn.BatchNorm2d(64), nn.ReLU(),nn.AvgPool2d(kernel_size=3, stride=2, padding=1))
# 2. 残差层
b2 = nn.Sequential(*res_block(64,64, num_residuals=2, first_block=True))
b3 = nn.Sequential(*res_block(64,128, num_residuals=2))
b4 = nn.Sequential(*res_block(128,256, num_residuals=2))
b5 = nn.Sequential(*res_block(256,512, num_residuals=2))# 3. 汇聚层和全连接层
# ResNet-18
net = nn.Sequential(b1, b2, b3, b4, b5,nn.AdaptiveAvgPool2d((1,1)),nn.Flatten(), nn.Linear(512, 10))'''
每个模块有4个卷积层(不包括恒等映射的1 × 1卷积层)。
加上第⼀个7 × 7卷积层和最后⼀个全连接层,共
有18层。因此,这种模型通常被称为ResNet-18。
'''

查看在ResNet中不同模块的输入形状是怎么变化的

X = torch.rand(size=(1, 1, 224, 224))
for layer in net:X = layer(X)print(layer.__class__.__name__,'output shape:\t', X.shape)

:::color1
Sequential output shape: torch.Size([1, 64, 56, 56])
Sequential output shape: torch.Size([1, 64, 56, 56])
Sequential output shape: torch.Size([1, 128, 28, 28])
Sequential output shape: torch.Size([1, 256, 14, 14])
Sequential output shape: torch.Size([1, 512, 7, 7])
AdaptiveAvgPool2d output shape: torch.Size([1, 512, 1, 1])
Flatten output shape: torch.Size([1, 512])
Linear output shape: torch.Size([1, 10])

:::

模型训练

# 模型训练
lr, num_epochs, batch_size = 0.05, 10, 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费送源码:Java+ssm++MVC+HTML+CSS+MySQL springboot 社区医院信息管理系统的设计与实现 计算机毕业设计原创定制

摘 要 随着互联网趋势的到来,各行各业都在考虑利用互联网将自己推广出去,最好方式就是建立自己的互联网系统,并对其进行维护和管理。在现实运用中,应用软件的工作规则和开发步骤,采用Java技术建设社区医院信息管理系统…

Marin说PCB之POC电路layout设计仿真案例---06

我们书接上回啊,对于上面的出现原因我这个美女同事安娜说会不会你把POC电感下面的相邻两层的CUT_OUT的尺寸再去加大一些会不会变得更好呢?这个难道说是真的有用吗?小编我先自己算一卦看下结果。 本期文章我们就接着验证通过改善我们的单板POC…

简洁清爽epub 阅读器

Jane Reader 是一款现代化的 epub 阅读器,有简洁清爽,支持自动多栏、多主题、直排模式等,开发者想要提供「媲美于印刷书籍的阅读体验」 Jane Reader 目前提供以下功能: 支持 epub 电子书格式; 内置书库; 支…

TDesign:NavBar 导航栏

NavBar 导航栏 左图,右标 appBar: TDNavBar(padding: EdgeInsets.only(left: 0,right: 30.w), // 重写左右内边距centerTitle:false, // 不显示标题height: 45, // 高度titleWidget: TDImage( // 左图assetUrl: assets/img/logo.png,width: 147.w,height: 41.w,),ba…

javaFX.(蜜雪冰城点餐小程序)MySQL数据库

学习Java只有3个月,不喜勿喷 该小程序是用的MySQL数据库,编辑软件用的equals,为什么不用idea有提示因为主打一个纯手打 要源码私信 目录 javafx.小程序(蜜雪冰城点餐系统)简介 主体思路 思路讲解 用户登录 用户注册 忘记…

StarRocks:存算一体模式部署

目录 一、StarRocks 简介 二、StarRocks 架构 2.1 存算一体 2.2 存算分离 三、前期准备 3.1前提条件 3.2 集群规划 3.3 配置环境 3.4 准备部署文件 四、手动部署 4.1 部署FE节点 4.2 部署BE节点 4.3 部署CN节点(可选) 4.4 FE高可用…

【LeetCode】394、字符串解码

【LeetCode】394、字符串解码 文章目录 一、递归: 嵌套类问题1.1 递归: 嵌套类问题 二、多语言解法 一、递归: 嵌套类问题 1.1 递归: 嵌套类问题 // go func decodeString(s string) string {// 如果遇到 嵌套括号的情况, 则递归// 可能连续多位数字, 则 通过 cur cur * 10 …

厦门凯酷全科技有限公司短视频带货可靠吗?

在当今这个数字化时代,抖音作为短视频和直播带货的领军平台,已经吸引了无数商家的目光。而在这一片繁荣的电商蓝海中,厦门凯酷全科技有限公司(以下简称“凯酷全”)凭借其专业的团队、丰富的经验和创新的服务模式&#…

图书馆管理系统(三)基于jquery、ajax

任务3.4 借书还书页面 任务描述 这部分主要是制作借书还书的界面,这里我分别制作了两个网页分别用来借书和还书。此页面,也是通过获取books.txt内容然后添加到表格中,但是借还的操作没有添加到后端中去,只是一个简单的前端操作。…

RabbitMQ消息可靠性保证机制7--可靠性分析-rabbitmq_tracing插件

rabbitmq_tracing插件 rabbitmq_tracing插件相当于Firehose的GUI版本,它同样能跟踪RabbitMQ中消息的注入流出情况。rabbitmq_tracing插件同样会对流入流出的消息进行封装,然后将封装后的消息日志存入相应的trace文件中。 # 开启插件 rabbitmq-plugins …

如何重新设置VSCode的密钥环密码?

故障现象: 忘记了Vscode的这个密码: Enter password to unlock An application wants access to the keyring “Default ke... Password: The unlock password was incorrect Cancel Unlock 解决办法: 1.任意terminal下,输入如下…

XILINX平台LINUX下高速ADC08060驱动

前置调研 原理图 AXI-FULL时序 由于项目需要实时性高,采用AXI-FULL接口ADC IP作为master端写入DDR中 引用: AXI_02 AXI4总线简介(协议、时序)_axi4总线时序-CSDN博客 AXI总线的访问 在ARM架构中,访问I/O地址通常通…

在uniapp Vue3版本中如何解决webH5网页浏览器跨域的问题

问题复现 uniapp项目在浏览器运行,有可能调用某些接口会出现跨域问题,报错如下图所示: 什么是跨域? 存在跨域问题的原因是因为浏览器的同源策略,也就是说前端无法直接发起跨域请求。同源策略是一个基础的安全策略&a…

搭建MPI/CUDA开发环境

本文记录MPI/CUDA开发环境搭建过程。 一、Linux 2.1 环境 操作系统Ubuntu 22.04.4 LTSVS Code1.92.1Git2.34.1GCC11.4.0CMake3.22.1 2.2 VS Code 下载VS Code,然后安装以下插件, Task Explorer Output Colorizer Git Extension Pack Git Graph Remot…

Swin transformer 论文阅读记录 代码分析

该篇文章,是我解析 Swin transformer 论文原理(结合pytorch版本代码)所记,图片来源于源paper或其他相应博客。 代码也非原始代码,而是从代码里摘出来的片段,配上简单数据,以便理解。 当然&…

Vulnhub靶场Nginx解析漏洞复现

一.nginx_parsing 原理:这个解析漏洞其实是PHP CGI的漏洞,在PHP的配置⽂件中有⼀个关键的选项cgi.fix_pathinfo默认是开启的,当URL中有不存在的⽂件,PHP就会向前递归解析。在⼀个⽂件/xx.jpg后⾯加上/.php会将 /xx.jpg/xx.php 解…

P1305 新二叉树

题目: P1305 新二叉树 - 洛谷 | 计算机科学教育新生态 题目描述 输入一串二叉树,输出其前序遍历。 输入格式 第一行为二叉树的节点数 n。(1≤n≤26) 后面 n 行,每一个字母为节点,后两个字母分别为其左右儿子。特别地&#x…

jvm字节码中方法的结构

“-Xss”这一名称并没有一个特定的“为什么”来解释其命名,它更多是JVM(Java虚拟机)配置参数中的一个约定俗成的标识。在JVM中,有多个配置参数用于调整和优化Java应用程序的性能,这些参数通常以一个短横线“-”开头&am…

熟悉u8g2图形库C语言函数

前言: 前面我们已经成功移植了U8g2的图形库(0.96寸OLED):手把手移植U8g2图形库,这个文章主要熟悉u8g2图形库的常用C语言函数!需要移植的资料的可以关注一波评论区评论,我看到了就会给你发哦&am…

MobaXterm 连接不上VMware 的Ubuntu 虚拟机

想在window11的笔记本上通过VMWare安装Ubuntu操作系统,但是在两个桌面见来回切换,十分的麻烦,于是通过远程服务访问客户端软件MateXterm来访问虚拟机的Linux系统,但是从CSDN上搜到的教程都没有成功,于是,尝…