卫星图像应用 - 洪水检测 使用DALI进行数据预处理

news2024/11/27 19:38:03

这篇文章是上一篇的延申。

运行环境:Google Colab

1. 当今的深度学习应用包含由许多串行运算组成的、复杂的多阶段数据处理流水线,仅依靠 CPU 处理这些流水线已成为限制性能和可扩展性的瓶颈。

2. DALI 是一个用于加载和预处理数据的库,可使深度学习应用加速。它提供了一系列高度优化的模块,用于加载和处理图像、视频和音频数据。DALI 通过将数据预处理卸载到 GPU 来解决 CPU 瓶颈问题。

!nvidia-smi
  • 检查CUDA版本
    在这里插入图片描述
!pip install --extra-index-url https://developer.download.nvidia.com/compute/redist --upgrade nvidia-dali-cuda120
  • 安装相应的nvidia.dali库
# import dependencies
from nvidia.dali.pipeline import Pipeline
from nvidia.dali import pipeline_def
import nvidia.dali.fn as fn
import nvidia.dali.types as types

import warnings
# 在代码执行期间禁用警告信息的显示
warnings.filterwarnings("ignore")
  • 导入需要的库。
batch_size=4

@pipeline_def
def simple_pipeline():
    # use fn.readers.file to read encoded images and labels from the hard drive
    pngs, labels=fn.readers.file(file_root=image_dir)
    # use the fn.decoders.image operation to decode images from png to RGB
    images=fn.decoders.image(pngs, device='mixed')
    # specify which of the intermediate variables should be returned as the outputs of the pipeline
    return images, labels
  • @pipeline_def 是一个装饰器(decorator),它用于标记下面的函数 simple_pipeline,以告诉 DALI 库这是一个数据处理流水线的定义。
  • 使用 DALI 库中的 fn.decoders.image 操作对图像数据进行解码。这里假设输入图像是 PNG 格式,而 fn.decoders.image 操作将其解码为 RGB 格式的图像。device=‘mixed’ 表示解码操作在 GPU 上执行。

3. 创建了一个数据处理流水线对象

# create and build pipeline
pipe=simple_pipeline(batch_size=batch_size, num_threads=4, device_id=0)
pipe.build()
  • num_threads=4 表示在流水线中使用的线程数量。这里设置为4,意味着在数据加载和预处理过程中会使用4个并行的线程,以提高数据处理的效率。
  • device_id=0 表示在哪个设备上执行数据处理操作。这里设置为0,表示在第一个设备(通常是CPU)上执行操作。
  • 调用 build 方法来准备流水线以开始数据加载和预处理的工作。

4. 验证数据处理流水线的输出是否包含稠密张量。稠密张量通常用于深度学习模型的输入数据,因此检查它们是否是稠密的可以帮助确保数据准备工作正确完成。如果输出是稠密张量,那么它们可以直接用于模型的训练和推理。

# run the pipeline
simple_pipe_output=pipe.run()

images, labels=simple_pipe_output
print("Images is_dense_tensor: " + str(images.is_dense_tensor()))
print("Labels is_dense_tensor: " + str(labels.is_dense_tensor()))
  • 调用之前创建的 pipe 对象的 run 方法,用于执行数据处理流水线。执行流水线将开始加载和处理数据,生成流水线的输出结果。
  • 将流水线的输出结果 simple_pipe_output 解包成两个变量:images 和 labels。通常,在数据处理流水线中,simple_pipe_output 是一个包含了单个批次数据的元组。

5. 定义用于显示图像批次的函数

# define a function display images
def show_images(image_batch):
    columns=4
    rows=1
    # create plot
    # 窗口的宽度是固定的,而高度根据列数和行数来自动计算,以确保图像按照指定的布局显示。
    fig=plt.figure(figsize=(15, (15 // columns) * rows))
    gs=gridspec.GridSpec(rows, columns)
    for idx in range(rows*columns):
        plt.subplot(gs[idx])
        plt.axis("off")
        plt.imshow(image_batch.at(idx))
    plt.tight_layout()

show_images(images.as_cpu())
  • 使用 gridspec.GridSpec 创建一个子图的网格布局。
  • 使用 plt.subplot 创建一个子图,并根据 gs 中的索引 idx 来选择子图的位置。
  • plt.imshow 显示图像,其中 image_batch.at(idx) 表示从图像批次中获取第 idx 张图像并在子图中显示。
  • 调用 plt.tight_layout(),以确保图像布局紧凑,避免重叠或不适当的间距。

在这里插入图片描述

6. 深度学习模型需要使用大量数据进行训练才能获得准确的结果。DALI 不仅能读取磁盘中的图像并将其批处理为张量,它还能在这些图像上执行各种增强,以改进深度学习训练结果。

7. 对图像和掩码数据执行一系列的增强操作,包括裁剪和水平翻转,以增加数据的多样性和模型的鲁棒性

import random

@pipeline_def
def augmentation_pipeline():
    # use fn.readers.file to read encoded images and labels from the hard drive
    image_pngs, _=fn.readers.file(file_root=image_dir)
    # use the fn.decoders.image operation to decode images from png to RGB
    images=fn.decoders.image(image_pngs, device='cpu')
    
    # the same augmentation needs to be performed on the associated masks
    mask_pngs, _=fn.readers.file(file_root=mask_dir)
    masks=fn.decoders.image(mask_pngs, device='cpu')
    
    image_size=512
    roi_size=image_size*.5
    roi_start_x=image_size*random.uniform(0, 0.5)
    roi_start_y=image_size*random.uniform(0, 0.5)
    
    # use fn.resize to investigate an roi, region of interest
    resized_images=fn.resize(images, size=[512, 512], roi_start=[roi_start_x, roi_start_y], roi_end=[roi_start_x+roi_size, roi_start_y+roi_size])
    resized_masks=fn.resize(masks, size=[512, 512], roi_start=[roi_start_x, roi_start_y], roi_end=[roi_start_x+roi_size, roi_start_y+roi_size])
    
    # use fn.resize to flip the image
    flipped_images=fn.resize(images, size=[-512, -512])
    flipped_masks=fn.resize(masks, size=[-512, -512])
    return images, resized_images, flipped_images, masks, resized_masks, flipped_masks
  • 使用 DALI 库中的 fn.readers.file 操作从硬盘上的指定目录(image_dir)中读取图像数据。image_pngs 变量将包含图像数据,而 _ 用于占位,表示不使用标签数据。
  • roi_size 表示感兴趣区域(Region of Interest,ROI)的大小,这里设置为图像大小的一半。
  • 使用 fn.resize 操作对图像和掩码进行裁剪,仅保留感兴趣区域(ROI)。size=[512, 512] 参数指定了裁剪后的图像大小,而 roi_start 和 roi_end 参数指定了感兴趣区域的起始和结束位置,从而对图像进行裁剪。
  • 使用 fn.resize 操作对图像和掩码进行水平翻转。通过将 size 参数设置为负数,可以实现水平翻转操作。
# 创建数据增强的数据处理流水线
pipe=augmentation_pipeline(batch_size=batch_size, num_threads=4, device_id=0)
# 构建数据处理流水线
pipe.build()
# 执行数据处理流水线
augmentation_pipe_output=pipe.run()
# define a function display images
augmentation=['original', 'resized', 'flipped']
def show_augmented_images(pipe_output):
    image_batch, resized_image_batch, flipped_image_batch, mask_batch, resized_mask_batch, flipped_mask_batch=pipe_output
    columns=6
    rows=batch_size
    # create plot
    fig=plt.figure(figsize=(15, (15 // columns) * rows))
    gs=gridspec.GridSpec(rows, columns)
    grid_data=[image_batch, resized_image_batch, flipped_image_batch, mask_batch, resized_mask_batch, flipped_mask_batch]
    # grid 变量用于追踪要显示的图像数据在 grid_data 列表中的索引。
    grid=0
    for row_idx in range(rows): 
        for col_idx in range(columns): 
            plt.subplot(gs[grid])
            plt.axis('off')
            plt.title(augmentation[col_idx%3])
            plt.imshow(grid_data[col_idx].at(row_idx))
            grid+=1
    plt.tight_layout()
  • 使用 gridspec.GridSpec 创建一个子图的网格布局。rows 和 columns 参数指定了网格的行数和列数,以便在图形界面上排列图像。
  • 使用 plt.subplot 创建一个子图,并根据 gs 中的索引 grid 来选择子图的位置。
  • grid_data[col_idx].at(row_idx) 表示从 grid_data 列表中获取要显示的图像,并在子图中显示。
show_augmented_images(augmentation_pipe_output)

在这里插入图片描述

show_augmented_images(pipe.run())
  • 针对下一批数据运行流水线

在这里插入图片描述

8. 旋转每个图像(以随机角度)来执行额外的数据增强

@pipeline_def
def rotate_pipeline():
    images, _=fn.readers.file(file_root=image_dir)
    masks, _=fn.readers.file(file_root=mask_dir)
    images=fn.decoders.image(images, device='cpu')
    masks=fn.decoders.image(masks, device='cpu')
    
    angle=fn.random.uniform(range=(-30.0, 30.0))
    rotated_images = fn.rotate(images.gpu(), angle=angle, fill_value=0, keep_size=True, device='gpu')
    rotated_masks = fn.rotate(masks.gpu(), angle=angle, fill_value=0, keep_size=True, device='gpu')
    
    return rotated_images, rotated_masks
  • 使用 random.uniform 并使用 rotate 进行旋转,由此生成随机角度。
  • 创建一个使用 GPU 的流水线来执行数据增强。
  • 将设备参数设为 gpu,并通过调用 .gpu() 确保其输入传输到 GPU。

9. rotate_pipeline 会在 GPU 上执行旋转

pipe=rotate_pipeline(batch_size=batch_size, num_threads=4, device_id=0)
pipe.build()
rotate_pipe_output=pipe.run()
  • 生成的图像会分配到 GPU 显存中。
  • 模型需要 GPU 显存中用于训练的数据。
# define a function display images
def show_rotate_images(pipe_output):
    image_batch, rotated_batch=pipe_output
    columns=batch_size
    rows=2
    fig=plt.figure(figsize=(15, (15 // columns) * rows))
    gs=gridspec.GridSpec(rows, columns)
    grid_data=[image_batch.as_cpu(), rotated_batch.as_cpu()]
    grid=0
    for row_idx in range(rows): 
        for col_idx in range(columns): 
            plt.subplot(gs[grid])
            plt.axis('off')
            plt.imshow(grid_data[row_idx].at(col_idx))
            grid+=1
    plt.tight_layout()
  • 只要想在运行流水线之后将数据复制回 CPU 内存,都可通过针对 Pipeline.run() 返回的对象调用 as_cpu() 来实现。
show_rotate_images(rotate_pipe_output)

在这里插入图片描述

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

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

相关文章

LabVIEW开发虚拟与现实融合的数字电子技术渐进式实验系统

LabVIEW开发虚拟与现实融合的数字电子技术渐进式实验系统 数字电子技术是所有电气专业的重要学科基础,具有很强的理论性和实践性。其实验是提高学生分析、设计和调试数字电路能力,培养学生解决实际问题的工程实践能力,激发学生创新意识&…

leetCode 188.买卖股票的最佳时机 IV 动态规划 + 状态压缩

给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。 注意:你不能同时参与多…

国庆中秋特辑(五)MySQL如何性能调优?下篇

目录 5.数据库维护6. 数据库调优工具7.数据库架构优化8.代码层面优化9. 硬件层面优化10. 数据库安全 MySQL 性能优化是一项关键的任务,可以提高数据库的运行速度和效率。以下是一些优化方法,包括具体代码和详细优化方案。 接下来详细介绍,共有…

Hudi第二章:集成Spark

系列文章目录 Hudi第一章:编译安装 Hudi第二章:集成Spark 文章目录 系列文章目录前言一、安装Spark1、安装Spark2.安装hive 二、spark-shell1.启动命令2.插入数据3.查询数据1.转换DF2.查询 3.更新4.时间旅行5.增量查询6.指定时间点查询7.删除数据1.获取…

C/C++字符函数和字符串函数详解————长度受限制的字符串函数

个人主页:点我进入主页 专栏分类:C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.前言 2.长度受限制的字符…

arm 汇编基础指令

实现1-100求和 .text .globl _start_start:mov r0, #1 i&#xff0c;i1mov r1, #100 条件变量i<100mov r2, #0 sumLoop: 循环cmp r0,r1 比较r0和r1的大小bhi stop 当r0>r1时&#xff0c;跳到stop标签a…

Ubuntu服务器安全性提升:修改SSH默认端口号

在Ubuntu服务器上&#xff0c;SSH&#xff08;Secure Shell&#xff09;是一种至关重要的远程连接工具。它提供了一种安全的方式来远程连接和管理计算机系统&#xff0c;通过加密通信来确保数据的保密性和完整性。SSH协议广泛用于计算机网络中&#xff0c;用于远程管理、文件传…

什么是 MyBatis?与 Hibernate 的区别

引言 在现代的应用程序开发中&#xff0c;与数据库的交互是至关重要的。为了简化数据库访问&#xff0c;许多开发者选择使用ORM&#xff08;对象-关系映射&#xff09;框架。MyBatis和Hibernate都是流行的ORM框架&#xff0c;它们可以帮助开发者更轻松地将Java对象映射到数据库…

Springboot+vue的球队训练信息管理系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的球队训练信息管理系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的球队训练信息管理系统&#xff0c;采用M&…

选择排序、冒泡排序、快速排序、归并排序

1、选择排序 设一个数据集有n个元素&#xff0c;选择这n个元素中最小的一个与第一个元素交换位置&#xff0c;再在剩下的n-1个元素中选择最小的一个与第二个元素交换位置&#xff0c;直到在最后两个元素中选择最小的一个放在倒数第二的位置上&#xff0c;简单选择排序是不稳定…

【Arduino ESP32教程入门】Note

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析3 目录 &#x1f449;&#x1f3fb;arduino开发板引脚USB串行总线串行总线和并行总线的优…

Kerberos常见报错汇总

一.kdb5_util: Password mismatch while reading master key from keyboard 1>.错误复现 2>.错误原因分析 在初始化Kerberos数据库时需要输入密码&#xff0c;2次密码输入不一致就会导致该错误。 3>.解决方案 重新执行"kdb5_util -r YINZHENGJIE.COM create -s…

读书笔记--知识图谱基础概念与关键环节解析

知识图谱相当于一张网&#xff0c;是一种大型知识库&#xff0c;一种揭示实体之间关系的语义网络&#xff0c;是事物及其关系的形式化描述&#xff0c;分为通用知识图谱和领域&#xff08;行业&#xff09;知识图谱&#xff0c;如DBpedia&#xff0c;OpenKG&#xff0c;Wikidat…

IP行业查询API:为用户分析提供帮助

引言 在数字化时代&#xff0c;IP地址不仅代表着设备在互联网上的位置&#xff0c;还蕴含着丰富的信息。IP地址所属行业查询API应运而生&#xff0c;为用户分析提供了有力支持。本文将探讨这一工具的应用&#xff0c;以及对用户分析的帮助。 IP行业API的应用 1. 目标市场定位…

凉鞋的 Unity 笔记 102. 场景层次 与 GameObject 的增删改查

102. 场景层次 与 GameObject 的增删改查 在上一篇&#xff0c;我们完成了 Unity 引擎的 Hello world 输出&#xff0c;并且完成了第一个基本循环&#xff1a; 通过这次基本循环的完成&#xff0c;我们获得了一点点的 Unity 使用经验&#xff0c;这非常重要。 有实践经验后再…

C++(string类)

本节目标&#xff1a; 1、为什么要学习string类 2.标准库中的string类 3.vs和g下string结构说明 1.为什么学习string类 1.1 c语言中的字符串 C 语言中&#xff0c;字符串是以 \0 结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c; C 标准库中提供了一些 str系列的…

ROS2 库包设置和使用 Catch2 进行单元测试

说明 本文的目的是了解如何在 ROS2 中创建库&#xff0c;以供其他 ROS2 包使用。除此之外&#xff0c;本文还介绍了如何使用 catch2 框架编写单元测试。本文的第 1 部分将详细介绍如何创建库包。第 2 部分将介绍 ROS2 软件包如何利用创建的库 上篇 ROS2 库包设置和使用 Catch2…

postgresql-管理数据表

postgresql-管理数据表 创建表数据类型字段约束表级约束模式搜索路径 修改表添加字段删除字段添加约束删除约束修改字段默认值修改字段数据类型重命名字段重命名表 删除表 创建表 在 PostgreSQL 中&#xff0c;使用 CREATE TABLE 语句创建一个新表&#xff1a; CREATE TABLE …

二、BurpSuite Scan扫描

1.Scan details 解释&#xff1a;选择只是爬行还是爬行加代码审计 Scan Type&#xff1a;选择爬行或者代码审计URLs to scan&#xff1a;定义要扫描的网址。Burp将从这些网址开始进行爬行&#xff0c;并默认将包括指定网址文件夹下的所有内容。Protocol settings&#xff1a;使…

【Office】超简单,Excel快速完成不规则合并单元格排序

演示效果&#xff1a;将下图已经合并了的单元格按照单位名称排序并将同一个单位的数据合并在了一起。 Step 1&#xff1a;取消合并 选中所有的数据后&#xff0c;点击 “开始”-“合并单元格” &#xff0c;并且取消数据源的合并。 Step 2&#xff1a;填充数据 选中需要填…