【机器学习】强化学习(2)——捋清深度强化学习的思路
在之前学习的过程中我了解到深度学习中很重要的一个概念是反向传播,最近看论文发现深度强化学习(DRL)有各种各样的方法,但是却很难区分他们的损失函数的计算以及反向传播的过程有何不同。在有监督的学习中,损失可以理解为预测值和真实值之间的距离,那么在这里的损失指的是什么?是否也涉及到两个值之间的差距呢,具体是哪两个东西之间的拟合(学习)?如何拟合?这里通过举例对几种强化学习方法进行比较。
问题设计
假设有一个3×3的迷宫(如上图),用S表示起点(入口)、E表示终点(出口)、O表示通路、W表示墙壁,目标是从S到E找到一条通路。
Q-learning
原理
Q-learning是一种基于值函数的强化学习方法,其核心思想是通过更新和维护动作值函数 Q ( s , a ) Q(s,a) Q(s,a)来间接推导出最优策略,使用Q-table存储每个状态-动作对的期望奖励。与深度学习中的反向传播不同,Q-learning在传统实现中并不依赖反向传播。
Q ( s , a ) Q(s,a) Q(s,a)的更新公式为贝尔曼方程:
Q ( s , a ) ← Q ( s , a ) + α [ r + γ max a ′ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s,a)←Q(s,a)+α[r+γ\max_{a'}Q(s',a')-Q(s,a)] Q(s,a)←Q(s,a)+α[r+γa′maxQ(s′,a′)−Q(s,a)]
其中, α α α是学习率, γ γ γ是折扣因子, r r r是当前奖励, s ′ s' s′是下一个状态。这是一个迭代更新公式,直接对Q-table进行更新,无需显式的梯度计算或反向传播,Q-table存储了所有状态-动作对的值,更新过程是逐个元素地调整表格中的值。
模拟
参数设计
- 奖励规则:到达终点奖励+100;到达墙壁或超出迷宫奖励-10;其他情况奖励分值为6-到出口最短路线距离(假设这些距离提前都计算好了)。比如走到(1,0)+3,走到(2,2)+4,走到(0,1)-10,走到(0,2)+100。
- 贝尔曼方程参数: α = 0.8 α=0.8 α=0.8; γ = 0.2 γ=0.2 γ=0.2。
Q-table初始化
初始化一个Q-table,大小为状态数×行为数
。对于3×3的迷宫,状态数为9(每个格子为一个状态),行为数为4(上下左右)。初始化Q-table为0:
学习过程
第一次
状态和状态转移:
状态s | 行为(随机) | 下一个状态s’ |
---|---|---|
(0,0) | UP | × |
更新Q-table:
原始Q[(0,0), UP] | 奖励 | 下一状态能获得的最大奖励 | 更新后的Q[(0,0), UP] |
---|---|---|---|
0 | -10 | 0 | -8 |
结果:
第二次
状态和状态转移:
状态s | 行为(随机) | 下一个状态s’ |
---|---|---|
(0,0) | DOWN | (1,0) |
更新Q-table:
原始Q[(0,0), DOWN] | 奖励 | 下一状态能获得的最大奖励 | 更新后的Q[(0,0), DOWN] |
---|---|---|---|
0 | +3 | 0 | 2.4 |
结果:
第三次
状态s | 行为(随机) | 下一个状态s’ | 原始Q[(1,0), RIGHT] | 奖励 | 下一状态能获得的最大奖励 | 更新后的Q[(1,0), RIGHT] |
---|---|---|---|---|---|---|
(1,0) | RIGHT | (1,1) | 0 | +4 | 0 | 3.2 |
结果:
中间省略1000次
状态s | 行为(随机) | 下一个状态s’ | 原始Q[(1,1), LEFT] | 奖励 | 下一状态能获得的最大奖励 | 更新后的Q[(1,1), LEFT] |
---|---|---|---|---|---|---|
(1,1) | LEFT | (1,0) | 0 | +3 | 3.2 | 2.912 |
状态s | 行为(随机) | 下一个状态s’ | 原始Q[(1,0), DOWN] | 奖励 | 下一状态能获得的最大奖励 | 更新后的Q[(1,0), DOWN] |
---|---|---|---|---|---|---|
(1,0) | DOWN | (2,0) | 0 | +2 | 0 | 1.6 |
自己抽签和计算太麻烦了,于是写了代码大致模拟了一下。
# Dangerous
import randomkeys = [(0,0,'up'), (0,0,'down'), (0,0,'left'), (0,0,'right'),(0,1,'up'), (0,1,'down'), (0,1,'left'), (0,1,'right'),(0,2,'up'), (0,2,'down'), (0,2,'left'), (0,2,'right'),(1,0,'up'), (1,0,'down'), (1,0,'left'), (1,0,'right'),(1,1,'up'), (1,1,'down'), (1,1,'left'), (1,1,'right'),(1,2,'up'), (1,2,'down'), (1,2,'left'), (1,2,'right'),(2,0,'up'), (2,0,'down'), (2,0,'left'), (2,0,'right'),(2,1,'up'), (2,1,'down'), (2,1,'left'), (2,1,'right'),(2,2,'up'), (2,2,'down'), (2,2,'left'), (2,2,'right')]
values = [-8,2.4,0,0,0,0,0,0,0,0,0,0,0,0,0,3.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] # 经历三次学习后的值rewards = [[2, -10, 100], [3, 4, 5], [2, -10, 4]]action_list = ['up', 'down', 'left', 'right']qTable = dict(zip(keys, values)) # 创建初始列表alpha = 0.8
gamma = 0.2now_x = 1
now_y = 1def transfer_x(x, act):if act == 'up': return x-1elif act == 'down': return x+1else: return xdef transfer_y(y, act):if act == 'left': return y-1elif act == 'right': return y+1else: return yfor i in range(1000): # 学习1000次action = random.choice(action_list) # 行为next_x = transfer_x(now_x, action) # 下一个状态s'next_y = transfer_y(now_y, action)before_q = qTable[(now_x, now_y, action)] # 原始Qif next_x not in [0,1,2] or next_y not in [0,1,2]: # 奖励reward = -10else: reward = rewards[next_x][next_y]if next_x not in [0, 1, 2] or next_y not in [0, 1, 2]: # 下一状态能获得的最大奖励max_reward = 0else:max_reward = 0for a in action_list:r = qTable[(next_x, next_y, a)]if r > max_reward: max_reward = rqTable[(now_x, now_y, action)] = before_q + alpha * (reward + gamma * max_reward - before_q) # 更新后的Q值random_start_list = [(0,0), (1,0), (1,1), (1,2), (2,0), (2,2)]random_start = random.choice(random_start_list)random_p = random.randint(1,10)random_flag = True if random_p == 1 else Falseif next_x == 0 and next_y == 2: # 如果走到终点就从随机位置开始now_x = random_start[0]now_y = random_start[1]elif next_x not in [0, 1, 2] or next_y not in [0, 1, 2]:# 如果走出去就不改变当前位置(以0.1的概率随机初始位置)if random_flag:now_x = random_start[0]now_y = random_start[1]elif next_y == 1 and (next_x == 0 or next_x == 2):# 如果走到墙上就不改变当前位置(以0.1的概率随机初始位置)if random_flag:now_x = random_start[0]now_y = random_start[1]else: # 或者以0.1的概率随机初始位置now_x = next_xnow_y = next_yif random_flag:now_x = random_start[0]now_y = random_start[1]# 打印Q表
for key in qTable:print("key:" + str(key) + " " + str(qTable[key]))
结果
得到结果如下:
其中阴影部分是墙和终点的位置,由于无法到达墙、到达终点后游戏结束,所以这两个位置不会更新Q值。
上表的解释:在(0,0)位置时(对应当前状态),Q值在行为"down"处最大为4.8,因此应该向下走,下一个状态是(1,0)。其余位置类似。
红色箭头表示每一个状态的最优行为,绿色箭头表示用该方法计算得出的最优路线。
DQN(深度Q-learning)
DQN和Q学习的主要区别在于如何表示和更新Q值,DQN使用神经网络来近似Q值函数,而不是使用表格。
经验回放
经验回放(Experience Replay)是强化学习中的一个重要技术,主要用于解决强化学习算法中的一些问题,提高算法的稳定性和学习效率。
具体来说,就是不每次都立刻进行Q值计算和反向传播,而是将每次的<状态、动作、状态转移>
(称为经验样本或经验元组)先放到缓冲区,然后每次从缓冲区取一部分一次性计算。类似计算机视觉中同时对数据集中的多张图片进行处理,大小表示为batch_size。
原理
其实就是将Q学习中需要查Q-table的时候都用网络替换。旧的Q表值和奖励共同作用下更新为新的Q表值。
(我以前一直以为是要让Q值越来越拟合奖励,所以很奇怪,明明奖励的公式我们已经知道了,还要怎么去学习呢,其实奖励只是作为一个已知的数值加入到计算中,并不是说我们要去模拟奖励的生成方式。)
Q-learning中的贝尔曼方程:
Q ( s , a ) ← Q ( s , a ) + α [ r + γ max a ′ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s,a)←Q(s,a)+α[r+γ\max_{a'}Q(s',a')-Q(s,a)] Q(s,a)←Q(s,a)+α[r+γa′maxQ(s′,a′)−Q(s,a)]
可以写为:
Q ( s , a ) ← ( 1 − α ) Q ( s , a ) + α [ r + γ max a ′ Q ( s ′ , a ′ ) ] Q(s,a)←(1-α)Q(s,a)+α[r+γ\max_{a'}Q(s',a')] Q(s,a)←(1−α)Q(s,a)+α[r+γa′maxQ(s′,a′)]
就像加权求和,它在原来Q的基础上加上了一部分奖励作用下的分数。
深度Q-learning中的损失函数:
L ( θ ) = E s , a , r , s ′ [ ( Q θ ( s , a ) − ( r + γ max a ′ Q θ − ( s ′ , a ′ ) ) ) 2 ] L(θ)=\mathbb{E}_{s,a,r,s'}[(Q_θ(s,a)-(r+γ\max_{a'}Q_{θ^-}(s',a')))^2] L(θ)=Es,a,r,s′[(Qθ(s,a)−(r+γa′maxQθ−(s′,a′)))2]
它就是使计算得到的Q值逐渐趋于稳定,基本上等于那个奖励作用下的分数,这个分数不仅考虑了当前奖励,还考虑了下一步能够得到的分数。注意上式中有两组参数,分别为 θ θ θ和 θ − θ^- θ−,对应两个网络(结构一样)。
- Q θ ( s , a ) Q_θ(s,a) Qθ(s,a)通过主网络训练得到
主网络(Main Network)也称为在线网络(Online Network)或当前网络(Current Network)。主网络负责学习环境中的状态-动作值函数(Q函数),即预测在给定状态下采取某个动作所能获得的预期回报。主网络通过梯度下降等优化算法不断更新其参数,以最小化预测Q值和实际Q值之间的差距。主网络直接与环境交互,根据采集到的经验(状态、动作、奖励、下一个状态)进行学习。 - max a ′ Q θ − ( s ′ , a ′ ) \max_{a'}Q_{θ^-}(s',a') maxa′Qθ−(s′,a′)由目标网络计算
目标网络(Target Network)是主网络的一个延迟更新版本,其参数定期从主网络复制过来。目标网络不直接参与学习,而是为主网络提供一个稳定的训练目标。在计算Q值的目标值时,使用目标网络来预测下一个状态下的Q值,这样可以减少学习过程中的方差,使学习更加稳定。目标网络的更新频率通常低于主网络,例如,每几千个时间步更新一次。
说明通过神经网络得到的Q值不仅体现了当前决策的奖励,还综合了未来的奖励。
模拟
参数设计
- 奖励规则:到达终点奖励+100;到达墙壁或超出迷宫奖励-10;其他情况奖励分值为6-到出口最短路线距离(假设这些距离提前都计算好了)。比如走到(1,0)+3,走到(2,2)+4,走到(0,1)-10,走到(0,2)+100。迷宫格内的奖励矩阵可以表示为:
- 贝尔曼方程参数: α = 0.001 α=0.001 α=0.001; γ = 0.99 γ=0.99 γ=0.99。
- 网络输入:状态 s s s,由二维坐标表示。从上往下三行的行号分别为0、1、2,从左到右三列的列标号分别为0,1,2,(0,0)是起点位于左上角,(0,2)是终点位于右上角。
- 网络输出:每个动作的Q值。
- 隐藏层架构:1层,16个神经元,激活函数为ReLU。
- ε-贪婪策略:初始阶段,以较高概率ϵ(设置为1.0)随机选择动作。随着训练进行,逐渐降低ϵ(最后衰减到0.01),更多地依赖网络预测的动作。
- 经验回放:缓冲区大小为 10 , 000 10,000 10,000, b a t c h s i z e = 32 batch_{size}=32 batchsize=32。
- 同步目标网络步长为100。
学习过程
- 初始化将智能体放置在起点
(0,0)
。 - 选择动作。使用ε-贪婪策略选择动作a。如果 r a n d o m < ϵ random<ϵ random<ϵ,随机选择动作。否则,选择 a r g max a Q θ ( s , a ) arg\max_aQ_θ(s,a) argmaxaQθ(s,a)。
- 执行动作:根据选定的动作 a a a,更新智能体的位置 s ′ s′ s′。如果超出迷宫范围或撞到障碍墙,给予奖励 -10 并结束回合。如果到达终点 (0, 2),给予奖励 100 并结束回合。否则,根据奖励矩阵 R R R给出奖励 r r r。
- 存储经验:将经验存入缓冲区。
- 采样并更新网络:从缓冲区中随机采样一批数据计算目标值。
更新主网络参数 θ θ θ以最小化损失函数 L ( θ ) L(θ) L(θ)。 - 同步目标网络:每隔若干步,将主网络参数复制到目标网络。
- 测试(关闭探索,使用网络预测的动作观察智能体是否能够成功从起点走到终点)。
【欢迎指正】
相关文章:
【机器学习】强化学习(2)——捋清深度强化学习的思路
在之前学习的过程中我了解到深度学习中很重要的一个概念是反向传播,最近看论文发现深度强化学习(DRL)有各种各样的方法,但是却很难区分他们的损失函数的计算以及反向传播的过程有何不同。在有监督的学习中,损失可以理解…...
touchgfx的工作机制
touchgfx的工作机制 一.MVP软件架构 MVP的全称为Model-View-Presenter Model: 就是数据部分,在整个touchgfx应用中,只有一个Model类实例对象,它为所有的Screen屏幕界面服务,可以理解成是一个全局变量区,同时它还负责和后端系统通信 View: 就是UI界面部分,对应于View类,在整…...
Fisher信息矩阵(Fisher Information Matrix, FIM)与自然梯度下降:机器学习中的优化利器
Fisher信息矩阵与自然梯度下降:机器学习中的优化利器 在机器学习尤其是深度学习中,优化模型参数是一个核心任务。我们通常依赖梯度下降(Gradient Descent)来调整参数,但普通的梯度下降有时会显得“笨拙”,…...
2025数学建模竞赛汇总,错过再等一年
01、2025第十届数维杯大学生数学建模挑战赛(小国赛) 竞赛介绍:数学建模行业内仅次于国赛和美赛的的第三赛事,被多所高校认定为国家级二类竞赛。赛题类型是国内唯一和高教社杯国赛题型风格完全一致的全国性数学建模竞赛࿰…...
设计模式教程:观察者模式(Observer Pattern)
一、模式概述 观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系。一个对象(称为主题)状态发生变化时,所有依赖于它的对象(称为观察者)都会自动得到…...
代码随想录算法训练营第九天| 151.翻转字符串里的单词、右旋转字符串 、28. 实现 strStr()、459.重复的子字符串、字符串总结
151.翻转字符串里的单词 题目链接:151.翻转字符串里的单词 文档讲解:代码随想录翻转字符串里的单词 视频讲解:LeetCode:翻转字符串里的单词 状态:参考自己写出来的 思路: 反转:思路很清晰&#…...
bpmn.js + Node.js_构建高效的后端工作流处理系统
1. 引言 1.1 研究背景与意义 随着企业业务的复杂化,传统的流程管理工具已难以满足需求。BPMN(Business Process Model and Notation)作为一种标准化的流程建模语言,结合 bpmn.js 和 Node.js 可以实现高效的工作流管理系统,提升企业的运营效率。 1.3 BPMN 和 bpmn.js 简…...
DeepSeek系统架构的逐层分类拆解分析,从底层基础设施到用户端分发全链路
一、底层基础设施层 1. 硬件服务器集群 算力单元: GPU集群:基于NVIDIA H800/H100 GPU构建,单集群规模超10,000卡,采用NVLink全互联架构实现低延迟通信。国产化支持:适配海光DCU、寒武纪MLU等国产芯片,通过…...
嵌入式硬件基础知识
1.电阻(主要是贴片电阻) 01 基础课程-电阻 1.电阻封装 2.相关参数 1.功率额定值: 电阻能够长期承受的最大功率,功率过大可能导致电阻过热或损坏。封装尺寸越大,散热能力越强,功率额定值通常越高。 2.容差: 电阻…...
springboot+dubbo+zookeeper的注册服务和调用实践
目录 zookeeper为什么可作为注册中心zookeeper注册中心优缺点启动zookeeper编写springboot项目提供dubbo服务1. 服务接口2. Springboot引入dubbo实现服务接口2.1 工程目录和依赖2.2 启动程序和application.properties2.3 DubboService 实现服务接口2.4 测试api,用于…...
ARM Cortex-M处理器中的MSP和PSP
在ARM Cortex-M系列处理器中,MSP(主堆栈指针)和PSP(进程堆栈指针)是两种不同的堆栈指针,主要用于实现堆栈隔离和提升系统可靠性。以下是它们的核心区别和应用场景: 1. 基本定义 MSP(…...
计算机网络:应用层 —— 电子邮件
文章目录 电子邮件的起源与发展电子邮件的组成电子邮件协议邮件发送和接收过程邮件发送协议SMTP协议多用途因特网邮件扩展MIME 电子邮件的信息格式 邮件读取协议邮局协议POP因特网邮件访问协议IMAP 基于万维网的电子邮件 电子邮件(E-mail)是因特网上最早…...
Vue3 + Spring WebMVC 验证码案例中的跨域问题与解决方法
最近在基于vue3 SpringWebMVC前后端分离的开发环境中实现一个验证码的案例,在开发过程中遇到了一些复杂的跨域问题,现已解决,故将解决方法分享,希望能帮到有需要的人。 出现的问题: 对于验证码的实现,我选…...
【Python爬虫(60)】解锁社交媒体数据宝藏:Python爬虫实战攻略
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...
Comfy UI 快捷键
Comfy UI 页面的快捷键操作(记录下,以防忘记): 捷径命令Ctrl Enter将当前图表排队等待生成Ctrl Shift Enter将当前图表排成第一个生成图表Ctrl Z/Ctrl Y撤消/重做Ctrl S保存工作流程Ctrl O加载工作流Ctrl A选择所有节点A…...
【C++】Arrays
《C程序设计基础教程》——刘厚泉,李政伟,二零一三年九月版,学习笔记 文章目录 1、一维数组的定义与初始化1.1、一维数组的定义1.2、一维数组的初始化 2、一维数组的使用3、一维数组与函数4、二维数组4.1、二维数组的定义4.2、二维数组的初始…...
EX_25/2/24
写一个三角形类,拥有私有成员 a,b,c 三条边 写好构造函数初始化 abc 以及 abc 的set get 接口 再写一个等腰三角形类,继承自三角形类 1:写好构造函数,初始化三条边 2:要求无论如何,等腰三角形类对象&#x…...
批量导出数据库表到Excel
这篇文章将介绍如何批量的将多个甚至成千上万的数据库表导出为Excel文件。 准备数据 如下图是数据库里的表,我们需要将它们全部导出为excel文件,这里以SQL Server数据库为例 新增导出 打开的卢导表工具,新建数据库连接,这里以S…...
代码随想录D52-53 图论 Python
目录 101. 孤岛的总面积 102. 沉没孤岛 103. 水流问题 104. 建造最大岛屿 101. 孤岛的总面积 要点: 整体来说是一个图着色的问题。 这道题目的思路符合直觉,但代码实现会和直觉有差别。如果仅使用visit记录不使用着色,会遇到非常多的…...
机器学习(部分算法、模型)
一、KNN 算法 原理 K-近邻算法(K-Nearest Neighbors,简称KNN),根据K个邻居样本的类别来判断当前样本的类别; 如果一个样本在特征空间中的k个最相似(最邻近)样本中的大多数属于某个类别,则该类本也属于这个类别 比如: 有10000个样…...
axios几种请求类型的格式
Axios 是一个基于 Promise 的 HTTP 客户端,广泛用于浏览器和 Node.js 中发送 HTTP 请求。它支持多种请求格式,包括 GET、POST、PUT、DELETE 等。也叫RESTful 目录 一、axios几种请求类型的格式 1、get请求 2、post请求 3、put请求 4、delete请求 二…...
SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)
SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密) 前言 在SpringBoot的项目开发中,大多数情况下 yml 配置文件中存储的密码均以明文形式展示,这种方式显然存在较大的安全隐患。一旦有开发人员离职&…...
【C语言】指针笔试题
前言:上期我们介绍了sizeof与strlen的辨析以及sizeof,strlen相关的一些笔试题,这期我们主要来讲指针运算相关的一些笔试题,以此来巩固我们之前所学的指针运算! 文章目录 一,指针笔试题1,题目一…...
力扣 下一个排列
交换位置,双指针,排序。 题目 下一个排列即在组成的排列中的下一个大的数,然后当这个排列为降序时即这个排列最大,因为大的数在前面,降序排列的下一个数即升序。所以,要是想找到当前排列的下一个排列&…...
Three.js 快速入门教程【八】常见材质类型
系列文章目录 Three.js 快速入门教程【一】开启你的 3D Web 开发之旅 Three.js 快速入门教程【二】透视投影相机 Three.js 快速入门教程【三】渲染器 Three.js 快速入门教程【四】三维坐标系 Three.js 快速入门教程【五】动画渲染循环 Three.js 快速入门教程【六】相机控件 Or…...
python~http的请求参数中携带map
背景 调试 http GET请求的 map 参数,链路携带参数一直有问题,最终采用如下方式携带map 解决 user{"demo":"true","info":"王者"}url encode之后的效果如下所示 user%7B%22demo%22:%22true%22,%22info%22:%22…...
爬虫第九篇-结束爬虫循环
最近在学习Python爬虫的过程中,遇到了一个很有趣的问题:如何优雅地结束爬虫循环?今天,我想和大家分享一下我的发现和心得。 一、爬虫循环结束的常见问题 在写爬虫时,我们经常会遇到这样的情况:当爬取到的…...
考研/保研复试英语问答题库(华工建院)
华南理工大学建筑学院保研/考研 英语复试题库,由华工保研er和学硕笔试第一同学一起整理,覆盖面广,助力考研/保研上岸!需要👇载可到文章末尾见小🍠。 以下是主要内容: Part0 复试英语的方法论 Pa…...
《Effective Objective-C》阅读笔记(中)
目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…...
前端如何解决跨域
解决前端跨域问题有多种方法 JSONP:利用 <script> 标签的跨域能力,通过动态创建 script 标签并指定回调函数来获取数据。但只能处理 GET 请求,安全性较低。 JSONP 的原理是利用了 <script> 标签的跨域能力。因为浏览器允许 <…...
【HDLbits--Comb组合逻辑】
HDLbits--Comb组合逻辑 1.5 组合逻辑1.5 Demo 在 Verilog 中,组合逻辑(Combinational Logic)是指输出仅依赖于当前输入的逻辑电路,没有记忆功能(即没有状态存储)。组合逻辑的特点是: 无时钟信号…...
如何在 Linux 上安装和配置 Zsh
文章目录 如何在 Linux 上安装和配置 Zsh1. 安装 Zsh1.1 在 Ubuntu/Debian 上安装1.2 在 CentOS/RHEL/Fedora 上安装1.3 在 Arch Linux 上安装1.4 验证 Zsh 安装 2. 设置 Zsh 为默认 Shell2.1 验证默认 shell 3. 配置 Zsh3.1 使用 Oh My Zsh3.1.1 安装 Oh My Zsh3.1.2 启用插件…...
Chromedriver与Chrome版本映射表
Chromedriver与Chrome版本映射表如下: Chrome 71-73版本对应Chromedriver 2.46Chrome 70-72版本对应Chromedriver 2.45Chrome 69-71版本对应Chromedriver 2.44Chrome 68-70版本对应Chromedriver 2.43Chrome 67-69版本对应Chromedriver 2.42…...
HarmonyOS学习第7天: 文本组件点亮界面的文字魔法棒
一、引言 在 HarmonyOS 那丰富多彩的系统界面中,从简洁直观的应用图标,到交互流畅的操作菜单,再到生动形象的图文展示,每一处细节都经过精心雕琢,为用户带来了独特而美妙的视觉与交互体验。而在这琳琅满目的界面元素中…...
06C语言——指针
一、指针入门 (1)、准备知识 0、图解: 1、内存地址 字节:字节是内存的容量单位,英文称为 byte,一个字节有8位,即 1byte(0000 0000 --- 1111 1111) 8bits(0 --- 1) 地址:系统为了便于区分每一个字节而对…...
Ubuntu DeepSeek磁盘空间不够解决办法
标签: Ubuntu; DeepSeek磁盘空间不够解决办法;Ubuntu 22, DeepSeek R1 671 B, solution for Insufficient Disk Space 问题:Ubuntu 22, DeepSeek R1 671B 磁盘空间不够解决办法 Ubuntu 22.04操作系统,台式…...
东信营销科技巨额补贴仍由盈转亏:毛利率大幅下滑,现金流告急
《港湾商业观察》施子夫 近期,东信营销科技有限公司(以下简称,东信营销科技)递表港交所,联席保荐机构为海通国际和中银国际。 东信营销科技的国内运营主体为深圳市东信时代信息技术有限公司。尽管期内收入规模有所提…...
Qt layout
文章目录 Qt layout**关键机制****验证示例****常见误区****最佳实践****总结**关键点总结:示例代码说明:结论: Qt layout 在 Qt 中,当调用 widget->setLayout(layout) 时,layout 的父对象会被自动设置为该 widget…...
本地部署轻量级web开发框架Flask并实现无公网ip远程访问开发界面
文章目录 1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 本篇文章主要讲解如何在本地安装Flask,以及如何将其web界面发布到公网进行远程访问。 Flask是目前十分流行的web框架,采用Python编程…...
基于YOLO11深度学习的苹果叶片病害检测识别系统【python源码+Pyqt5界面+数据集+训练代码】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
Android MMKV集成指南
首先简单介绍一下MMKV当下Android Studio最版本及Gradle8.7 MMKV集成根据官方文档重新对mmkv重新包了一次(便于开发)总结首先简单介绍一下MMKV MMKV 是腾讯开源的一款专为移动端设计的高性能键值存储组件,旨在替代传统的 SharedPreferences 和 SQLite,尤其在频繁读写和数据…...
React七Formik
Formik是一个专为React构建的开源表单库。它提供了一个易于使用的API来处理表单状态管理,表单验证以及表单提交。Formik支持React中的所有表单元素和事件,可以很好地与React生态系统中的其他库集成。同时,Formik还提供了一些高级功能…...
5分钟使用Docker部署Paint Board快速打造专属在线画板应用
文章目录 前言1.关于Paint Board2.本地部署paint-board3.使用Paint Board4.cpolar内网穿透工具安装5.创建远程连接公网地址6.固定Paint Board公网地址 💡 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住…...
可狱可囚的爬虫系列课程 14:10 秒钟编写一个 requests 爬虫
一、前言 当重复性的工作频繁发生时,各种奇奇怪怪提高效率的想法就开始萌芽了。当重复代码的模块化封装已经不能满足要求的时候,更高效的方式就被揭开了神秘的面纱。本文基于这样的想法,来和大家探讨如何 10 秒钟编写一个 requests 爬虫程序。…...
【深度学习神经网络学习笔记(三)】向量化编程
向量化编程 向量化编程前言1、向量化编程2、向量化优势3、正向传播和反向传播 向量化编程 前言 向量化编程是一种利用专门的指令集或并行算法来提高数据处理效率的技术,尤其在科学计算、数据分析和机器学习领域中非常常见。它允许通过一次操作处理整个数组或矩阵的…...
PHP入门基础学习四(PHP基本语法)
运算符 运算符,专门用于告诉程序执行特定运算或逻辑操作的符号。根据运算符的作用,可以将PHP语言中常见的运算符分为9类 算数运算符: 是用来处理加减乘除运算的符号 也是最简单和最常用的运算符号 赋值运算符 1. 是一个二元运算符&#x…...
【十二】Golang 映射
💢欢迎来到张胤尘的开源技术站 💥开源如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 映射映射的定义映射初始化make 函数使用字面量 源…...
简单理解Oracle中的latch
可以用一个小卖部抢购的例子来理解 Oracle 数据库中的 Latch: 1、 什么是 Latch? 打个比方,假设数据库的某个内存区域(比如缓存的数据块)是小卖部货架上的最后一包辣条,Latch 就像是货架前的一个狭窄通道&a…...
hbase集群部署
1.hbase集群的搭建(以及内部逻辑) 虽然Hmaster有多个,但是属于热备,起作用的就active上的这个。 部署流程: 因为我配置的hadoop是一个非HA的,所以修改为以下 如果是HA的hadoop一定要做以下这一步。 在启动…...
塔能物联运维保障智慧地下停车场安全与高效
一、智慧地下停车场安全在城市升级改造中的关键地位 随着城市的不断发展和升级改造,智慧地下停车场的重要性日益凸显。在现代城市中,土地资源愈发珍贵,地下停车场成为解决停车难题的关键设施。然而,停车场的安全问题是其正常运行和…...