David Silver Lecture 6: Value function approximation

news2024/9/21 22:07:35

1 Introduction

pipeline大致讲完了,开始到数值计算的部分。

1.1 大规模的运算

在这里插入图片描述
对于这种大规模运算,如何拓展前面两个章节的内容,进行实战。

1.1.1 回顾value function approximation

在这里插入图片描述
在这里插入图片描述

1.1.3 which function approximator

强化学习中的值函数近似(value function approximation)是一种用于估计值函数(如状态值函数V或状态动作值函数Q)的方法。它的主要作用是在大型或连续状态空间的强化学习问题中提供可扩展的解决方案。值函数近似通过将值函数表示为参数化的函数形式(如线性模型、神经网络、决策树等),可以减少存储和计算需求,从而使得算法在大型和复杂的环境中仍然有效。

线性值函数近似:在这种方法中,值函数用一个线性函数表示,即 V ( s ) = θ T ⋅ ϕ ( s ) V(s) = \theta^T \cdot \phi(s) V(s)=θTϕ(s) Q ( s , a ) = θ T ⋅ ϕ ( s , a ) Q(s,a) = \theta^T \cdot \phi(s,a) Q(s,a)=θTϕ(s,a),其中 θ \theta θ 是参数向量, ϕ ( s ) \phi(s) ϕ(s) ϕ ( s , a ) \phi(s,a) ϕ(s,a) 分别是状态特征向量和状态-动作特征向量。通过调整参数向量 θ \theta θ,我们可以拟合值函数。在线性值函数近似中,特征向量的选择至关重要,因为它们决定了能否有效地表示值函数。

在这里插入图片描述
需要训练方法,适用于non-stationary, non-iid 数据。
下面是一个用线性函数表示Q-table的frozenlake的例子
Q ( s , a ) = θ T ⋅ ϕ ( s , a ) Q(s,a) = \theta^T \cdot \phi(s,a) Q(s,a)=θTϕ(s,a)

import numpy as np
import gym

# 定义状态-动作对到特征向量的映射函数
def state_action_to_feature_vector(state, action):
    num_states = env.observation_space.n
    num_actions = env.action_space.n

    feature_vector = np.zeros(num_states * num_actions)
    index = state * num_actions + action
    feature_vector[index] = 1

    return feature_vector

# 初始化环境
env = gym.make('FrozenLake-v1')
num_states = env.observation_space.n
num_actions = env.action_space.n

# 初始化参数向量
theta = np.zeros(num_states * num_actions)

# 超参数
num_episodes = 5000
alpha = 0.01
gamma = 0.99
epsilon = 0.1

# 开始训练
for episode in range(num_episodes):
    state = env.reset()
    if isinstance(state, tuple):
        state = state[0]
    done = False

    while not done:
        # 使用 epsilon-greedy 策略选择动作
        if np.random.rand() < epsilon:
            action = env.action_space.sample()
        else:
            q_values = [np.dot(theta, state_action_to_feature_vector(state, a)) for a in range(num_actions)]
            action = np.argmax(q_values)

        # 采取动作,观察结果
        next_state, reward, done, _, _ = env.step(action)

        # 计算目标值
        if done:
            target = reward
        else:
            next_q_values = [np.dot(theta, state_action_to_feature_vector(next_state, a)) for a in range(num_actions)]
            target = reward + gamma * np.max(next_q_values)

        # 更新参数向量
        theta += alpha * (target - np.dot(theta, state_action_to_feature_vector(state, action))) * state_action_to_feature_vector(state, action)

        state = next_state

# 测试学习到的策略
num_test_episodes = 100
num_success = 0

for episode in range(num_test_episodes):
    state = env.reset()
    done = False

    while not done:
        q_values = [np.dot(theta, state_action_to_feature_vector(state, a)) for a in range(num_actions)]
        action = np.argmax(q_values)
        state, reward, done, _, _ = env.step(action)

    if reward == 1.0:
        num_success += 1

print(f"成功完成 {num_success} 次测试")

env.close()

对比之前的基于q_table的代码:

import numpy as np
import gym

# 初始化环境
env = gym.make('FrozenLake-v1')

# 初始化参数
n_states = env.observation_space.n
n_actions = env.action_space.n
alpha = 0.1  # 学习率
gamma = 0.99  # 折扣因子
epsilon = 0.1  # Epsilon-greedy策略参数
episodes = 20000  # 迭代次数

# 初始化Q表
q_table = np.zeros((n_states, n_actions))

# Epsilon-greedy策略
def epsilon_greedy_policy(state, q_table, epsilon):
    if np.random.rand() < epsilon:
        return np.random.randint(n_actions)
    else:
        return np.argmax(q_table[state])

# 通过重要性采样更新Q值
def update_q_table_with_importance_sampling(state, action, reward, next_state, q_table, alpha, gamma, epsilon):
    # 使用Q-Learning选择下一个动作
    next_action = np.argmax(q_table[next_state])
    
    # 使用Epsilon-greedy策略选择下一个动作
    behavior_next_action = epsilon_greedy_policy(next_state, q_table, epsilon)
    
    # 计算目标策略和行为策略的概率
    target_policy_prob = 1.0 if action == next_action else 0.0
    behavior_policy_prob = 1 - epsilon + epsilon / n_actions if action == behavior_next_action else epsilon / n_actions
    
    # 计算重要性采样比率
    importance_sampling_ratio = target_policy_prob / behavior_policy_prob
    
    # 计算TD目标和TD误差
    td_target = reward + gamma * q_table[next_state, next_action]
    td_error = td_target - q_table[state, action]
    
    # 使用重要性采样更新Q值
    q_table[state, action] += alpha * importance_sampling_ratio * td_error

# 开始学习
for episode in range(episodes):
    state = env.reset()
    done = False
    
    while not done:
        # 选择动作
        action = epsilon_greedy_policy(state, q_table, epsilon)
        
        # 执行动作并观察结果
        next_state, reward, done, _ = env.step(action)
        
        # 更新Q表
        update_q_table_with_importance_sampling(state, action, reward, next_state, q_table, alpha, gamma, epsilon)
        
        # 更新状态
        state = next_state

print("Q-Table:")
print(q_table)

比较核心代码的区别

## q-table code
action = epsilon_greedy_policy(state, q_table, epsilon)
# 执行动作并观察结果
next_state, reward, done, _ = env.step(action)
# 使用Q-Learning选择下一个动作
next_action = np.argmax(q_table[next_state])

# 计算TD目标和TD误差
td_target = reward + gamma * q_table[next_state, next_action]
td_error = td_target - q_table[state, action]
# 使用重要性采样更新Q值
q_table[state, action] += alpha * td_error
# 更新状态
state = next_state

在Q-table方法中,我们维护了一个表格,其中每个状态-动作对都有一个对应的值。在值函数近似的方法中,我们试图找到一个参数向量 θ \theta θ,使得线性模型能够近似地表示状态-动作值函数。

在线性值函数近似方法中,我们尝试通过学习参数向量 θ \theta θ来逼近真实的Q值。实际上, θ \theta θ的作用类似于Q-table的作用,但它是一个连续的、可微的表示。我们使用梯度下降法来更新 θ \theta θ,以最小化预测值和实际值之间的误差。

请注意,虽然 θ T ⋅ ϕ ( s , a ) \theta^T \cdot \phi(s, a) θTϕ(s,a)和Q-table方法中的 Q ( s , a ) Q(s, a) Q(s,a)都表示状态-动作值,但它们的表示和计算方式是不同的。Q-table方法使用离散的查找表表示Q值,而线性值函数近似方法使用线性模型和参数向量 θ \theta θ表示Q值。
在frozenLake这个例子中,因为状态向量是单位向量

feature_vector = np.zeros(n_states)
feature_vector[state] = 1

if np.random.uniform(0, 1) < epsilon:
    return env.action_space.sample()
else:
    q_values = [np.dot(theta, state_to_feature_vector(state)) for a in range(env.action_space.n)]
    return np.argmax(q_values)
    
next_state, reward, done, _ = env.step(action)
global theta
current_value = np.dot(theta, state_to_feature_vector(state))
next_value = np.dot(theta, state_to_feature_vector(next_state))
td_target = reward + gamma * next_value
td_error = td_target - current_value
theta += alpha * td_error * state_to_feature_vector(state)

2 Incremental methods

2.1 gradient descent

使用增量方法(如梯度下降)可让我们逐渐优化值函数近似。在每个时间步,我们都会收到新的观测数据,使用TD目标和梯度下降来更新我们的参数。这样,在训练的过程中,我们的值函数近似将逐渐变得更加准确。这种增量方法的好处在于它能够在线地学习,而无需等待整个数据集收集完毕。
增量方法(如梯度下降)的关键优势在于它们能够处理不断变化的数据。强化学习中,智能体与环境的交互持续生成新的数据。使用增量方法,我们可以逐步更新我们的值函数近似,并逐步改进我们的策略。这种在线学习方法使得智能体能够适应不断变化的环境,并持续优化其行为。

import numpy as np
import gym

def state_action_to_feature_vector(state, action, num_states, num_actions):
    feature_vector = np.zeros(num_states * num_actions)
    feature_vector[state * num_actions + action] = 1
    return feature_vector

env = gym.make('FrozenLake-v1')
num_states = env.observation_space.n
num_actions = env.action_space.n

theta = np.random.randn(num_states * num_actions)

num_episodes = 5000
alpha = 0.01
gamma = 0.99
epsilon = 0.1

for episode in range(num_episodes):
    state = env.reset()
    done = False

    while not done:
        if np.random.rand() < epsilon:
            action = env.action_space.sample()
        else:
            q_values = [np.dot(theta, state_action_to_feature_vector(state, a, num_states, num_actions)) for a in range(num_actions)]
            action = np.argmax(q_values)

        next_state, reward, done, _ = env.step(action)

        if done:
            target = reward
        else:
            next_q_values = [np.dot(theta, state_action_to_feature_vector(next_state, a, num_states, num_actions)) for a in range(num_actions)]
            target = reward + gamma * np.max(next_q_values)

        theta += alpha * (target - np.dot(theta, state_action_to_feature_vector(state, action, num_states, num_actions))) * state_action_to_feature_vector(state, action, num_states, num_actions)
        state = next_state

体现gradient descent部分如下

next_q_values = [np.dot(theta, state_action_to_feature_vector(next_state, a, num_states, num_actions)) for a in range(num_actions)]
target = reward + gamma * np.max(next_q_values)

loss = (target - np.dot(theta, state_action_to_feature_vector(state, action, num_states, num_actions)))
gradient = - state_action_to_feature_vector(state, action, num_states, num_actions)
theta += -alpha * loss * gradient
# 对比之前不适用gradent descent的代码
current_value = np.dot(theta, state_to_feature_vector(state))
next_value = np.dot(theta, state_to_feature_vector(next_state))
td_target = reward + gamma * next_value
td_error = td_target - current_value
theta += alpha * td_error * state_to_feature_vector(state)

在强化学习中,我们通常使用Temporal Difference(TD)目标作为实际目标值。TD目标是当前奖励加上折扣后的未来预测值。TD误差表示为:
ϕ t = R t + 1 + γ v ^ ( S t + 1 , w ) − v ^ ( S t , w ) \phi_t=R_{t+1} + \gamma \hat{v}(S_{t+1}, \bm{w}) -\hat{v}(S_t, \bm{w}) ϕt=Rt+1+γv^(St+1,w)v^(St,w)

其中 δ t \delta_t δt是TD误差, R t + 1 R_{t+1} Rt+1是下一个时间步的奖励, γ \gamma γ是折扣因子, v ^ ( S t , w ) \hat{v}(S_t, \boldsymbol{w}) v^(St,w)是当前状态值函数的预测值, v ^ ( S t + 1 , w ) \hat{v}(S_{t+1}, \boldsymbol{w}) v^(St+1,w)是下一个状态值函数的预测值, w \boldsymbol{w} w是值函数近似的参数向量。

对于刚才那个例子
L ( θ ) = 1 2 ( t a r g e t − Q ( s , a ) ) 2 L(\theta)=\frac{1}{2}(target - Q(s,a))^2 L(θ)=21(targetQ(s,a))2
∂ L ( θ ) ∂ θ = ( t a r g e t − Q ( s , a ) ) ∗ ( − ϕ ( s , a ) ) \frac{\partial L(\theta)}{\partial \theta} = (target-Q(s,a))*(-\phi(s,a)) θL(θ)=(targetQ(s,a))(ϕ(s,a))

在这里插入图片描述
通过stochastic gradient descent 进行value function approximation
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 Feature Vectors

在这里插入图片描述
在这里插入图片描述

2.2.1 Linear Value function Approximation

在这里插入图片描述

2.2.2 table lookup features

实现了前面线性拟合q-table的例子
在这里插入图片描述
在这里插入图片描述

  • 在monte-carlo中使用value function approximation
    在这里插入图片描述
  • TD-learning with value function approximation
    在这里插入图片描述
  • TD(λ) with Value Function Approximation
    在这里插入图片描述
    在control的时候,使用q值代替v值
    在这里插入图片描述
  • Linear action-value function approximation
    在这里插入图片描述
    在这里插入图片描述

2.3 convergence

2.3.1 convergence of prediction algorithms

在这里插入图片描述

TD does not follow the gradient of any objective function
This is why TD can diverge when off-policy or using
non-linear function approximation
Gradient TD follows true gradient of projected Bellman error
在这里插入图片描述
在这里插入图片描述

3 Batch Methods

batch methods的意义
在这里插入图片描述

3.1 least squares prediction

3.1.1 Least Squares Prediction

通过Least squares的算法找到参数vector w, 最小化 v ^ ( s t , w ) \hat{v}(s_t, \bm{w}) v^(st,w)和target value v t π v_t^{\pi} vtπ的误差
在这里插入图片描述

3.1.2 Stochastic Gradient Descent with Experience Replay

在这里插入图片描述
在这里插入图片描述
用least-square去拟合值函数,解决frozenlake的问题

  • 数据集采集的方法,数据采集策略的选择对学习结果至关重要。如果数据集没有足够的多样性或没有充分探索状态空间,那么学到的策略可能会受到限制。这就是为什么在数据采集阶段,一种平衡探索和利用的策略可能是更好的选择。
    • 随机策略:在这种策略下,智能体在每个状态下都随机选择动作。这种策略可以确保环境的充分探索,但可能无法充分利用已学到的知识。
    • 贪心策略: 这种策略下,智能体始终选择具有最高估计动作值的动作。这种策略充分利用了已学到的知识,但可能在探索方面不足。
    • ε-贪心策略: 这是一种介于随机策略和贪心策略之间的策略。在这种策略下,智能体以1-ε的概率选择具有最高估计动作值的动作,以ε的概率随机选择动作。这种策略在探索和利用之间进行权衡。
    • 其他探索策略: 还有许多其他探索策略,如 UCB(Upper Confidence Bound)算法,它基于置信区间来平衡探索和利用。这些方法通常用于在线学习设置,但也可以用于生成数据集。
  • 目标值:target = reward + gamma * np.max(next_q_values)
  • 状态向量:这个里面采用的是,执行了动作,设置状态向量对应值为1
import numpy as np
import gym

def state_action_to_feature_vector(state, action, num_states, num_actions):
    feature_vector = np.zeros(num_states * num_actions)
    feature_vector[state * num_actions + action] = 1
    return feature_vector

env = gym.make('FrozenLake-v1')
num_states = env.observation_space.n
num_actions = env.action_space.n

theta = np.zeros(num_states * num_actions)

num_episodes = 5000
alpha = 0.01
gamma = 0.99
epsilon = 0.1

# Collect a dataset of state-action pairs, rewards, and next states.
dataset = []
for episode in range(num_episodes):
    state = env.reset()
    done = False

    while not done:
        action = env.action_space.sample()
        next_state, reward, done, _ = env.step(action)
        dataset.append((state, action, reward, next_state))
        state = next_state

# Perform least squares fitting.
X = np.array([state_action_to_feature_vector(s, a, num_states, num_actions) for s, a, r, next_s in dataset])
y = np.array([r + gamma * np.max([np.dot(theta, state_action_to_feature_vector(next_s, next_a, num_states, num_actions)) for next_a in range(num_actions)]) if not done else r for s, a, r, next_s in dataset])

theta = np.linalg.lstsq(X, y, rcond=None)[0]

# Test the learned policy.
state = env.reset()
done = False
while not done:
    q_values = [np.dot(theta, state_action_to_feature_vector(state, a, num_states, num_actions)) for a in range(num_actions)]
    action = np.argmax(q_values)
    next_state, reward, done, _ = env.step(action)
    state = next_state
    env.render()

3.1.3 Experience Replay in Deep Q-Networks

DQN uses experience replay and fixed Q-targets
使用DQN解决刚才这个frozenLake的问题
在这里插入图片描述

import gym
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import random
from collections import deque

class DQN(nn.Module):
    def __init__(self, input_dim, output_dim):
        super(DQN, self).__init__()
        self.fc = nn.Linear(input_dim, output_dim)

    def forward(self, x):
        return self.fc(x)

def one_hot_encoding(state, num_states):
    encoded_state = np.zeros(num_states)
    encoded_state[state] = 1
    return encoded_state

env = gym.make('FrozenLake-v1')
num_states = env.observation_space.n
num_actions = env.action_space.n

dqn = DQN(num_states, num_actions)
optimizer = optim.Adam(dqn.parameters(), lr=0.01)
loss_fn = nn.MSELoss()

num_episodes = 2000
epsilon = 0.1
gamma = 0.99
replay_buffer = deque(maxlen=10000)

for episode in range(num_episodes):
    state = env.reset()
    done = False

    while not done:
        if np.random.rand() < epsilon:
            action = env.action_space.sample()
        else:
            state_tensor = torch.FloatTensor(one_hot_encoding(state, num_states)).unsqueeze(0)
            q_values = dqn(state_tensor)
            action = torch.argmax(q_values).item()

        next_state, reward, done, _ = env.step(action)

        # Store the transition in the replay buffer
        replay_buffer.append((state, action, reward, next_state, done))

        state = next_state

        # Train the DQN with a random sample from the replay buffer
        if len(replay_buffer) >= 64:
            batch = random.sample(replay_buffer, 64)

            states = torch.FloatTensor([one_hot_encoding(s, num_states) for s, a, r, next_s, d in batch])
            actions = torch.LongTensor([a for s, a, r, next_s, d in batch]).unsqueeze(1)
            rewards = torch.FloatTensor([r for s, a, r, next_s, d in batch]).unsqueeze(1)
            next_states = torch.FloatTensor([one_hot_encoding(next_s, num_states) for s, a, r, next_s, d in batch])
            dones = torch.BoolTensor([d for s, a, r, next_s, d in batch])

            q_values = dqn(states).gather(1, actions)
            target_q_values = rewards + gamma * dqn(next_states).max(1, keepdim=True)[0].detach()
            target_q_values[dones] = rewards[dones]

            loss = loss_fn(q_values, target_q_values)

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

# Test the learned policy
state = env.reset()
done = False
while not done:
    state_tensor = torch.FloatTensor(one_hot_encoding(state, num_states)).unsqueeze(0)
    q_values = dqn(state_tensor)
    action = torch.argmax(q_values).item()

    next_state, reward, done, _ = env.step(action)
	state = next_state
	env.render()

关键的要点
从代码上来看比较简单

q_values = dqn(states).gather(1, actions)
target_q_values = rewards + gamma * dqn(next_states).max(1, keepdim=True)[0].detach()
target_q_values[dones] = rewards[dones]

loss = loss_fn(q_values, target_q_values)

这个示例中的关键部分包括:

1. 定义一个简单的神经网络(`DQN` 类),它接收状态作为输入,并输出每个动作的 Q 值。
2. 使用经验回放缓冲区(`replay_buffer`)来存储智能体与环境交互过程中的经验。
3. 在每个时间步上,从经验回放缓冲区中随机采样一个批次的数据,并使用这些数据来训练神经网络。
4. 使用 ε-贪心策略来平衡探索与利用。

在完成训练后,我们使用训练好的神经网络来测试学到的策略。这个示例可能需要一些调整,才能在 FrozenLake-v1 环境中获得最佳性能。在实际应用中,对于更复杂的问题,我们通常会使用更复杂的神经网络结构,例如卷积神经网络(CNN)或循环神经网络(RNN),来表示 Q 函数。

4.2 linear least squares prediction

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java源码----集合系列1----ArrayList,linkedList

Arraylist 基础信息 底层是一个object数组 Arraylist 是java里面Collection 标准的一个集合&#xff0c;其底层是一个object数组。当new一个空参的ArrayList的时候&#xff0c;会默认生成一个空数组。 Arraylist上限是 Integer.MAX_VALUE - 8(Integer.MAX_VALUE 2^31-1);…

一文搞定接口测试及常用接口测试工具解析

目录 首先&#xff0c;什么是接口呢&#xff1f; 一、常见接口&#xff1a; 二、前端和后端&#xff1a; 三、什么是接口测试&#xff1a; 四、接口组成 五、为什么要做接口测试&#xff1a; 六、接口测试怎么测&#xff1a; 七、用什么工具测 首先&#xff0c;什么是接…

软件工程开发文档写作教程(06)—项目建议书写作规范

本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl本文参考资料&#xff1a;电子工业出版社《软件文档写作教程》 马平&#xff0c;黄冬梅编著 项目建议书概述 项目建议书一般是由主策划或者项目经理负责编写的。进行可行性分析是一个自…

3.编写油猴脚本之-helloword

3.编写油猴脚本之-helloword Start 通过上一篇文章的学习&#xff0c;我们安装完毕了油猴插件。今天我们来编写一个helloword的脚步&#xff0c;体验一下油猴。 1. 开始 点击油猴插件>添加新脚本 默认生成的脚本 // UserScript // name New Userscript // name…

Linux介绍及环境搭建

文章目录 &#x1f3ac;1.Linux背景&#x1f4bb;1.1 计算机的发展&#x1f4bb;1.2 操作系统的故事&#x1f4bb;1.3 Linux操作系统&#x1f4bb;1.4 Linux的应用场景&#x1f4bb;1.5 Linux版本 &#x1f50c;2. Linux环境&#x1f4be;2.1 环境选择&#x1f4be;2.2 云服务器…

u1s1,查问题已经从百度到Google,再从Google到gpt了

现在查问题&#xff0c;查资料&#xff0c;基本都是问gpt。 感觉AI的回答会比较智能。 除了解释说明&#xff0c;还会附录Demo源码。 而且没有广告和其他杂七杂八的。 方便/快捷&#xff0c;提高了工作效率。 举例 上传图片后无法渲染的文章,发现数据库的图片地址前缀带blob,可…

数据结构-查找-线性结构(顺序、折半、分块)查找

目录 一、顺序查找 *查找效率分析 二、折半查找 *查找效率分析 三、分块查找 *查找效率分析 一、顺序查找 有称线性查找&#xff0c; 算法思想&#xff1a;从头到尾挨个查找(反过来也行) typedef struct{int *elem; //数据int TableLen; …

MySQL原理(六):日志

前言 上一篇介绍了 MySQL 的锁&#xff0c;这一篇将介绍日志相关的内容。 MySQL 中最常见的日志有三类&#xff1a; undo log&#xff08;回滚日志&#xff09;&#xff1a;是 Innodb 存储引擎层生成的日志&#xff0c;实现了事务中的原子性&#xff0c;主要用于事务回滚和 …

MATLAB程序在设备端部署实例

背景介绍 MATLAB广泛应用于物理系统建模、测量测试、系统控制以及深度学习等&#xff0c;在工程实践中具有非常重要的地位&#xff0c;具体如图1所示。调研发现&#xff0c;科研人员能够编写各种matlab代码&#xff0c;通过建模仿真来更好的认识世界。近年来&#xff0c;随着物…

《LeetCode》—— 摆动序列

今天&#xff0c;我们要讲解的是 “摆动序列” 这道题目。对于这道题目&#xff0c;我们可以从贪心的思想去解决&#xff0c;也可以使用动态规划的方法。接下来&#xff0c;我通过这两种方法的讲解让你轻松拿捏它&#xff01; 目录 &#xff08;一&#xff09;贪心算法 1、上下…

跑在笔记本里的大语言模型 - GPT4All

何为GPT4All GPT4All 官网给自己的定义是&#xff1a;一款免费使用、本地运行、隐私感知的聊天机器人&#xff0c;无需GPU或互联网。 从官网可以得知其主要特点是&#xff1a; 本地运行&#xff08;可包装成自主知识产权&#x1f436;&#xff09;无需GPU&#xff08;穷人适配…

sort、uniq、tr、cut的使用

管理文件内容的使用 一、sort命令二、uniq命令三、tr命令四、cut命令 一、sort命令 sort命令是以行为单位对文件内容进行排序&#xff0c;也可以根据不同的数据类型来排序&#xff0c;比较原则是从首字符向后&#xff0c;依次按ASCII码进行比较&#xff0c;最后将他们按升序输…

Linux:rpm查询安装 yum安装

环境&#xff1a; 需要插入安装镜像 镜像内有所需的安装库 我这里使用的虚拟机直接连接光盘 连接的光盘挂载在/dev/cdrom 由于我们无法直接进入&#xff0c;所以选择把/dev/cdrom挂载到别的地方即可 mount /dev/cdrom /123 将/dev/cdrom 挂载到 /123 目录下 Packages下就是…

C++笔记—— 第十七篇 智能指针 C++11来了(下)

目录 1. 为什么需要智能指针 2. 内存泄漏 2.1 什么是内存泄漏&#xff0c;内存泄漏的危害 2.2 内存泄漏分类 2.3如何避免内存泄漏 3.智能指针的使用及原理 3.1 RAII 3.2 智能指针的原理 3.3 std::auto_ptr 3.4 std::unique_ptr 3.5 std::shared_ptr shared_ptr的线…

JVM性能调优

一、JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范&#xff0c;JVM将内存划分为&#xff1a; New&#xff08;年轻代&#xff09; Tenured&#xff08;年老代&#xff09; 永久代&#xff08;Perm&#xff09; 其中New和Tenured属于堆内存&#xff0c;堆内存会从JVM启动参…

【牛客刷题专栏】0x28:JZ30 包含min函数的栈(C语言编程题)

前言 个人推荐在牛客网刷题(点击可以跳转)&#xff0c;它登陆后会保存刷题记录进度&#xff0c;重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏&#xff1a;个人CSDN牛客刷题专栏。 题目来自&#xff1a;牛客/题库 / 在线编程 / 剑指offer&#xff1a; 目录 前言问…

【神经网络】tensorflow实验9--分类问题

1. 实验目的 ①掌握逻辑回归的基本原理&#xff0c;实现分类器&#xff0c;完成多分类任务&#xff1b; ②掌握逻辑回归中的平方损失函数、交叉熵损失函数以及平均交叉熵损失函数。 2. 实验内容 ①能够使用TensorFlow计算Sigmoid函数、准确率、交叉熵损失函数等&#xff0c…

(浙大陈越版)数据结构 第二章 线性结构 2.4 多项式的加法和乘法运算实现

目录 2.4.1多项式的加法运算实现 如何设计一个函数分别求两个一元多项式的和&#xff1f; 算法思路&#xff1a;两个指针p1&#xff0c;p2分别指向两个多项式的第一个结点&#xff08;最高项&#xff09;并循环 循环&#xff1a; 2.4.2 多项式的乘积 1.多项式的表示 2.程…

IPsec VPN IKE方式协商密钥

实验拓扑 要求pc1与pc2两个网络访问走ipsec隧道互访。 前言&#xff1a; ipsecs 隧道两端的acl规则定义的协议类型要一致&#xff0c;如果一端是ip协议&#xff0c;另一端也必须是ip协议 配置acl的原因是&#xff1a;1&#xff0c;通过acl&#xff08;permit&#xff09;指定需…

Metalama released Crack

Metalama released Crack Metalama是一个面向C#的元编程框架。它可以帮助您提高代码质量和生产力。使用Metalama&#xff0c;您可以通过在编译过程中动态生成样板文件来减少样板文件。您的源代码仍然非常清晰。根据体系结构、模式和约定实时验证代码。无需等待代码评审。通过定…