【人工智能机器学习基础篇】——深入详解强化学习之常用算法Q-Learning与策略梯度,掌握智能体与环境的交互机制
深入详解强化学习之常用算法:Q-Learning与策略梯度
强化学习(Reinforcement Learning, RL)作为机器学习的一个重要分支,近年来在多个领域取得了显著成果。从棋类游戏的人机对战到自主驾驶汽车,强化学习技术展示了其强大的潜力。本文将深入探讨强化学习中的常用算法,重点介绍Q-Learning和策略梯度方法,详细阐述其关键概念、核心原理、示例及主要应用,帮助读者全面掌握智能体与环境的交互机制。
目录
深入详解强化学习之常用算法:Q-Learning与策略梯度
1. 引言
2. 强化学习概述
关键概念
智能体与环境的交互机制
3. Q-Learning
核心原理
算法步骤
示例:网格世界(Grid World)
主要应用
4. 策略梯度方法
核心原理
常见策略梯度算法
REINFORCE
Actor-Critic
示例:CartPole平衡
主要应用
5. 比较与选择
6. 深度强化学习
深度Q网络(DQN)
深度确定性策略梯度(DDPG)
7. 总结与展望
8. 参考资料
1. 引言
强化学习是一种通过与环境交互来学习最优策略的机器学习方法。与监督学习和无监督学习不同,强化学习关注的是智能体(Agent)在环境中采取行动以最大化累积奖励的过程。理解强化学习中的常用算法,如Q-Learning和策略梯度方法,对于解决复杂的决策和控制问题至关重要。
2. 强化学习概述
关键概念
在深入算法之前,理解强化学习的基本概念至关重要:
- 智能体(Agent):执行动作以与环境互动的实体。
- 环境(Environment):智能体互动的外部系统,对智能体的动作做出反应。
- 状态(State, S):环境在某一时刻的具体情况。
- 动作(Action, A):智能体在特定状态下可以采取的行为。
- 奖励(Reward, R):智能体执行动作后,环境给予的反馈信号,用于指导学习。
- 策略(Policy, π):智能体选择动作的策略,可以是确定性的(π(s) = a)或随机的(π(a|s))。
- 价值函数(Value Function, V):评估在状态s下,智能体未来能获得的累积奖励。
- 状态-动作价值函数(Q-Function, Q):评估在状态s下采取动作a,智能体未来能获得的累积奖励。
智能体与环境的交互机制
强化学习的核心是通过试错与环境进行互动,智能体在每一步选择一个动作,环境返回一个奖励和下一个状态。智能体的目标是学习一个策略,使得在长期内累积的奖励最大化。这一过程可以形式化为马尔可夫决策过程(Markov Decision Process, MDP)。
3. Q-Learning
核心原理
Q-Learning是一种基于价值的强化学习算法,通过学习状态-动作价值函数Q(s, a),实现最优策略的逼近。Q-Learning的核心思想是通过迭代更新Q值,使其逐步逼近真实的Q值。
Q-Learning的更新公式为:
\[
Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left[ r_{t+1} + \gamma \max_{a} Q(s_{t+1}, a) - Q(s_t, a_t) \right]
\]
其中:
- \( s_t \)是当前状态
- \( a_t \) 是当前动作
- \( r_{t+1} \) 是执行动作后的奖励
- \( \gamma \) 是折扣因子(通常介于0和1之间)
- \( \alpha \) 是学习率
算法步骤
Q-Learning的基本步骤如下:
- 初始化Q表(Q(s, a))为任意值(通常为0)。
- 对于每一个回合:
- 初始化环境,获取初始状态s。
- 对于每一个时间步:
- 根据当前策略(如ε-贪心策略)选择动作a。
- 执行动作a,观察奖励r和下一个状态s'。
- 更新Q值:
\[
Q(s, a) \leftarrow Q(s, a) + \alpha \left[ r + \gamma \max_{a'} Q(s', a') - Q(s, a) \right]
\] - 将状态s更新为s'。
- 若达到终止状态,则结束当前回合。
示例:网格世界(Grid World)
下面通过一个简单的网格世界展示Q-Learning的应用。假设智能体在一个4x4的网格中移动,目标是从起点到达终点。
import numpy as np
import random# 定义网格世界
class GridWorld:def __init__(self):self.size = 4self.start = (0, 0)self.end = (3, 3)self.state = self.startself.actions = ['up', 'down', 'left', 'right']def reset(self):self.state = self.startreturn self.statedef step(self, action):x, y = self.stateif action == 'up':x = max(x - 1, 0)elif action == 'down':x = min(x + 1, self.size - 1)elif action == 'left':y = max(y - 1, 0)elif action == 'right':y = min(y + 1, self.size - 1)self.state = (x, y)if self.state == self.end:return self.state, 1, True # 奖励1,终止else:return self.state, 0, False # 奖励0,继续# Q-Learning算法
def q_learning(env, episodes=500, alpha=0.1, gamma=0.9, epsilon=0.1):Q = {}for x in range(env.size):for y in range(env.size):Q[(x, y)] = {a: 0 for a in env.actions}for episode in range(episodes):state = env.reset()done = Falsewhile not done:# ε-贪心策略if random.uniform(0, 1) < epsilon:action = random.choice(env.actions)else:action = max(Q[state], key=Q[state].get)next_state, reward, done = env.step(action)# Q值更新Q[state][action] += alpha * (reward + gamma * max(Q[next_state].values()) - Q[state][action])state = next_statereturn Q# 训练代理
env = GridWorld()
Q = q_learning(env)# 展示学习后的策略
def print_policy(Q, env):policy_actions = {'up': '↑', 'down': '↓', 'left': '←', 'right': '→'}for x in range(env.size):row = ''for y in range(env.size):if (x, y) == env.end:row += ' G 'else:action = max(Q[(x, y)], key=Q[(x, y)].get)row += ' ' + policy_actions[action] + ' 'print(row)print_policy(Q, env)
代码说明:
-
GridWorld类:定义一个4x4的网格环境,智能体从(0,0)出发,目标是到达(3,3)。每次动作后,如果到达终点,获取奖励1并终止回合;否则,奖励为0。
-
q_learning函数:实现Q-Learning算法,初始化Q表,采用ε-贪心策略选择动作,并根据奖励和最大Q值更新Q表。
-
print_policy函数:展示学习后的策略,用箭头表示智能体在不同状态下的最佳动作。
结果展示:
→ ↓ → ↓ ↑ → → ↓ ↑ ↑ → ↓ ← ← ← G
上述策略表明,智能体在各个状态下最优的动作方向,通过学习能够有效地从起点到达终点。
上述策略表明,智能体在各个状态下最优的动作方向,通过学习能够有效地从起点到达终点。
主要应用
Q-Learning广泛应用于各种决策和控制问题,主要包括:
- 游戏AI:如Atari游戏、棋类游戏等智能体的策略学习。
- 机器人导航:机器人在未知环境中的路径规划与避障。
- 推荐系统:根据用户行为动态调整推荐策略。
- 自动驾驶:车辆在复杂交通环境中的决策与控制。
4. 策略梯度方法
核心原理
策略梯度方法是基于策略优化的强化学习算法,直接优化策略函数π(a|s; θ),使得预期累积奖励最大化。与基于价值的方法(如Q-Learning)不同,策略梯度不依赖于价值函数,而是直接通过梯度上升来优化策略参数。
目标函数:
\[
J(\theta) = \mathbb{E}_{\pi_\theta} \left[ \sum_{t=0}^{T} \gamma^t r_t \right]
\]
策略梯度的更新规则基于梯度上升:
\[
\theta \leftarrow \theta + \alpha \nabla_\theta J(\theta)
\]
其中,梯度可以通过“策略梯度定理”得到:
\[
\nabla_\theta J(\theta) = \mathbb{E}_{\pi_\theta} \left[ \sum_{t=0}^{T} \nabla_\theta \log \pi_\theta(a_t|s_t) G_t \right]
\]
其中,\( G_t \) 是从时间步t开始的累积奖励。
常见策略梯度算法
REINFORCE
REINFORCE是最基础的策略梯度算法,又称为蒙特卡罗策略梯度。其特点是使用完整的回合数据进行更新。
算法步骤:
1. 初始化策略参数θ。
2. 对于每一个回合:
生成一个完整的回合,记录状态、动作和奖励。
计算每个时间步的累积奖励 \( G_t \)。
更新策略参数:
\[
\theta \leftarrow \theta + \alpha \sum_{t} \nabla_\theta \log \pi_\theta(a_t|s_t) G_t
\]
Actor-Critic
Actor-Critic结合了策略梯度和值函数的方法,利用一个“演员”(Actor)来更新策略,一个“评论家”(Critic)来评估当前策略的价值函数,从而提高学习效率。
算法步骤:
1. 初始化策略参数θ(Actor)和价值函数参数ϕ(Critic)。
2. 对于每一个时间步:
根据策略π(a|s; θ)选择动作a。
执行动作a,观察奖励r和下一个状态s'。
计算TD误差:
\[
\delta = r + \gamma V(s'; \phi) - V(s; \phi)
\]
更新Critic参数:
\[
\phi \leftarrow \phi + \alpha_c \delta \nabla_\phi V(s; \phi)
\]
更新Actor参数:
\[
\theta \leftarrow \theta + \alpha_a \delta \nabla_\theta \log \pi(a|s; \theta)
\]
示例:CartPole平衡
以经典的CartPole环境为例,演示策略梯度方法的应用。智能体需要通过移动小车,使得杆子保持平衡。
import gym
import numpy as np
import tensorflow as tf
from tensorflow.keras import layers# 创建环境
env = gym.make('CartPole-v1')num_states = env.observation_space.shape[0]
num_actions = env.action_space.n# 构建策略网络
model = tf.keras.Sequential([layers.Dense(24, activation='relu', input_shape=(num_states,)),layers.Dense(24, activation='relu'),layers.Dense(num_actions, activation='softmax')
])optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)
gamma = 0.99# 策略梯度算法
def policy_gradient():state = env.reset()state = np.reshape(state, [1, num_states])done = Falserewards = []actions = []states = []while not done:action_probs = model(state).numpy()[0]action = np.random.choice(num_actions, p=action_probs)next_state, reward, done, _ = env.step(action)next_state = np.reshape(next_state, [1, num_states])states.append(state)actions.append(action)rewards.append(reward)state = next_state# 计算累积奖励discounted_rewards = []cumulative = 0for r in rewards[::-1]:cumulative = r + gamma * cumulativediscounted_rewards.insert(0, cumulative)discounted_rewards = np.array(discounted_rewards)discounted_rewards -= np.mean(discounted_rewards)discounted_rewards /= (np.std(discounted_rewards) + 1e-8)with tf.GradientTape() as tape:loss = 0for logit, action, reward in zip(model(np.concatenate(states)), actions, discounted_rewards):loss += -tf.math.log(logit[action]) * rewardgrads = tape.gradient(loss, model.trainable_variables)optimizer.apply_gradients(zip(grads, model.trainable_variables))return np.sum(rewards)# 训练智能体
episodes = 1000
for episode in range(episodes):total_reward = policy_gradient()if (episode + 1) % 100 == 0:print(f'Episode: {episode + 1}, Total Reward: {total_reward}')env.close()
代码说明:
- 环境创建:使用OpenAI Gym中的CartPole环境。
- 策略网络:构建一个两层隐藏层的神经网络,输出层使用Softmax激活函数,表示每个动作的概率。
- 策略梯度函数(policy_gradient):
- 运行一个完整的回合,记录状态、动作和奖励。
- 计算每个时间步的折扣累积奖励,并进行标准化。
- 使用梯度带(Gradient Tape)计算损失函数的梯度,并更新策略网络参数。
- 训练过程:进行1000个回合的训练,每100个回合输出一次总奖励。
结果说明:
随着训练的进行,智能体通过策略梯度方法逐步学会保持杆子的平衡,累积奖励不断增加,最终能够稳定地控制小车平衡杆子。
主要应用
策略梯度方法在需要连续动作空间和复杂策略优化的任务中表现优异,主要应用包括:
- 机器人控制:如机械臂的精确控制、自主导航。
- 游戏AI:如复杂策略游戏中的智能对手。
- 金融交易:模拟和优化交易策略,进行高频交易决策。
- 自然语言处理:如对话生成、文本摘要等任务中的策略优化。
5. 比较与选择
Q-Learning和策略梯度方法各有优缺点,选择合适的算法取决于具体应用场景:
- Q-Learning:
- 优点:
- 简单易实现,适用于离散动作空间。
- 理论基础扎实,收敛性良好。
- 缺点:
- 难以扩展到高维和连续动作空间。
- 对于大型状态空间,Q表难以存储和更新。
- 优点:
- 策略梯度方法:
- 优点:
- 适用于高维和连续动作空间。
- 能够直接优化策略,处理复杂策略类型。
- 缺点:
- 收敛速度较慢,易受局部最优影响。
- 需要大量样本进行训练,训练不稳定性较高。
- 优点:
在实际应用中,深度强化学习(Deep Reinforcement Learning, DRL)结合了深度学习与强化学习的优势,采用神经网络近似价值函数或策略,广泛应用于复杂任务中。
6. 深度强化学习
深度强化学习通过使用深度神经网络作为函数逼近器,解决了传统强化学习在高维状态空间和复杂任务中的局限性。典型的深度强化学习算法包括深度Q网络(Deep Q-Network, DQN)和深度确定性策略梯度(Deep Deterministic Policy Gradient, DDPG)等。
深度Q网络(DQN)
DQN通过使用神经网络近似Q函数,解决了Q-Learning在高维状态空间中的问题。DQN引入经验回放和目标网络,提升了训练的稳定性和效率。
关键技术:
- 经验回放(Experience Replay):将智能体的经验存储在缓冲区中,随机采样进行训练,打破数据的时间相关性。
- 目标网络(Target Network):使用一个固定的目标网络来稳定Q值的更新,减少训练过程中的震荡。
深度确定性策略梯度(DDPG)
DDPG是一种适用于连续动作空间的深度强化学习算法,结合了策略梯度和确定性策略的方法。DDPG使用两个神经网络:一个是策略网络(Actor),另一个是价值网络(Critic),通过经验回放和软更新机制提升训练稳定性。
7. 总结与展望
本文深入探讨了强化学习中的两大主流算法:Q-Learning和策略梯度方法,详细介绍了其关键概念、核心原理、示例及主要应用。Q-Learning作为基于价值的方法,适用于离散动作空间,简单易实现;而策略梯度方法适用于复杂和连续动作空间,能够直接优化策略。通过对比与分析,可以根据具体任务选择合适的算法。
随着计算能力的提升和深度学习技术的发展,深度强化学习(DRL)进一步拓展了强化学习的应用范围,解决了许多传统方法难以应对的复杂问题。未来,强化学习将在更多领域发挥重要作用,如智能制造、智能医疗、无人驾驶等,推动人工智能技术的进一步发展。
8. 参考资料
- 《强化学习:An Introduction》(Richard S. Sutton, Andrew G. Barto 著)
- DeepMind的DQN论文:Mnih, V., et al. (2015). "Human-level control through deep reinforcement learning."
- OpenAI Gym官方文档:Gym Documentation
- TensorFlow官方网站:https://www.tensorflow.org/
- PyTorch官方网站:PyTorch
【此文为作者经过搜集资料,整理及编辑而成,仅供学习者参考。本文属于个人学习过程中对于人工智能相关知识概念进行的整合作品,如需更详细的信息和扩展内容,建议参考相关专业书籍和学术论文,若有不当之处可进行指正,共同学习交流!】
相关文章:

【人工智能机器学习基础篇】——深入详解强化学习之常用算法Q-Learning与策略梯度,掌握智能体与环境的交互机制
深入详解强化学习之常用算法:Q-Learning与策略梯度 强化学习(Reinforcement Learning, RL)作为机器学习的一个重要分支,近年来在多个领域取得了显著成果。从棋类游戏的人机对战到自主驾驶汽车,强化学习技术展示了其强大…...

银河麒麟桌面v10sp1修复引导笔记
1.安装双系统最好备份esp分区,uefi引导丢失可以用diskgen,选择工具再点击设置uefi bios,鼠标右键选择efi文件。 2.银河麒麟界面添加windows,复制EFI/Microsoft或者pe生成引导文件后,修复Windows引导用下面命令 /桌面# update-gru…...

深入理解 MVCC 与 BufferPool 缓存机制
深入理解 MVCC 与 BufferPool 缓存机制 在 MySQL 数据库中,MVCC(Multi-Version Concurrency Control)多版本并发控制机制和 BufferPool 缓存机制是非常重要的概念,它们对于保证数据的一致性、并发性以及提升数据库性能起着关键作用…...

vue实现下拉多选、可搜索、全选功能
最后的效果就是树形的下拉多选,可选择任意一级选项,下拉框中有一个按钮可以实现全选,也支持搜索功能。 在mounted生命周期里面获取全部部门的数据,handleTree是讲接口返回的数据整理成树形结构,可以自行解决 <div c…...

探秘Kafka源码:关键内容解析
文章目录 一、以kafka-3.0.0为例1.1安装 gradle 二、生产者源码2.1源码主流程图2.2 初始化2.3生产者sender线程初始化2.4 程序入口2.5生产者 main 线程初始化2.6 跳转到 KafkaProducer构造方法 一、以kafka-3.0.0为例 打开 IDEA,点击 File->Open…->源码包解…...

Android音频效果处理:基于`android.media.audiofx`包的原理、架构与实现
Android音频效果处理:基于android.media.audiofx包的原理、架构与实现 目录 引言Android音频框架概述android.media.audiofx包简介音频效果处理的原理 4.1 音频信号处理基础4.2 常见音频效果android.media.audiofx的架构设计 5.1 类结构分析5.2 设计模式应用系统定制与扩展 6…...

LeetCode - 初级算法 数组(两个数组的交集 II)
两个数组的交集 II 这篇文章讨论如何求两个数组的交集,并返回结果中每个元素出现的次数与其在两个数组中都出现的次数一致。提供多个实现方法以满足不同场景需求。 免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 描述 给定两个整数数组 nums1 和 nums2,以数…...

SQL 实战:分页查询的多种方式对比与优化
在处理大数据表时,分页查询是非常常见的需求。分页不仅可以提高用户体验,还能有效减少数据库查询返回的数据量,避免一次性加载大量记录引起的性能瓶颈。 然而,在数据量较大或复杂查询中,简单的分页方式可能导致性能下降…...
汇川Easy系列正弦信号发生器(ST源代码)
正弦余弦信号发生器CODESYS和MATLAB实现请参考下面文章链接: 正弦余弦信号发生器应用(CODESYS ST源代码+MATLAB仿真)_st语言根据输入值,形成正弦点-CSDN博客文章浏览阅读410次。本文介绍了如何在CODESYS编程环境中创建正弦和余弦信号发生器。通过详细的PLC梯形图和SCL语言代码…...

JavaSpring AI与阿里云通义大模型的集成使用Java Data Science Library(JDSL)进行数据处理
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默, 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……) 2、学会Oracle数据库入门到入土用法(创作中……) 3、手把…...

Three.js教程002:Three.js结合Vue进行开发
文章目录 Three.js结合Vue开发创建Vue项目安装依赖运行项目安装three使用three.js完整代码下载Three.js结合Vue开发 创建Vue项目 创建命令: npm init vite@latest框架这里选择【Vue】: 安装依赖 安装命令: cd 01-vueapp npm install运行项目 npm run dev...

pycharm+anaconda创建项目
pycharmanaconda创建项目 安装: Windows下PythonPyCharm的安装步骤及PyCharm的使用-CSDN博客 详细Anaconda安装配置环境创建教程-CSDN博客 创建项目: 开始尝试新建一个项目吧! 选择好项目建设的文件夹 我的项目命名为:pyth…...

vue2中遇到的问题与解决方案(自用)
1 、在vue2中怎么能成功渲染字符串中存在自定义组件 比如,前端样式定义后由接口返回想渲染的样式,如果此时直接使用v-html,那么vue的自定义组件或者ui框架的组件是会被直接引用不能编译成功 解决方案: 此时想到vue官网使用render函…...
CF2043b-B. Digits
题目链接 题意:给定两个整数n、d,要求找出排列成n!个d之后的数可以被1-9中奇数整除的数 题解: 主要是考察分类讨论: 被3整除,当d能被3整除时一定成立或者n > 3,当n > 3时n!一定包含因数3 被5整除&a…...

ultralytics库RT-DETR代码解析
最近读了maskformer以及maskdino的分割头设计,于是想在RT-DETR上做一个分割的改动,所以选择在ultralytics库中对RTDETR进行改进。 本文内容简介: 1.ultralytics库中RT-DETR模型解析 2. 对ultralytics库中的RT-DETR模型增加分割头做实例分割 1.ultralytics库中RT-DETR模型解…...

(七)- plane/crtc/encoder/connector objects
1,framebuffer/plane Rockchip RK3399 - DRM framebuffer、plane基础知识 - 大奥特曼打小怪兽 - 博客园 2,crtc Rockchip RK3399 - DRM crtc基础知识 - 大奥特曼打小怪兽 - 博客园 3,encoder/connector/bridge Rockchip RK3399 - DRM en…...

基于STM32的四轴飞行器的控制系统(论文+源码)
1.系统设计 本次基于stm32单片机的四轴飞行器控制系统主要包括硬件和软件这两大部分,其中硬件部分是基于单片机的四轴飞行器控制系统实现的基石,其中主要STM32单片机负责整个系统功能的实现;NRF24L01无线模块负责对四轴飞行器的远程控制&…...

混合精度训练(Mixed Precision Training)中为什么在训练过程中不直接使用bf16进行权重更新?中英双语
中文版 为什么在训练过程中不直接使用 bf16 进行权重更新? 在深度学习的训练过程中,我们通常使用 混合精度训练(Mixed Precision Training)来提高训练效率,减少内存占用。虽然 bf16(Brain Floating Point…...

【java】HashMap的实现原理
目录 1. 说明2. 哈希函数3. 桶数组4. 哈希冲突解决5. 动态扩容6. 查找、插入和删除操作 1. 说明 1.HashMap是一个基于哈希表的数据结构,它实现了Map接口。2.HashMap允许使用null键和null值,并且不保证映射的顺序。 2. 哈希函数 1.HashMap使用哈希函数…...

FCM32F103C8T6开发指引
打了块板,没有STM芯片了,于是,换了块FCM32F103C8T6.原来的工程直接编译,不能仿真,提示M3,M4核不兼容,但是,用jflash是可以直接把bin文件烧录进去的,也可以正常运行起来。 但为了方便…...

Python世界:人生苦短,我用Python
Python世界:人生苦短,我用Python 前言Python优势Python缺点 前言 几句话说清,我们为啥要用Python? Python设计之初心,是为了解决编程门槛,让大家更聚焦业务实现,而非编程细节。当前人工智能火…...

【从零开始入门unity游戏开发之——C#篇43】C#补充知识——值类型和引用类型汇总补充、变量的生命周期与性能优化、值类型和引用类型组合使用
文章目录 一、值类型和引用类型汇总补充1、值类型和引用类型汇总2、值类型和引用类型的区别3、简单的判断值类型和引用类型 二、变量的生命周期与性能优化1、**栈和堆的区别**2、**变量生命周期**3、**垃圾回收(GC)机制**4、**代码示例与优化**4.1. 临时…...

从论文到实践:Stable Diffusion模型一键生成高质量AI绘画
🏡作者主页:点击! 🤖编程探索专栏:点击! ⏰️创作时间:2024年12月24日10点02分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文源地址有视频: 链接h…...

项目管理:用甘特图 “导航” 项目全程
项目全程管理是一个复杂而又系统的过程,它涵盖了从项目启动到结束的各个阶段,包括规划、执行、监控和收尾等一系列活动。 项目全程管理能够确保项目按时交付、控制成本、提高质量以及满足客户需求。通过有效的管理,项目团队可以避免资源浪费…...

v3.0.8- 「S+会员」新增专属运动秀,试试新穿搭吧- 与「好友」
v3.0.8 - 「S会员」新增专属运动秀,试试新穿搭吧 - 与「好友」互动支持前往对方所在的「在线运动房」 - 「运动秀工坊」新增智能背景抠图 - 「体育竞技」匹配中可以看到我和对手的装备 - 多项界面体验和性能优化 v2.0.17 - 班级运动场新增运动秀展示 - 班级玩法&…...

9-Gin 中自定义 Model --[Gin 框架入门精讲与实战案例]
在 Gin 框架中自定义 Model 通常指的是定义你自己的数据结构,这些结构体(Structs)将用来表示数据库中的表、API 请求的参数或响应的数据格式。下面是如何在 Gin 中创建和使用自定义 Model 的基本步骤。 自定义 Model 定义结构体 首先&…...

【VBA】EXCEL - VBA 创建 Sheet 表的 6 种方法,以及注意事项
目录 1. 创建一个新工作表,并将其添加到工作簿的末尾 2. 创建一个新工作表,并命名它 3. 创建一个新工作表,并将其插入到指定位置 4. 检查是否已有同名工作表,避免重复创建 5. 创建多个工作表 6. 基于现有模板创建新工作表 …...

数据库中,group by 和partition by:数据分组和数据分区的区别
数据库中,group by 和partition by:数据分组和数据分区的区别 在大规模数据处理和分析的场景中,对数据进行分区和分组处理是非常常见的场景。 为了实现这一操作,在一些主流的关系型数据库管理系统中,提供了group by 和…...

【linux学习指南】Ext系列文件系统(四)路径分区链接
文章目录 🌠⽬录与⽂件名🌠路径解析🌠路径缓存🌠挂载分区🌉 ⽂件系统总结 🌠软硬连接🌉 硬链接🌉 软链接🌉 软硬连接对⽐🌉软硬连接的⽤途: &…...

深度学习中的参数初始化
深度学习中的参数初始化主要是指初始化神经网络中的权重和偏置。权重和偏置通常分开初始化,偏置通常初始化为零或较小的常数值。 没有一种万能的初始化技术,因为最佳初始化可能因具体架构和要解决的问题而异。因此,尝试不同的初始化技术以了解…...