【强化学习系列】Gym库使用——创建自己的强化学习环境1:单一环境创建测试

news2025/2/21 4:43:04

       

目录

一、Gym类创建单一环境

        1.gym类初始化 __init__()

        2.gym类初始状态 reset()

        3.gym类渲染可视化 render()

        4.gym类运行核心 step()

        5.gym类运行


        在强化学习中实操中,有两个非常重要的设计模块,一个是模型网络和算法的设计,另一个则是用于智能体交互的强化学习环境搭建。Gym 库凭借其标准化和兼容性好的接口、丰富多样的环境库、易于定制和扩展的能力、完善的文档和易用性、高效的集成模拟器和图像处理支持、以及活跃的研究生态系统成为了强化学习研究和开发的首选工具。

        Gym官方文档介绍地址:https://gymnasium.farama.org/

        本文记录自建Gym强化学习环境中遇到的问题和解决,本文将按照源码Gym类的创建逻辑展开,并将单个环境过渡到矢量化多个环境同时运行以加速训练。

一、Gym类创建单一环境

        1.gym类初始化 __init__()

        在初始化gym自建环境类中,关键是定义环境的动作空间(self.action_space)和状态空间(self.observation_space)

        在下图中,自定义一个关于目标检测框二次调整移动的强化学习gym环境,动作空间是四个对框的调整移动,状态空间是当前图片上的目标检测框四坐标。

        在自定义 Gym 环境时,action_space(动作空间)定义了智能体(代理)可以选择的所有可能动作。动作空间决定了智能体能够做出的决策范围。observation_space(状态空间)定义了环境可以返回给智能体(代理)的所有可能状态或观测值。状态空间决定了智能体所能感知到的环境信息范围。

        Gym 提供了多种动作空间和状态空间类型,每种类型都有其独特的参数和使用场景。两者本质上使用的都是gym.Space这个类的定义功能,下述将其合并记录。

        此部分官方文档地址:Gym.Space官方文档介绍

        ① Discrete 空间

        用于表示一个离散的动作或状态空间,有限个动作或状态,每个用一个整数索引表示。

        参数 n 表示动作的总数。如定义一个在二维空间中移动的小球,可以定义其动作为移动   {上:0,下:1,左:2,右:3}  。或者定义一个3x3的网格状态空间,总共可能的格子数为9。

from gym import spaces

# 定义一个4动作离散动作空间, 如移动:上、下、左、右
action_space = spaces.Discrete(4)

# 定义一个9状态的状态空间,如3x3网格:九个格子对应9种情况
observation_space = spaces.Discrete(9)

         ② Box 空间

        用于表示一个连续的动作或状态空间。用于需要连续动作的任务,如机器人手臂的操作,金融交易决策。或用于一个连续的状态空间,如空间物理位置、传感器读数、速度等。

        参数 low 表示每个维度的最小值,high 表示每个维度的最大值。例如假设机器人手臂最大转动角度为一圈,那么此时动作空间中 low=0 代表0度;high=360 代表360度一圈。如温度传感器的最大温度限制为200摄氏度,最低为-50摄氏度,那么状态空间 low=-50,high=200。

        参数 shape 表示动作空间维度, dtype 表示使用数据类型。

from gym import spaces
import numpy as np

# 定义一个二维连续动作空间,每个维度的取值范围是 [-1.0, 1.0]
action_space = spaces.Box(low=np.array([-1.0, -1.0]), high=np.array([1.0, 1.0]), dtype=np.float32)

# 定义一个三维连续状态空间,每个维度的取值范围分别是 [-1.0, 1.0], [0, 5], [0, 10]
observation_space = spaces.Box(low=np.array([-1.0, 0.0, 0.0]), high=np.array([1.0, 5.0, 10.0]), dtype=np.float32)

        ③ MultiDiscrete 空间

        用于表示多个独立的离散动作或状态空间组合,如在环境中智能体需要同时控制多个变量——方向、速度(三维空间中小车移动),每个属性对应于一个不同的离散取值。或者环境存在多个维度,如三维离散空间。

        参数 n 是一个整数数组,代表每个维度动作空间的取值范围。如移动方向四个(上下左右),速度四个(一倍速:0,两倍速:1,三倍速:2, 四倍速:3)。那么参数输入就是[4,4]。或者说对于3x3网格要分横竖两个方向的状态空间,那么可以理解为x,y轴两个方向分别对应三个可能情况,参数输入[3,3]

from gym import spaces

# 定义一个两个维度的多离散动作空间,每个维度有4种可能的动作
action_space = spaces.MultiDiscrete([4,4])

# 定义一个二维离散状态空间
observation_space = spaces.MultiDiscrete([3,3])

        ④ MultiBinary 空间

        用于多个独立的二元变量动作或状态组合,如多个开关或布尔运算的组合。

        参数 n 表示二元变量(开关)的数量

from gym import spaces

# 定义一个有3个二元变量的动作空间
action_space = spaces.MultiBinary(3)

# 定义一个有2个二元变量的状态空间
observation_space = spaces.MultiBinary(2)

        ⑤ Tuple 空间

        这是一个更加自由的定义动作和状态空间的方式,允许多个不同类型的动作和状态空间组合,如一个动作可以由一个离散动作或状态和一个连续控制或连续空间组合。

        参数是一个元组,元组包含多个 gym.Space 对象。

from gym import spaces

# 定义一个动作空间,由一个离散空间和一个连续空间组合而成
action_space = spaces.Tuple((spaces.Discrete(3), spaces.Box(low=0, high=1, shape=(2,), dtype=np.float32)))

# 定义一个状态空间,由一个离散空间和一个连续空间组合而成
observation_space = spaces.Tuple((spaces.Discrete(3), spaces.Box(low=0, high=1, shape=(2,), dtype=np.float32)))

        ⑥ Dict 空间

        用于表示一个字典格式动作空间,可以更自由的灵活定义多维复杂动作结构。

        参数也是 gym.Space 对象,用字典形式输入。

from gym import spaces

# 定义一个字典动作空间,包含一个离散空间和一个连续空间
action_space = spaces.Dict({
    'discrete_action': spaces.Discrete(5),
    'continuous_action': spaces.Box(low=-1, high=1, shape=(3,), dtype=np.float32)
})

# 定义一个字典状态空间,包含一个离散空间和一个连续空间
observation_space = spaces.Dict({
    'discrete_state': spaces.Discrete(5),
    'continuous_state': spaces.Box(low=-1, high=1, shape=(3,), dtype=np.float32)
})

        上述是gym库支持的一般空间形式,在后续 gymnasium 分支更新中,又更新了新的空间表示形式以适应新的强化学习环境要求。记录在下。

        ⑦ Text 空间

        在Gymnasium库中,Text空间专门用于处理文本数据的空间类型。用于自然语言处理相关的强化学习任务,如文字游戏、对话生成等。通常此类多用于状态空间表示

        参数min_length 和参数 max_length 表示文本的最小最大长度,是一个整数,指定空间中允许出现的最小最大字符数。参数charset表示文本的字符集或词汇表。

from gymnasium.spaces import Text

# 示例 1:创建一个最大长度为 10,字符集为默认 ASCII 的 Text 空间
text_space = Text(max_length=10)

# 示例 2:创建一个最大长度为 5,自定义字符集为 'abcdef' 的 Text 空间
text_space_custom = Text(max_length=5, charset="abcdef")

# 示例 3:创建一个最大长度为 7,词汇表为 ["hello", "world"] 的 Text 空间
text_space_words = Text(max_length=7, charset=["hello", "world"])

print("Default Text Space:", text_space)
print("Custom Character Set Text Space:", text_space_custom)
print("Custom Word Set Text Space:", text_space_words)

        本文记录的是目标检测框的强化学习环境搭建,其中动作空间代表框的移动是一个四动作的离散空间状态空间是图片中的目标框box坐标,因此是一个(图片框总数,4)的四维连续空间,其每一维度取值范围是0到图片的高或宽

import pygame
import gym
from gym import spaces
import numpy as np

class RL_Env(gym.Env):
    def __init__(self, image_path, render_mode=None):
        super(RL_Env, self).__init__()
        # 读取当前图像信息
        self.img = pygame.image.load(image_path)
        self.width, self.height = self.img.get_width(), self.img.get_height()
        # 创建动作和状态空间范围
        self.action_space = spaces.Discrete(4)
        self.observation_space = spaces.Box(low=np.array([0,0,0,0],dtype=np.float32), high=np.array([self.width, self.height,
                                            self.width, self.height],dtype=np.float32), shape=(4,), dtype=np.float32)
        # 定义模式:人类可视化or机器人训练
        self.render_mode = render_mode
        self.window = None  # 可视化窗口
        self.clock = None   # 可视化时钟
        self.window_size = (600,800)  # 窗口大小
        self.background = None  # 背景图
        self.scale_x = None     # x横轴缩放比
        self.scale_y = None     # y竖轴缩放比

        2.gym类初始状态 reset()

        这里的关键就是初始化整个游戏的基础界面信息,对于每个不同的环境或项目,其定义可能是仁者见仁智者见智,此处仅记录基于目标检测框移动的项目代码。

        因为状态空间就是对应当前图片的一个已知的框(目标是优化当前框,提供精度),因此只需从外部读取框信息并加载到状态空间中即可。对于其他的环境按住实际需求编写代码即可。

        如果选择‘human’模式,就调用pygame可视化函数 self.render() 。

class RL_Env(gym.Env):
    # 重置环境——读取图片和框信息
    def reset(self, json_path):
        # 读取外部数据
        with open(box_path, 'r') as f:
            box_dict_list = json.load(f)
        box_list = []
        for box_dict in box_dict_list:
            box = box_dict['box']
            box_list.append(box)
        # 框构成当前状态空间
        self.state = np.array(box_list,dtype=np.float32).reshape(-1,4)
        
        # 如果是‘human’模式,则初始可视化
        if self.render_mode == 'human':
            self.background = pygame.transform.scale(self.img, self.window_size) # 设置背景图
            # 计算x和y方向的缩放比例
            self.scale_x = self.window_size[0]/ self.width
            self.scale_y = self.window_size[1] / self.height
            self.render()
        return self.state

        3.gym类渲染可视化 render()

         在初始化函数中使用了可视化函数 render() ,可视化分为几个步骤:1.设置窗口,2.填充背景,3.描绘状态,4.完整展示。对于本文例子中,背景就是目标检测的图片,而变化的状态就是图上的框,因此可以编写一个十分简单的可视化函数。

        其中self.clock.tick()控制每张图片显示的时长(实际是帧率,这里方便理解),参数调的越小,每一张图停留的时间越长。

class RL_Env(gym.Env):
    def render(self):
        # 初始化窗口和时钟
        if self.window is None and self.render_mode == 'human':
            pygame.init()
            pygame.display.init()
            self.window = pygame.display.set_mode(self.window_size)
        if self.clock is None and self.render_mode == 'human':
            self.clock = pygame.time.Clock()
        # 重新绘制背景,以清除上一层
        if self.background is not None:
            self.window.blit(self.background,(0,0))
        # 绘制框
        for box in list(self.state):
            rect = [box[0], box[1], abs(box[2]-box[0]), abs(box[3]-box[1])]
            # 根据x和y方向的缩放比例计算每个矩形框的新位置
            stretched_rectangle = [
                rect[0] * self.scale_x,  # x 坐标
                rect[1] * self.scale_y,  # y 坐标
                rect[2] * self.scale_x,  # 宽度
                rect[3] * self.scale_y  # 高度
            ]
            pygame.draw.rect(self.window, (0, 255, 0), stretched_rectangle, 1)  # 绘制矩形框,线宽为2
        # 更新显示
        pygame.display.flip()
        self.clock.tick(2)

        4.gym类运行核心 step()

        本部分也是需要根据实际需求编写代码,step() 是整个环境更新的核心部分,影响着模型动作与环境的交互。总体来说,可以分为三部分思考此处代码架构。

        a.输入动作与环境的交互设计——强化学习的模型输入的动作序列如何影响环境中的状态空间,如移动框中坐标信息的改变。

        b.从动作之前状态到之后状态奖励设计——强化学习的关键就是奖励函数的设计,机器动作传入后是赢了游戏达到目标(正奖励)还是“一事无成”甚至使得状况更坏了(负奖励)。

        c.终止条件设计——什么时候游戏到头了,或者哪些条件可以判断“角色挂了”,要设置当前环境的退出条件机制。

         本文只简单实验环境搭建,占不写出具体的奖励逻辑等,终止条件也按最简单的到达一定步数时,退出环境。

class RL_Env(gym.Env):
    def step(self, action):  # 动作序列{0:上扩, 1:上缩, 2:下扩, 3:下缩}
        # 根据action生成移动数组
        movement_np = np.zeros_like(self.state,dtype=np.float32)
        for i,act in enumerate(action):
            if act == 0:
                movement_np[i,1] = 100
            elif act == 1:
                movement_np[i,1] = -100
            elif act == 2:
                movement_np[i,3] = 100
            elif act == 3:
                movement_np[i,3] = -100
        # 移动当前状态框
        self.state += movement_np
        self.state = np.clip(self.state, env.observation_space.low, env.observation_space.high)

        return self.state

        5.gym类运行

        有了上述所有功能的准备,于是可以测试运行强化学习环境了。首先需要准备环境搭建的数据集——1.图片jpg数据;2.检测框json数据

        图片上还是使用coco8中的图片,使用官方yolo8m模型预测目标框并保存为json格式。建立下图文件夹,运行下面代码得到结果。

from ultralytics import YOLO
import os
import json

jpg_file = './jpg'
save_file = './box'

model = YOLO(model='./yolo/yolov8m.pt')

for file in os.listdir(jpg_file):
    base = file.split('.')[0]
    savedir = os.path.join(save_file, base+'.json')
    jpgdir = os.path.join(jpg_file, file)

    pred = model.predict(jpgdir)
    boxes = pred[0].boxes.xyxy
    boxes_list = [[int(r[0]), int(r[1]), int(r[2]), int(r[3])] for r in boxes]

    box_dict_list = []
    for i,box in enumerate(boxes_list):
        box_dict = dict()
        box_dict['id'] = i
        box_dict['box'] = box
        box_dict_list.append(box_dict)
    with open(savedir,'w') as f:
        json.dump(box_dict_list, f)

         有了数据支持,就可以实例化环境类并将本地图片和框传入环境并可视化展示了。这里选择随机生成动作序列,动作action是一个列表,其中元素与图片内的框一一对应。对框做50次修改以后退出环境。

if __name__=='__main__':
    # 加载本地图片
    image_path = './jpg/000000000025.jpg'  # 替换为你的图片路径
    # 加载本地框
    box_path = './box/000000000025.json'

    env = RL_Env(image_path, render_mode='human')

    state = env.reset(box_path)
    for epid in range(50):
        action = np.random.choice([0,1,2,3],size=state.shape[0])
        state = env.step(action)
        env.render()

        方便复制使用的完整代码如下。

import json

import pygame
import gym
from gym import spaces
import numpy as np

class RL_Env(gym.Env):
    def __init__(self, image_path, render_mode=None):
        super(RL_Env, self).__init__()
        # 读取当前图像信息
        self.img = pygame.image.load(image_path)
        self.width, self.height = self.img.get_width(), self.img.get_height()
        # 创建动作和状态空间范围
        self.action_space = spaces.Discrete(4)
        self.observation_space = spaces.Box(low=np.array([0,0,0,0],dtype=np.float32), high=np.array([self.width, self.height,
                                            self.width, self.height],dtype=np.float32), shape=(4,), dtype=np.float32)
        # 定义模式:人类可视化or机器人训练
        self.render_mode = render_mode
        self.window = None  # 可视化窗口
        self.clock = None   # 可视化时钟
        self.window_size = (600,600)  # 窗口大小
        self.background = None  # 背景图
        self.scale_x = None     # x横轴缩放比
        self.scale_y = None     # y竖轴缩放比

    # 重置环境——读取图片和框信息
    def reset(self, json_path):
        with open(box_path, 'r') as f:
            box_dict_list = json.load(f)
        box_list = []
        for box_dict in box_dict_list:
            box = box_dict['box']
            box_list.append(box)
        self.state = np.array(box_list,dtype=np.float32).reshape(-1,4)

        if self.render_mode == 'human':
            self.background = pygame.transform.scale(self.img, self.window_size) # 设置背景图
            # 计算x和y方向的缩放比例
            self.scale_x = self.window_size[0]/ self.width
            self.scale_y = self.window_size[1] / self.height
            self.render()
        return self.state

    def step(self, action):  # 动作序列{0:上扩, 1:上缩, 2:下扩, 3:下缩}
        # 根据action生成移动数组
        movement_np = np.zeros_like(self.state,dtype=np.float32)
        for i,act in enumerate(action):
            if act == 0:
                movement_np[i,1] = 10
            elif act == 1:
                movement_np[i,1] = -10
            elif act == 2:
                movement_np[i,3] = 10
            elif act == 3:
                movement_np[i,3] = -10
        # 移动当前状态框
        self.state += movement_np
        self.state = np.clip(self.state, env.observation_space.low, env.observation_space.high)

        return self.state

    def render(self):
        # 初始化窗口和时钟
        if self.window is None and self.render_mode == 'human':
            pygame.init()
            pygame.display.init()
            self.window = pygame.display.set_mode(self.window_size)
        if self.clock is None and self.render_mode == 'human':
            self.clock = pygame.time.Clock()
        # 重新绘制背景,以清除上一层
        if self.background is not None:
            self.window.blit(self.background,(0,0))
        # 绘制框
        for box in list(self.state):
            rect = [box[0], box[1], abs(box[2]-box[0]), abs(box[3]-box[1])]
            # 根据x和y方向的缩放比例计算每个矩形框的新位置
            stretched_rectangle = [
                rect[0] * self.scale_x,  # x 坐标
                rect[1] * self.scale_y,  # y 坐标
                rect[2] * self.scale_x,  # 宽度
                rect[3] * self.scale_y  # 高度
            ]
            pygame.draw.rect(self.window, (0, 255, 0), stretched_rectangle, 1)  # 绘制矩形框,线宽为2
        # 更新显示
        pygame.display.flip()
        self.clock.tick(2)

    def close(self):
        pygame.quit()


if __name__=='__main__':
    # 加载本地图片
    image_path = './jpg/000000000025.jpg'  # 替换为你的图片路径
    # 加载本地框
    box_path = './box/000000000025.json'

    env = RL_Env(image_path, render_mode='human')

    state = env.reset(box_path)
    for epid in range(50):
        action = np.random.choice([0,1,2,3],size=state.shape[0])
        state = env.step(action)
        env.render()

        

         受篇幅原因,本篇到此结束。在下一篇中,将记录使用矢量化环境的操作。在强化学习训练中如果一步只对应一张图片一个环境,运行是十分慢的,而且也没有发挥神经网络小批量处理的加速——即一次只输出批量为1的动作,因为当前一个环境只能接受一个动作。因此矢量化环境本质上就是同时加载多个相同或不同的图片环境与模型输出的多批次动作进行交互。

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

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

相关文章

计算机毕业设计选题推荐-学生在线投票系统-Java/Python项目实战(亮点:数据可视化分析、找回密码)

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

UML-统一建模语言学习笔记20240912

UML入门 一、软件开发基础知识: 1.软件开发的生命周期,包括需求分析,设计,实现,测试和维护等阶段。 2.面向对象的编程(OOP):UML 是一种用于描述面向对象系统的语言,需要…

这么好用的电脑桌面美化工具 你怎么能错过她?

芝麻时钟是一个功能强大的桌面时钟软件,它具有多种实用功能,包括桌面时钟、时钟屏保、任务栏时钟和桌面日历等。这个软件不仅提供了丰富的主题和美观的界面,更重要的是它的实用性和特色功能。(下载地址:https://clock.zhimasoft.c…

计算机网络 ---- OSI参考模型TCP/IP模型

目录 一、OSI参考模型 1.1 学习路线 1.2 OSI参考模型和TCP/IP模型 1.3 具体设备与具体层次对应关系 1.3.1 物理层 1.3.2 数据链路层 1.3.3 网络层 1.3.4 传输层 1.3.5 会话层、表示层、应用层 1.4 各层次数据传输单位 二、TCP/IP模型 2.1 学习路线 2.2 TCP/I…

源代码防泄密软件的五大特点

在数据防泄密领域,深信达的SDC沙盒软件以其独特的技术和创新应用,为源代码安全提供了强有力的保护。特别是在源代码防泄密方面,SDC沙盒表现出色,其实现方式主要包括以下几个方面: 1. **内核级虚拟沙盒技术**&#xff1…

QT学习参考书籍

6.2 Qt参考书籍资料 6.2.1 《Qt C编程从入门到实战》 主编:彭源 6.2.2 《Qt 5编程入门 第2版》编著:程梁 霍亚飞 6.2.3 《嵌入式Qt开发项目教程》编著:王浩 著 王浩 6.2.4 《Qt Quick核心编程》编著:安晓辉 6.2.5《零基础学Qt 4编程》 作者:吴迪著 6.2.6 《C并发编程实战(第2版…

【Python机器学习】循环神经网络(RNN)——超参数

几乎所有模型都可以根据数据和样本进行调整,它们都有各自的优势和相应的利弊权衡方式。寻找最优超参数集通常是一个棘手的问题,但是人类的直觉和经验可以为我们提供解决问题的方法。比如之前的例子: #设置任意输入序列的最大长度 maxlen100 …

论文笔记:基于LLM和多轮学习的漫画零样本角色识别与说话人预测

整理了ACM MM2024 Zero-Shot Character Identification and Speaker Prediction in Comics via Iterative Multimodal Fusion)论文的阅读笔记 背景模型框架实现细节 模型数据集实验可视化消融实验 背景 最近读到一篇新文章,主要是做漫画中的零样本角色识…

Linux中限制服务如mysql的最大cpu使用率

1、cpu占用测试&#xff1a; DELIMITER // DROP PROCEDURE IF EXISTS intensive_calculations; CREATE PROCEDURE intensive_calculations() BEGINDECLARE v INT DEFAULT 0;DECLARE i INT DEFAULT 0;WHILE i < 1000000 DOSET v SQRT(i * i (RAND() * 10000));SET i i 1…

【动态规划】(一)动态规划理论及基础题目

动态规划理论及基础题目 理论基础斐波那契数爬楼梯使用最小花费爬楼梯不同的路径不同的路径2整数拆分不同的二叉搜索树 理论基础 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划…

告别存储烦恼,MyDiskTest全方位检测解决方案

科技改变生活&#xff0c;但质量决定科技的生命力——这句话在数字化时代尤为贴切。近年来&#xff0c;随着科技的飞速发展&#xff0c;U盘、SD卡、CF卡等移动存储设备已成为我们日常工作和生活中不可或缺的工具。它们便携、高效&#xff0c;能够快速存储和传输大量数据。然而&…

【详解】数据库E-R图——医院计算机管理系统

题目 某医院病房计算机管理中需要如下信息&#xff1a; 科室&#xff1a;科室名&#xff0c;科室地址&#xff0c;科室电话&#xff0c;医生姓名 病房&#xff1a;病房号&#xff0c;床位号&#xff0c;所属科室名 医生&#xff1a;工作证号&#xff0c;姓名&#xff0c;性别&a…

GPT撰写开题报告教程——课题确定及文献调研

撰写开题报告是一项复杂而重要的任务&#xff0c;需要涵盖从主题选择到文献综述、研究方法等多个环节。借助AI&#xff0c;如ChatGPT&#xff0c;可以显著提高这一过程的效率以及内容的质量。本文将详细探讨如何一步步利用ChatGPT撰写开题报告。 一、开题报告内容 一个清晰的…

基于R语言的统计分析基础:使用ggplot2包进行绘图

安装ggplot2包并查看官方文档 ggplot2是一个基于图形语法的R包&#xff0c;它允许用户通过声明式方式指定数据、美学映射和图形元素来灵活创建复杂且美观的可视化图表。 ggplot2包官方教学文档&#xff1a;ggplot2官方文档 在R语言中安装ggplot2有两种方法&#xff1a; 安装整…

【SQL】百题计划:SQL判断条件OR的使用。

【SQL】百题计划-20240912 Select name, population, area from World where area>3000000 or population > 25000000;

替换传统数据处理平台,TDengine 与华风数据达成合作

在全球能源转型的大背景下&#xff0c;新能源产业正迎来前所未有的发展机遇。随着国家对可再生能源的政策支持和市场需求的不断增长&#xff0c;风电、光伏和储能等新能源项目如雨后春笋般蓬勃发展。然而&#xff0c;随之而来的数据处理与管理挑战也日益凸显。面对海量的设备运…

YOLO-v8:对yolov8网络的改进教程(以GAM注意力模块为例)

本文将介绍如何在YOLOv8网络中进行模块化修改。 通过将改进的核心模块添加到项目中&#xff0c;即可直接运行各种 YOLOv8-xxx.yaml 网络配置文件&#xff0c;支持乐高式创新扩展。无论是进行网络结构的调整还是增加新的功能模块&#xff0c;用户只需一键运行&#xff0c;轻松实…

净赚百亿背后,海尔智家的机遇与隐忧

广撒网、出海忙&#xff0c;海尔智家如何熬过存量周期&#xff1f; 转载&#xff1a;科技新知 原创 作者丨田箫 编辑丨赛柯 冰箱、空调、洗衣机不好卖了&#xff0c;已成为不争的事实。 在购房热情降温、收入预期低迷的双重打击下&#xff0c;白电品牌正艰难求生。然而&#x…

通过ASCII码打印HelloWorld(花式打印HelloWorld)

/*** 通过ASCII码打印HelloWorld*/ public class Main {public static void main(String[] args) {String target "HelloWorld";String fi "";for (int i 0; i < target.length(); i) {for (int x 0; x < 127; x) {char c (char) x;String d f…

怎么利用短信接口发送文字短信

在当今这个快节奏的数字时代&#xff0c;即时通讯已成为人们日常生活和工作中不可或缺的一部分。而短信接口&#xff08;SMS Interface&#xff09;&#xff0c;作为传统与现代通讯技术结合的典范&#xff0c;凭借其高效、稳定、广泛覆盖的特性&#xff0c;在众多领域发挥着不可…