深度学习之梯度下降法 | Chapter 2 | Deep Learning | 3Blue1Brown

目录

    • 前言
    • 1. 总览
    • 2. 回顾
    • 3. 训练数据的使用
    • 4. 代价函数
    • 5. 梯度下降法
    • 6. 梯度向量
    • 7. 梯度下降小结
    • 8. 分析网络
    • 9. 网络如何学习的研究
    • 相关资料
    • 结语

前言

3Blue1Brown 视频笔记,仅供自己参考

这个章节主要介绍梯度下降的思想,之后进一步探索网络的能力以及隐含层神经元的真实目的

官网:https://www.3blue1brown.com

视频:https://www.bilibili.com/video/BV1Ux411j7ri

1. 总览

在这里插入图片描述

在上一个章节中我讲解了神经网络的结构,我会在这里快速回顾一下,帮大家唤醒记忆

在这里插入图片描述

接着我在这章内容里有两个主要目标,首先是介绍梯度下降的思想,它不仅仅是神经网络学习的基础,机器学习中很多其他技术也是基于这个方法

在这里插入图片描述

之后,我们将进一步探索一下上图所示这个网络的能力,以及那些隐含层神经元的真实目的

2. 回顾

在这里插入图片描述

回顾一下,我们的目标是实现手写数字识别这个经典范例,即神经网络中的 “Hello World”

在这里插入图片描述

手写数字的图像分辨率为 28x28 像素,每个像素的灰度值在 0 和 1 之间,它们决定了网络输入层中 784 个神经元的激活值

在这里插入图片描述

接着下一层的每个神经元的激活值等于上一层所有激活值的加权和,再加上一些叫做偏置值的数字,最后把这个和输进 sigmoid 或者 ReLU 之类的压缩函数

在这里插入图片描述

在这里插入图片描述

我比较随意地选取了两个隐含层,每层有 16 个神经元,整个网络有 13000 多个权重偏置值可供我们调整,正是这些数值决定了网络实际会做什么工作

在这里插入图片描述

当我们说这个网络对一个给定的数字进行分类时,我们的意思是,最后一层 10 个神经元中最亮的那个就对应了这个数字

在这里插入图片描述

要记得,我们在这里使用分层结构是出于这样的理由:没准第二层可以识别短边,说不定第三层会识别圆圈和直线等图案,最后在最后一层将这些图案拼凑起来,识别出数字

Note:这里提到的 pattern “图案” 就等价于 “模式识别” 中的模式

3. 训练数据的使用

在这里插入图片描述

那这章我们就来研究神经网络是怎么学习的,OK,现在我们想要这么一种算法,你可以给这个网络看一大堆训练数据,其中包括一堆不同的手写数字图像,以及它们代表哪个数字的标记,算法会调整这 13000 个权重和偏置值,以提高网络对训练数据的表现

在这里插入图片描述

我们希望这种分层结构可以让它学会举一反三,识别训练数据之外的图像。训练好网络之后,我们会给它更多以前从未见过的带标记的数据作为测试,你就能看到它对这些新图像进行分类的准确度

在这里插入图片描述

这例子之所以能广泛用于入门,是因为有幸 MNIST 数据库背后的好心人搜集了数以万计的手写数字图像,并分别都标记上了它们所表示的数字

在这里插入图片描述

虽然机器会 “学习” 的说法很大胆,但当你实际看到它的工作原理之后,这听起来就不再像是疯狂的科幻场面,而更像是一道微积分习题了,我是指这实际上是在找某个函数的最小值

4. 代价函数

在这里插入图片描述

从概念上讲,我们认为每个神经元都与上一层的所有神经元相连接,决定其激活值的加权和中的权重有点像是那些连接的强弱,而偏置值则表明神经元是否更容易被激活

在这里插入图片描述

在一开始,我们会完全随机地初始化所有的权重和偏置值,可想而知,这个网络对于给定的训练示例会表现得非常糟糕,毕竟它只是在做一些随机的判断

在这里插入图片描述

在这里插入图片描述

例如,你输入一个 3 的图像后,输出层看起来就一团糟,这时你就要定义一个 “代价函数” 来告诉电脑这是一个不好的结果,其他神经元输出的激活值应该基本上是 0,只有 3 这个神经元是 1,但你给我的结果完全错误

在这里插入图片描述

用更加数学的语言来说,你要将每个错误输出激活值与你想要的值之间的差的平方加起来,我们称之为训练单个样本的 “代价”

Note:单个样本上代价也叫做 Loss,“损失/误差”,不过现在很多人将 loss function、cost function 混着用了

在这里插入图片描述

注意一下,网络能对图像进行正确的分类时,这个平方和就比较小,但如果网络糊里糊涂找不着北的话,这个平方和就很大

在这里插入图片描述

你接下来就要考虑手头上几万个训练样本中代价的平均值,而我们就用这个平均代价值来评价这个网络有多糟糕

Note:代价的平均值也叫 Empirical Risk,“经验风险”

在这里插入图片描述

但这东西挺复杂的,要记得网络本身不过是个函数,有 784 个输入值,即像素的灰度,最后的输出值是 10 个数字,而所有的权重和偏置值可以说就组成了这个函数的参数

在这里插入图片描述

而代价函数还要再抽象一层,这 13000 多个权重和偏置值作为它的参数,它输出的是单个数值,来表示这些权重和偏置值有多差劲,而且代价函数取决于网络对于上万个训练数据的综合表现

在这里插入图片描述

内容很多,需要慢慢消化,但如果你只告诉电脑这个网络它有多糟糕,那并不是很有用,你还得告诉它,怎么改变这些权重和偏置值才能有进步

在这里插入图片描述

为了简化问题,我们先不去想一个有 13000 个变量的函数,而先考虑简单的一元函数,只有一个输入变量,只输出一个数字,要怎么找输入值 w w w 使得函数值最小化呢?学过微积分的都知道,有时候你可以直接算出这个最小值

在这里插入图片描述

不过函数很复杂的话,就不一定能写出来,而我们这个超复杂 13000 元的代价函数就更加是不可能做到的了

在这里插入图片描述

一个更灵活的技巧是,先随便挑一个输入值,然后考虑向左还是向右走,函数值才会变小,准确地说,如果你找到了函数在这里的斜率,那么斜率为正就向左走,斜率为负就向右走。在每一个点上都这样子重复,计算新斜率,再适当地走一步的话,你就会逼近函数的某个局部最小值

在这里插入图片描述

你可以想象一个小球滚下山坡,要注意,就算是这个很简单的一元函数,由于不知道一开始输入值在哪里,最后你可能会落到许多不同的坑里,而且无法保证你落到的局部最小值就是代价函数可能达到的全局最小值

在这里插入图片描述

我们的神经网络也会遇到这个问题,值得一提的是如果每步的大小和斜率成比例,那么在最小值附近斜率会越来越平缓,每步会越来越小,这样可以防止调过头

5. 梯度下降法

在这里插入图片描述

想象一个更复杂的,两个输入一个输出的二元函数,输入空间可以想象成 XY 平面,代价函数是平面上方的曲面

在这里插入图片描述

现在我们不问函数的斜率,而应该问在输入空间内沿哪个方向走才好让输入结果下降得最快,换句话说,哪个方向下山最快,这里同样可以套用球滚下山的场景方便思考

在这里插入图片描述

在这里插入图片描述

熟悉多元微积分的人已经知道,函数的 梯度 指出了函数的 最陡增长方向,也就是说按梯度的方向走,函数值增长得就最快,那么沿梯度的负方向走,函数值自然就降低得最快了,而且,这个梯度向量的长度就代表了这个最陡的斜坡到底有多陡

在这里插入图片描述

但如果你不熟悉多元微积分,想了解更多的话,推荐你们可以去看看之前的多元微积分课程。然而大家现在只需要知道,我们有办法算出这么个向量,它能够指出哪个方向下山最快,路有多陡就可以了,知道了这一点,具体细节掌握不牢靠也无所谓

在这里插入图片描述

你只要懂得让函数值最小的算法其实不过是先计算梯度,再按梯度反方向走一小步下山,然后循环

在这里插入图片描述

处理带 13000 个输入的函数也是一个道理,想象把 13000 个权重偏置都放到一个列向量里,那么代价函数的负梯度也不过是个向量,负梯度正是指出了在这个大到爆炸的函数输入空间内,具体如何改变每一项参数才可以让代价函数的值下降得最快

在这里插入图片描述

那么,对于这个我们特别设计的代价函数,更新权重和偏置来降低代价函数的值,意味着输入训练集的每一份样本的输出都更接近期待的真实结果,而不是一串 10 个随机数字

在这里插入图片描述

要注意的是这个代价函数取了整个训练集的平均值,所以最小化的意思是,对所有的样本得到的总体结果都会更好一点

在这里插入图片描述

这个计算梯度的算法是神经网络的核心,我们叫做 反向传播算法(Back Propagation,BP),那就是下个章节的内容了,到时,我会从头到尾梳理一遍单个训练数据会具体让每个权重和每个偏置产生怎么样的变化,不再死磕相关的微积分和公式的概念,而是给大家直观上的感受

在这里插入图片描述

此时此刻,除了怎么实现这个算法,我主要想强调当我们提到让网络学习,实质上就是让代价函数的值最小,而为了达到这个效果,代价函数非常有必要是平滑的,这样我们才能每次挪一点点,最后找到一个局部最小值

在这里插入图片描述

这也顺便解释了,为什么人工神经元的激活值是连续的,而非直接沿袭生物学神经元那种二元式的,要么激活要么非激活的取值模式

在这里插入图片描述

这种按照负梯度的倍数不断调整函数输入值的过程就叫做 梯度下降法(Gradient descent),这是一种可以让你收敛到代价函数图中某一个 “坑” 里,即一个局部最小值的地方

在这里插入图片描述

这里我依然展示的是一个二元函数图,毕竟人脑想象一个 13000 维的输入空间中的变动实在是略困难,但其实我们还有一种漂亮的思路,不用借助空间

在这里插入图片描述

负梯度中的每一项都告诉了我们两件事,正负号很明显在告诉我们输入向量的这一项该调大还是调小,但重要的是,每一项的相对大小更告诉了我们改变哪个值的影响更大

在这里插入图片描述

可以看到我们的网络中,调整其中一个权重对于代价函数的影响就比调整别的权重大得多,对训练数据来说,其中某些连线就是更加的重要

6. 梯度向量

在这里插入图片描述

所以,你在看到这个复杂到爆炸的代价函数它的梯度向量时,就可以把它理解为各个权重偏置的相对重要度,标记出了改变哪个参数性价比最高

在这里插入图片描述

这也是理解方向的另一种方式,举个简单的例子,假设有个输入两个变量的二元函数,你算出来这个函数在某个点的梯度是 [3, 1],一种解读就是,你站在这个点,顺着这个梯度的方向移动,函数值增加得最快

在这里插入图片描述

当你把这个函数曲面画出来时,你沿这个向量的方向走就是径直向上的

在这里插入图片描述

但我们还有另外一种解读,即第一个变量的重要性是第二个变量的 3 倍,也就是说,起码在这一块取值区域内,改变 x 的值会造成更大的影响

7. 梯度下降小结

在这里插入图片描述

好吧,我们回到对网络的讨论中来,小结一下,神经网络本身是一个带 784 个输入和 10 个输出的函数,由各种加权和所定义的

在这里插入图片描述

代价函数则是更复杂一层,把那 13000 多个权重偏置作为输入,通过训练数据得出一个对网络糟糕程度的评分

在这里插入图片描述

而代价函数的梯度,则在上边还要复杂一层,告诉我们如何微调权重偏置的值才可以让代价函数的结果改变得最快,也就是可以理解为改变了哪些权重影响力最大

8. 分析网络

在这里插入图片描述

那么,当你随机初始化权重和偏置,并通过梯度下降法调整了很多次参数之后,神经网络来识别它从未见过的图像时,表现又会如何呢?

在这里插入图片描述

对于这个带 2 层 16 个神经元隐含层的神经网络来说,其实表现并不赖,它可以正确分类 96% 的新图像

在这里插入图片描述

老实说,如果你去检查下它搞错了的图像的话,你自己也会觉得不应该那么强求它

在这里插入图片描述

如果我们再修改下隐含层的结构的话,准确率可以上到 98%,这的确够好了,当然不是最好,换成更加复杂的网络比原版的肯定效果会更好

在这里插入图片描述

但既然图像识别本来任务就很艰巨,我觉得神经网络在我们从未告诉它该识别什么图案的情况下,能准确识别出从未见过的图像,已经很了不起了

在这里插入图片描述

一开始我介绍这种结构期望的是,它的第二层能识别出短边,第三层能把短边拼成圈或长笔画,最后把这些部件拼成数字,那么神经网络真的是这么做的吗?

在这里插入图片描述

好吧,对于这个网络而言,完全不是嘛

在这里插入图片描述

还记得上一章中我们可以把第一层所有神经元和第二层某一神经元间所有的权重表示为第二层神经元所识别的一个像素图案吗,然而实际应用中,第一层和第二层之间的权重,之前说它们能识别出各种散落的短边,但其实它们看起来没什么规律,中间只有一些松散的图案,感觉就像在如深海一般的 13000 维参数空间中,我们的网络找到了一个还不错的局部最小值住了下来,尽管它可以成功对绝大多数图像做分类,但它并不会如期望一般识别出图像中的各种图案

在这里插入图片描述

看个最明显的例子,我们把一个随机的图像输入进去,如果网络很智能,你可能会期待它要么会感到不确定,10 个输出神经元一个都不激活,要么就激活全部的 10 个神经元,激活值都差不多

在这里插入图片描述

但结果却是,网络总是很自信地给你一个没道理的回答,正如它能把一张真正的 5 确定成 5 一般,它也能把一张随机的噪声图识别成 5

在这里插入图片描述

换句话来讲,虽然网络可以很好地识别数字,但它也并不知道自己如何写数字

在这里插入图片描述

究其原因,很大程度上是因为它的训练被限定在了很窄的框架内,试想一下神经网络的第一视角,从它的角度看,整个宇宙都是由小网格内清晰定义的静止数字所组成的,而它的代价函数则只会促使它对最后的判断有绝对的自信

在这里插入图片描述

那么,上面这张图真的显示了第二层神经元的工作过程吗?

在这里插入图片描述

你可能想知道,为什么我一开始在介绍这个网络的时候,我想让你们觉得它们在识别图案和短边,毕竟,神经元根本就没这么做,是不是

在这里插入图片描述

其实,我们不应该把这看做我们讨论的终点,而应该当做学习的起点,这种网络其实是在早八九十年代就已经研究过的旧技术,你确实需要先理解这些旧的才好理解现代变种的细节,而显然旧方法也足以解决些有趣的问题

在这里插入图片描述

不过,你越深究隐含层的工作过程,你会觉得它也没那么智能

9. 网络如何学习的研究

最后,我们来谈下几篇 paper,它们都深入研究了更先进的图像识别是如何学习的:

  • Understanding deep learning requires rethinking generalization
  • A Closer Look at Memorization in Deep Networks
  • The Loss Surfaces of Multilayer Networks

在这里插入图片描述

我们先来看第一篇

在这里插入图片描述

这篇文章选取了一个图像识别做得特别好的深度神经网络,但不给它一个正确标记过的训练集,而是用了个标记被打乱了的训练集,显然测试的准确率不比随机猜测的好,毕竟所有的标记都被打乱了

在这里插入图片描述

但训练的时候,它依然能达到相同的训练准确率,就当跟用了个正确标记的训练集一样,即是说这个网络数以百万计的权重足以让它记忆下所有随机的数据

在这里插入图片描述

但问题就来了,我们让代价函数最小到底是对应上了图像中的某些结构呢,还是只是单纯的死记硬背罢了

在这里插入图片描述

在 ICML 会议上的一篇论文,即我们讨论的第二篇论文,提出了一些想法认为这些网络其实做到了更智能的东西

在这里插入图片描述

观察下它的准确率曲线,如果训练用了一个随机的训练集的话,代价下降得就特别的慢,跟一个线性方程差不多

在这里插入图片描述

也就是说你很难得找到可能存在的局部最小值,也能难找到让你准确率上升的权重

在这里插入图片描述

而当你用了 “结构化” 的训练集,拥有标记正确的数据的话,你一开始代价值会上下浮动,但后来一下就降到很低的地方了,表示达到了一定准确率,所以某种程度上讲就更容易找到局部最小值

在这里插入图片描述

这个问题正好可以引出另外一篇已经发表了好几年的论文,它那里面用到的网络每一层都简化了许多

在这里插入图片描述

但论文的一个结论就是,你看下代价函数的优化结果就会发现,网络倾向收敛到的各个局部最小值其实都差不多一样大,你可以认为如果数据集已经结构化了,那么你就能更轻松地找到局部最小

相关资料

  • 神经网络和深度学习的书籍 | Michael Nielsen
    • http://neuralnetworksanddeeplearning.com/
    • https://github.com/mnielsen/neural-networks-and-deep-learning
  • MNIST 数据库
    • https://yann.lecun.com/exdb/mnist/
  • 博客 | Chris Olah
    • https://colah.github.io/
  • 机器学习视频 | Welch Labs
    • Learning To See [Part 1:Introduction]
    • Neural Networks Demystified [Part 2:Data and Architecture]
  • 深度学习书籍 | GoodfellowBengioCourville
    • https://www.amazon.com/Deep-Learning-Adaptive-Computation-Machine

结语

这个章节我们主要学习了神经网络是怎么学习的,它主要是通过梯度下降法,最小化代函数来更新网络中的各个参数,以达到学习的目的,而其中计算梯度的算法是神经网络的核心,叫做反向传播算法,我们下章会详细讲解

OK,以上就是本章的全部内容了,下章我们来讲反向传播算法,敬请期待😄

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

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

相关文章

助农贷款、保险精准定价,背后的“星绽”机密计算全球开源

文|白 鸽 编|王一粟 河南平顶山种植日本引进白草莓的李朝阳,和山东临沂种植山楂和桃子的李东旭,都是网商银行“农户秒贷”项目的受益者。 “发果农工资,收购水果,遇上天气灾害时周转应急时,“…

E/MicroMsg.SDK.WXMediaMessage:checkArgs fail,thumbData is invalid 图片资源太大导致分享失败

1、微信分享报: 2、这个问题是因为图片太大导致: WXWebpageObject webpage new WXWebpageObject();webpage.webpageUrl qrCodeUrl;//用 WXWebpageObject 对象初始化一个 WXMediaMessage 对象WXMediaMessage msg new WXMediaMessage(webpage);msg.tit…

MySQL-12.DQL-条件查询

一.DQL-条件查询 -- DQL:条件查询 -- 1.查询 姓名 为 杨逍 的员工 select id, username, password, name, gender, image, job, entrydate, create_time, update_timefrom tb_emp where name 杨逍;-- 2.查询 id小于等于5 的员工信息 select * from tb_emp where id < 5;-…

Flutter 小技巧之 equatable 包解析以及宏编程解析

今天我们聊聊 equatable 包的实现&#xff0c;并通过 equatable 去理解 Dart 宏编程的作用和实现&#xff0c;对于 Flutter 开发者来说&#xff0c;Dart 宏编程可以说是「望眼欲穿」。 equatable 正如 equatable 这个包名所示&#xff0c;它的功能很简单&#xff0c;主要是用…

LeetCode 热题100之双指针

1.移动零 思路分析1&#xff08;纯模拟&#xff09; 定义指针j&#xff0c;用来收集不是0的数&#xff1b;收集完毕之后&#xff0c;再把剩下位置处置为0即可。 具体实现代码&#xff08;详解版&#xff09;&#xff1a; class Solution { public:void moveZeroes(vector<…

前端vue框架配置基础信息详解分析

前端vue2、vue3框架是我们最近常用的框架&#xff0c;今天我们分析一下配置基础信息、详解其中的功能含义。 1、vue.config.js 文件分析 这个 vue.config.js 文件是 Vue CLI 项目中用于配置项目构建行为和开发环境设置的文件。它能够让开发者定制打包、代理、路径、样式等方面…

国产单片机及其特点

国产单片机在近年来取得了显著的发展&#xff0c;不仅在技术上不断突破&#xff0c;还在市场上占据了越来越重要的位置。 主要国产单片机品牌及特点 兆易创新&#xff08;GD&#xff09; 主要系列&#xff1a;GD32系列&#xff0c;基于ARM Cortex-M内核。特点&#xff1a;高性能…

Android 中的串口开发

一&#xff1a;背景 本文着重讲安卓下的串口。 由于开源的Android在各种智能设备上的使用越来越多&#xff0c;如车载系统等。在我们的认识中&#xff0c;Android OS的物理接口一般只有usb host接口和耳机接口&#xff0c;但其实安卓支持各种各样的工业接口&#xff0c;如HDM…

ResNet18果蔬图像识别分类

1. 项目简介 本项目的目标是开发一个基于ResNet18深度学习模型的果蔬图像分类系统。随着现代农业与人工智能的结合&#xff0c;智能果蔬分类技术在供应链、生产和销售管理中扮演了越来越重要的角色。本项目的背景源于提升果蔬分类效率的需求&#xff0c;通过使用计算机视觉技术…

基于SSM+微信小程序的酒店管理系统1

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于微信小程序开发的酒店管理系统管理员&#xff0c;酒店管理员以及用户。 1、管理员功能可以管理个人中心&#xff0c;用户信息管理&#xff0c;酒店管理员管理&#xff0c;房间类型管…

YOLO11改进 | 注意力机制 | 添加SE注意力机制

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 本文介绍了YOLOv11添加SE注意力机制&…

Redis中String类型数据扩容原理分析

大家好&#xff0c;我是 V 哥。在 Java 中&#xff0c;我们有动态数组ArrayList&#xff0c;当插入新元素空间不足时&#xff0c;会进行扩容&#xff0c;好奇 Redis 中的 String 类型&#xff0c;C 语言又是怎样的实现策略&#xff0c;带着疑问&#xff0c;咱们来了解一下。 最…

Python酷库之旅-第三方库Pandas(167)

目录 一、用法精讲 766、pandas.Interval.open_left属性 766-1、语法 766-2、参数 766-3、功能 766-4、返回值 766-5、说明 766-6、用法 766-6-1、数据准备 766-6-2、代码示例 766-6-3、结果输出 767、pandas.Interval.open_right属性 767-1、语法 767-2、参数 …

[LeetCode] 78. 子集

题目描述&#xff1b; 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1…

Windows通过netsh控制安全中心防火墙和网络保护策略

Windows通过netsh控制安全中心防火墙和网络保护策略 1. 工具简介 【1】. Windows安全中心 【2】. netsh工具 netsh(Network Shell) 是一个Windows系统本身提供的功能强大的网络配置命令行工具。 2. 开启/关闭防火墙策略 在设置端口&#xff08;禁用/启用&#xff09;前&am…

传输层协议UDP详解

目录 一. 知识准备 1.1 传输层 1.2 重识端口号 二. UDP协议 三. UDP协议特点 一. 知识准备 1.1 传输层 前面已经讲过&#xff0c;HTTP协议是应用层协议&#xff0c;在此之前&#xff0c;我们短暂的认为HTTP是直接通过应用层与外界通信的。但是我们要知道&…

DOTween动画插件超详解(保姆级巨细)

文章目录 一、前言二、DOTween简介与安装&#xff08;一&#xff09;什么是DOTween&#xff1f;&#xff08;二&#xff09;下载安装 三、DOTween 的使用&#xff08;基础&#xff09;&#xff08;一&#xff09;使用前注意事项1. 引入命名空间2. 进行初始化3. 清除遗留4. 设置…

基于Java的电商书城系统源码带本地搭建教程

技术框架&#xff1a;jQuery MySQL5.7 mybatis jsp shiro 运行环境&#xff1a;jdk8 IntelliJ IDEA maven3 宝塔面板 系统功能介绍 该系统分为前台展示和后台管理两大模块&#xff0c;前台主要是为消费者服务。该子系统实现了注册&#xff0c;登录&#xff0c; 以及…

asp.net core mvc发布时输出视图文件Views

var builder WebApplication.CreateBuilder(args); builder.Services.AddRazorPages();builder.Services.AddControllersWithViews(ops > {//全局异常过滤器&#xff0c;注册ops.Filters.Add<ExceptionFilter>(); })// Views视图文件输出到发布目录&#xff0c;视图文…

使用 VSCode 通过 Remote-SSH 连接远程服务器详细教程

使用 VSCode 通过 Remote-SSH 连接远程服务器详细教程 在日常开发中&#xff0c;许多开发者需要远程连接服务器进行代码编辑和调试。Visual Studio Code&#xff08;VSCode&#xff09;提供了一个非常强大的扩展——Remote-SSH&#xff0c;它允许我们通过 SSH 协议直接连接远程…