神经网络的搭建与各层分析
为什么去西藏的人都会感觉很治愈
拉萨的老中医是这么说的
缺氧脑子短路,很多事想不起来,就会感觉很幸福
一、卷积层
解释:卷积层通过卷积操作对输入数据进行处理。它使用一组可学习的滤波器(也称为卷积核或特征检测器),将滤波器与输入数据进行逐元素的乘法累加操作,从而生成输出特征图。这种滤波器的操作类似于图像处理中的卷积操作,因此得名卷积层。
主要作用:
-
特征提取:卷积层通过滤波器的卷积操作,可以有效地提取输入数据中的局部特征。滤波器可以学习到不同的特征,例如边缘、纹理、形状等,这些特征对于图像识别和分类等任务非常重要。
-
参数共享:卷积层的滤波器在整个输入数据上共享参数。这意味着在不同位置上使用相同的滤波器,从而减少了需要学习的参数数量。这种参数共享的特性使得卷积层具有一定的平移不变性,即对于输入数据的平移操作具有不变性。
-
减少参数数量:相比全连接层(每个神经元与上一层的所有神经元相连),卷积层的参数数量较少。这是因为卷积层的滤波器在空间上共享参数,并且每个滤波器只与输入数据的局部区域进行卷积操作。这种参数共享和局部连接的方式大大减少了需要学习的参数数量,提高了模型的效率和泛化能力。
-
空间结构保持:卷积层在进行卷积操作时,保持了输入数据的空间结构。这意味着输出特征图的每个元素对应于输入数据的相应局部区域,从而保留了输入数据的空间信息。这对于图像处理任务非常重要,因为图像中的相邻像素之间存在一定的关联性。
使用示例:
代码示例:
import torch
import torch.nn.functional as F# 模拟图像
input = torch.tensor([[1, 2, 0, 3, 1],[0, 1, 2, 3, 1],[1, 2, 1, 0, 0],[5, 2, 3, 1, 1],[2, 1, 0, 1, 1]])
# 模拟卷积核
kernal = torch.tensor([[1, 2, 1],[0, 1, 0],[2, 1, 0]])# 参数结构转化
input = torch.reshape(input, (1, 1, 5, 5))
kernal = torch.reshape(kernal, (1, 1, 3, 3))print(input.shape)
print(kernal.shape)# 输入经过卷积操作
output = F.conv2d(input, kernal, stride=2, padding=1)
print(output)
输出
torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[ 1, 4, 8],[ 7, 16, 8],[14, 9, 4]]]])
图片数据集经过卷积层输出:
import torch
import torchvision
from torch.utils.data import DataLoader
from torch.nn import Conv2d
from torch import nn
from torch.utils.tensorboard import SummaryWriter# 加载数据集并加载到神经网络中
dataset = torchvision.datasets.CIFAR10("./cifar10", train=False, transform=torchvision.transforms.ToTensor(),download=False)
dataloader = DataLoader(dataset, batch_size=64)class Lh(nn.Module):def __init__(self):super(Lh, self).__init__()self.conv1 = Conv2d(3, 6, 3, 1)def forward(self, x):x = self.conv1(x)return xlh = Lh()writer = SummaryWriter("logs")
step = 0
for data in dataloader:imgs, targets = dataoutput = lh(imgs)writer.add_images("input", imgs, step)output = torch.reshape(output, (-1, 3, 30, 30))writer.add_images("output", output, step)step += 1
通过tensorboard展示
二、最大池化层
解释:它将输入数据划分为不重叠的矩形区域(通常是2x2的窗口),然后在每个区域中选择最大值作为输出。这样,最大池化层通过取每个区域中的最大值来减少数据的维度。
主要作用:
-
特征减少:最大池化层可以减少输入数据的空间尺寸,从而降低了模型的计算复杂度。通过减少特征图的尺寸,最大池化层能够在保留重要特征的同时,减少需要处理的数据量,提高模型的效率。
-
平移不变性:最大池化层具有一定的平移不变性,即对于输入数据的平移操作具有不变性。这是因为在最大池化操作中,只选择每个区域中的最大值,而不考虑其位置信息。这种平移不变性使得神经网络对于输入数据的位置变化具有一定的鲁棒性。
-
特征提取:最大池化层可以帮助提取输入数据中的主要特征。通过选择每个区域中的最大值作为输出,最大池化层能够保留输入数据中的重要特征,并且对于噪声和不重要的细节具有一定的鲁棒性。
最大池化层在神经网络中起到了减少数据维度、提取关键特征和增强模型的鲁棒性等作用(简单来说就是把1080p的视频变成720p的)。它通常与卷积层交替使用,帮助神经网络有效地处理输入数据,提高模型的性能和泛化能力。
使用示例:
import torch
from torch.nn import MaxPool2d
from torch import nn
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterdataset = torchvision.datasets.CIFAR10('./cifar10', train=False, transform=torchvision.transforms.ToTensor(),download=False)
dataloader = DataLoader(dataset, 64, False)input = torch.tensor([[1, 2, 0, 3, 1],[0, 1, 2, 3, 1],[1, 2, 1, 0, 0],[5, 2, 3, 1, 1],[2, 1, 0, 1, 1]], dtype=torch.float32)input = torch.reshape(input, (1, 1, 5, 5))class Lh(nn.Module):def __init__(self):super(Lh, self).__init__()self.maxpool = MaxPool2d(kernel_size=3, ceil_mode=True)def forward(self, x):x = self.maxpool(x)return xlh = Lh()writer = SummaryWriter("logs")
step = 0
for data in dataloader:imgs, tagerts = datawriter.add_images("input", imgs, step)output = lh(imgs)writer.add_images("output", output, step)step += 1writer.close()
使用torchboard打卡
三、非线性激活函数
解释:神经网络的非线性激活函数是在神经网络的每个神经元上引入非线性变换的函数。它的作用是为神经网络引入非线性能力,从而使网络能够学习和表示更加复杂的函数关系。
主要作用:
-
引入非线性:线性变换的组合只能表示线性关系,而神经网络的层级结构和参数学习能力使其具备了更强大的函数逼近能力。非线性激活函数的引入打破了线性关系的限制,使得神经网络可以学习和表示非线性的函数关系,从而更好地适应复杂的数据模式。
-
增强模型的表达能力:非线性激活函数可以增强神经网络的表达能力,使其能够学习和表示更加复杂的特征和模式。通过引入非线性变换,激活函数可以对输入信号进行非线性映射,从而提取和表示更多种类的特征,帮助网络更好地理解输入数据。
-
解决分类问题的非线性可分性:在处理分类问题时,输入数据通常是非线性可分的。非线性激活函数可以帮助神经网络学习并表示类别之间的非线性边界,从而提高分类准确性。例如,常用的激活函数如ReLU、Sigmoid和Tanh等都是非线性的,它们可以帮助神经网络学习并表示复杂的决策边界。
-
缓解梯度消失问题:在深层神经网络中,反向传播算法需要通过链式法则计算梯度并更新参数。线性激活函数(如恒等映射)会导致梯度的乘积变得非常小,从而导致梯度消失问题。而非线性激活函数可以通过引入非线性变换,使得梯度能够在网络中传播并保持较大的幅度,从而缓解了梯度消失问题,有助于更好地训练深层网络。
使用示例:
import torch
import torchvision.datasets
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterinput = torch.tensor([[1, 2, 0, 3, 1],[0, 1, 2, 3, 1],[1, 2, 1, 0, 0],[5, 2, 3, 1, 1],[2, 1, 0, 1, 1]], dtype=torch.float32)input = torch.reshape(input, (-1, 1, 5, 5))dataset = torchvision.datasets.CIFAR10("./cifar10", False, transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, 64)class Lh(nn.Module):def __init__(self):super(Lh, self).__init__()self.relu1 = ReLU()self.sigmoid = Sigmoid()def forward(self, input):return self.sigmoid(input)lh = Lh()step = 0
writer = SummaryWriter("logs")for data in dataloader:imgs, targets = datawriter.add_images("input", imgs, step)output = lh(imgs)writer.add_images("output", output, step)step += 1writer.close()print("end")
使用torchboard打开
四、其它层与神经网络模型
查看pytorch的官方文档可以看到,神经网络中不同层及其使用
你可以创建自己的神经网络,然后自由搭配里面的网络层进行模型的训练。但是一般情况下我们不用手动去一层一层构建,因为官网提供了很多已经搭配好的神经网络模型,这些模型的训练效果都非常不错,我们只需要选择构建好的模型使用即可。
如 torchvision.models
五、神经网络搭建小实战
crfar10 model structure
根据上图,以input为 3@32 * 32为例,可更据公式计算pandding
代码示例:
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
import torchclass Lh(nn.Module):def __init__(self):super(Lh, self).__init__()self.model1 = Sequential(Conv2d(3, 32, 5, padding=2),MaxPool2d(2),Conv2d(32, 32, 5, padding=2),MaxPool2d(2),Conv2d(32, 64, 5, padding=2),MaxPool2d(2),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model1(x)return xlh = Lh()
input = torch.ones((64,3,32,32))
print(input.shape)
output = lh(input)
print(output.shape)
可以使用tensorboard绘制神经网络流程图
writer = SummaryWriter('logs')
writer.add_graph(lh, input)
writer.close()
六、损失函数
损失函数用于衡量模型的预测输出与真实标签之间的差异,并且在训练过程中用于优化模型的参数。
常用的损失函数及其简单使用方法:
1. 均方误差损失(Mean Squared Error, MSE):
均方误差损失函数用于回归问题,计算预测值与真实值之间的平均平方差。它可以通过torch.nn.MSELoss()
来创建。
import torch
import torch.nn as nnloss_fn = nn.MSELoss()predictions = torch.tensor([0.5, 0.8, 1.2])
targets = torch.tensor([1.0, 1.0, 1.0])loss = loss_fn(predictions, targets)
print(loss)
2. 交叉熵损失(Cross Entropy Loss):
交叉熵损失函数常用于分类问题,特别是多分类问题。它计算预测概率分布与真实标签之间的交叉熵。在PyTorch中,可以使用torch.nn.CrossEntropyLoss()
来创建交叉熵损失函数。
import torch
import torch.nn as nnloss_fn = nn.CrossEntropyLoss()predictions = torch.tensor([[0.2, 0.3, 0.5], [0.8, 0.1, 0.1]])
targets = torch.tensor([2, 0]) # 真实标签loss = loss_fn(predictions, targets)
print(loss)
3. 二分类交叉熵损失(Binary Cross Entropy Loss):
二分类交叉熵损失函数适用于二分类问题,计算预测概率与真实标签之间的交叉熵。在PyTorch中,可以使用torch.nn.BCELoss()
来创建二分类交叉熵损失函数。
import torch
import torch.nn as nnloss_fn = nn.BCELoss()predictions = torch.tensor([0.2, 0.8])
targets = torch.tensor([0.0, 1.0]) # 真实标签loss = loss_fn(predictions, targets)
print(loss)
将损失函数运用到前面的神经网络模型中:
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10('./cifar10', False, transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)class Lh(nn.Module):def __init__(self):super(Lh, self).__init__()self.model1 = Sequential(Conv2d(3, 32, 5, padding=2),MaxPool2d(2),Conv2d(32, 32, 5, padding=2),MaxPool2d(2),Conv2d(32, 64, 5, padding=2),MaxPool2d(2),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model1(x)return xloss = nn.CrossEntropyLoss()
lh=Lh()
for data in dataloader:imgs, targets = dataoutputs = lh(imgs)result_loss = loss(outputs, targets)result_loss.backward()print(result_loss)
七、优化器
优化器用于更新模型的参数以最小化损失函数。
常用的优化器及其简单使用方法:
1. 随机梯度下降(Stochastic Gradient Descent, SGD):
随机梯度下降是最基本的优化算法之一,它通过计算损失函数关于参数的梯度来更新参数。在PyTorch中,可以使用torch.optim.SGD
来创建SGD优化器。
import torch
import torch.optim as optimmodel = MyModel() # 自定义模型optimizer = optim.SGD(model.parameters(), lr=0.01)# 在训练循环中使用优化器
optimizer.zero_grad() # 清零梯度
loss = compute_loss() # 计算损失
loss.backward() # 反向传播计算梯度
optimizer.step() # 更新参数
2. Adam优化器:
Adam是一种自适应学习率优化算法,它结合了动量(momentum)和自适应学习率调整。在PyTorch中,可以使用torch.optim.Adam
来创建Adam优化器。
import torch
import torch.optim as optimmodel = MyModel() # 自定义模型optimizer = optim.Adam(model.parameters(), lr=0.001)# 在训练循环中使用优化器
optimizer.zero_grad() # 清零梯度
loss = compute_loss() # 计算损失
loss.backward() # 反向传播计算梯度
optimizer.step() # 更新参数
3. 其他优化器:
PyTorch还提供了其他优化器,如Adagrad、RMSprop等。这些优化器都可以在torch.optim
模块中找到,并使用类似的方式进行使用。
结合前面的神经网络模型代码示例:
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader
import torchdataset = torchvision.datasets.CIFAR10('./cifar10', False, transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)class Lh(nn.Module):def __init__(self):super(Lh, self).__init__()self.model1 = Sequential(Conv2d(3, 32, 5, padding=2),MaxPool2d(2),Conv2d(32, 32, 5, padding=2),MaxPool2d(2),Conv2d(32, 64, 5, padding=2),MaxPool2d(2),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model1(x)return xloss = nn.CrossEntropyLoss()
lh=Lh()
optis = torch.optim.SGD(lh.parameters(), lr=0.1)for epoch in range(10):running_loss = 0for data in dataloader:imgs, targets = dataoutputs = lh(imgs)result_loss = loss(outputs, targets)optis.zero_grad()result_loss.backward() # 设置对应的梯度optis.step()running_loss += result_lossprint(running_loss)
相关文章:

神经网络的搭建与各层分析
为什么去西藏的人都会感觉很治愈 拉萨的老中医是这么说的 缺氧脑子短路,很多事想不起来,就会感觉很幸福 一、卷积层 解释:卷积层通过卷积操作对输入数据进行处理。它使用一组可学习的滤波器(也称为卷积核或特征检测器)…...

SQL-每日一题【1174. 即时食物配送 II】
题目 配送表: Delivery 如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。 「首次订单」是顾客最早创建的订单。我们保证一个顾客只会有一个「首次订单」。 写一条 SQL 查询语句获取即时订单在所有用户的首次订…...
MySQL学习记录:第一章 DQL语言
文章目录 第一章 查询语言,DQL语言一、基础查询1、查询表中单个字段2、查询表中多个字段3、查询表中所有字段4、查询常量值5、查询表达式6、查询函数7、起别名8、去重9、+号的作用二、条件查询1、按条件表达式筛选2、按逻辑表达式筛选三、模糊查询四、排序查询五、常见函数1、…...

redis+token+分布式锁确保接口的幂等性
目录 1.幂等性是什么? 2.如何实现幂等性呢? 1.新增管理员,出弹窗的同时,请求后台。 2.后端根据雪花算法生成唯一标识key,以雪花数为key存到redis。并返回key给前端。 3.前端保存后端传过来的key。 4.前端输入完成…...

Vue模版语法
目录 接下来学习click 例题:修改背景颜色 例题:反复点击button按钮,可以不断切换背景颜色 先看以下例题是回顾vue的用法 <body><div id"box">{{myname}} - {{myage}}</div><script>var vm new Vue({el…...

新一代开源流数据湖平台Apache Paimon入门实操-上
文章目录 概述定义核心功能适用场景架构原理总体架构统一存储基本概念文件布局 部署环境准备环境部署 实战Catalog文件系统Hive Catalog 创建表创建Catalog管理表查询创建表(CTAS)创建外部表创建临时表 修改表修改表修改列修改水印 概述 定义 Apache Pa…...

ELK 企业级日志分析系统(一)
目录 一、ELK 简介 1.1 组件说明 1.2 为什么要使用ELK 1.3 完整日志系统的基本特征 1.4 ELK工作原理 二、Elasticsearch的介绍 2.1 Elasticsearch的核心: 三、Logstash 3.1 Logstash简介 四、Kibana 五、部署ELK日志分析系统 5.1 服务器配置 5.2 ELK Elasticse…...
2023-08-01力扣今日二题-Hard-DPLIS优先队列-好题
链接: 354. 俄罗斯套娃信封问题 题意: 一个信封有长宽,如果一个信封的长宽均严格大于另一个信封,那么大的这个信封可以装下小的这个信封 求最多能套娃几个信封 解: 类似普通的最长上升子序列,但是信封…...

并发 如何创建线程 多线程
进程:一个程序的执行过程 线程:一个方法就是一个线程 并发:多个线程抢夺一个资源 操作同一个对象 创建线程方法1 //创建线程方法1 继承Thread类 重写润方法 调用start开启线程 public class TestThead extends Thread{Overridepublic voi…...

亚马逊鲲鹏系统是怎么引流的?
亚马逊鲲鹏系统有三种引流方式,可设置通过亚马逊站点搜索、站外引流、直接访问产品页面进入到相关产品页面进行操作。 1、通过亚马逊站点搜索 正常的登录到我们的亚马逊主页,然后通过设置关键词及asin,最后进入你指定的产品,进行…...

第五章 Git
5-1、Git的安装 1、为什么要使用代码版本控制系统 【1】版本控制 【2】开发中存在的麻烦 2、Git和SVN的对比 【1】Git和SVN对比 (1)SVN (2)Git 3、Git下载和安装 【1】下载 【2】安装 一路下一步就好了,更换安装…...

无涯教程-Lua - 变量声明
变量的名称可以由字母,数字和下划线字符组成。它必须以字母或下划线开头,由于Lua区分大小写,因此大写和小写字母是不同的。 在Lua中,尽管无涯教程没有变量数据类型,但是根据变量的范围有三种类型。 全局变量(Global) …...
vue3学习-组件基础、深入组件
组件 基本概述 单独的 .vue文件 单文件组件(SFC)(single file component) 使用子组件 导入,无需注册,直接使用编译时,区分大小写可使用 />关闭标签 传递 props 需要再组件上声明注册 def…...

原型链污染分析
原型链污染问题 原型链原型的继承原型链污染 原型链 原型的继承 先创建一个对象,查看一下属性 const obj { prop1: 111, prop2: 222,} 这里的Object.prototype就是对象的原型。 原型里面有许多的属性,这里面的constructor是我们需要着重关注的。 除此…...
RF PCB的9条改进型建议
1.小功率的RF的PCB设计中,主要使用标准的FR4材料(绝缘特性好、材质均匀、介电常数ε=4,10%)。主要使用4层~6层板,在成本非常敏感的情况下可以使用厚度在1mm以下的双面板,要保证反面是一个完整的地层,同时由于双面板的厚度在1mm以上,使得地层和信号层之间的FR4介质较厚,…...

网络安全(黑客)自学就业
前段时间,遇到网友提问,说为什么我信息安全专业的找不到工作? 造成这个结果主要是有两大方面的原因。 第一个原因,求职者本身的学习背景问题。那这些问题就包括学历、学校学到的知识是否扎实,是否具备较强的攻防实战…...

uni-app选择器( uni-data-picker)选择任意级别
背景说明 uni-app 官方的插件市场有数据驱动选择器,可以用作多级分类的场景。引入插件后,发现做不到只选择年级,不选择班级(似乎,只能到最后子节点了)。 需求中,有可能选择的不是叶子。比如&a…...

网络入侵探测器Pi.Alert
什么是 Pi.Alert ? Pi.Alert 是 WIFI/LAN 入侵探测器。通过扫描连接到您的 WIFI/LAN 的设备,提醒您未知设备的连接。它还警告断开“始终连接”的设备。 Pi.Alert 使用了三种扫描方式 方式1:arp-scan。arp扫描系统实用程序用于使用 arp 帧搜索…...

Flask项目打包为exe(附带项目资源,静态文件)
1.在项目根目录创建my_app.spec文件,内容如下: # -*- mode: python ; coding: utf-8 -*-block_cipher Nonea Analysis([server.py], # flask入口pathex[],binaries[], datas[("E:/**/templates","/templates"),("E:/**/s…...

无代码开发(BIP旗舰版-YonBuilder)
目录 我的应用 新建领域 菜单管理 应用构建 新建应用 对象建模 新增业务对象 新增业务实体 页面建模 新增页面 编辑页面 发布管理 我的应用 角色管理 yonbuilder开发平台,提供标准服务和专业开发服务; 本篇文章只演示标准服务的可视化应用…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...