【pytorch深度学习】使用张量表征真实数据

使用张量表征真实数据

本文为书pytorch深度学习实战的一些学习笔记和扩展知识,涉及到的csv文件等在这里不会给出,但是我会尽量脱离这一些文件将书本想要表达的内容给展示出来。

文章目录

  • 使用张量表征真实数据
    • 1. 加载图像文件
    • 2. 改变布局
    • 3. 加载目录下图像
    • 4. 正规化数据
    • 5. 三维图像:体数据
    • 6. 表示表格数据
    • 7. 独热编码
    • 8. 分类与阈值
    • 9. 处理时间序列

学习目标:我们如何获取一段数据,并以一种适合训练深度学习模型的方式用张量表示?这就是这篇博文的主要内容,我们将介绍不同类型的数据,并展示如何将这些数据表示为张量。

1. 加载图像文件

使用imageio模块加载PNG格式图像:

import imageio
img_arr = imageio.v2.imread('./1.png')
print(img_arr)
print(img_arr.shape)
[[[45 46 48]
  [44 45 47]
  [44 45 49]
  ...
  [30 31 35]
  [30 31 35]
  [30 31 35]]

 [[44 45 47]
  [44 45 47]
  [43 44 48]
  ...
  [30 31 35]
  [30 31 35]
  [30 31 35]]

 [[44 45 47]
  [44 45 47]
  [44 45 49]
  ...
  [30 31 35]
  [30 31 35]
  [30 31 35]]

 ...

 [[44 45 49]
  [44 45 49]
  [44 45 49]
  ...
  [30 31 35]
  [30 31 35]
  [30 31 35]]

 [[44 45 49]
  [44 45 49]
  [44 45 49]
  ...
  [30 31 35]
  [30 31 35]
  [30 31 35]]

 [[44 45 49]
  [44 45 49]
  [44 45 49]
  ...
  [30 31 35]
  [30 31 35]
  [30 31 35]]]
(256, 252, 3)

这段输出显示的是一个RGB图像的像素数据,以及该图像的尺寸和颜色通道信息。

  1. 像素数据: 输出的大部分是一个三维数组,代表了图像中每个像素的颜色信息。

    • 数组的每个元素是一个长度为3的小数组,分别对应RGB颜色模型中的红色(R)、绿色(G)和蓝色(B)通道。
    • 每个通道的值范围通常是0-255,表示该颜色通道的强度。例如,[45, 46, 48] 代表一个像素点,其中红色通道的强度为45,绿色为46,蓝色为48。
  2. 图像尺寸: 输出的最后部分 (256, 252, 3) 描述了图像的尺寸和颜色通道。

    • 256: 图像的高度(像素行数)。
    • 252: 图像的宽度(像素列数)。
    • 3: 颜色通道数,这里是RGB的3个通道。

唯一要注意的是维度布局,处理图像数据的pytorch模块要求张量排列为C H W,分别表示通道高度宽度。

2. 改变布局

我们可以用张量的permute()方法将每个新的维度,利用旧维度得到一个合适的布局。

img = torch.from_numpy(img_arr)
out = img.permute(2,0,1)  #permute()函数对通道进行重排CxHxW—>HxWxC

注意点是,这个操作没有复制张量数据,而是让out使用与img相同的底层储存,所以img中的像素改变也会影响out中的数据。

3. 加载目录下图像

从一个输入目录中加载所有的PNG图像,并将它们储存在张量中:

batch_size = 3
batch = torch.zeros(batch_size, 3, 256, 256, dtype=torch.uint8)
import os
data_dir = '......'
filenames = [name for name in os.listdir(data_dir)
            if os.path.splitext(name)[-1]=='.png']
for i ,filename in enumerate(filenames):
    img_arr = imageio.imread(os.path.join(data_dir,filename))
    img_t = torch.from_numpy(img_arr)
    img_t = img_t.permute(2, 0, 1)
    img_t = img_t[:3]
    batch[i] = img_t
print(batch)

4. 正规化数据

神经网络通常使用浮点数张量作为输入,当输入数据的范围在0~1或-1~1时,神经网络表现出最佳的训练性能。

  • 归一化:
batch = batch.float()
batch /= 255.0  # 将数据归一到[0,1]
print(batch)

在数字图像处理中,每个像素的颜色通道通常用一个8位整数来表示,这意味着每个通道的值都是0到255,所以最大值就是255,这里的除以255就是这样来的。

  • 标准化:
batch_size = 3
batch = torch.zeros(batch_size, 3, 256, 256, dtype=torch.uint8)
import os
data_dir = '...'
filenames = [name for name in os.listdir(data_dir)
            if os.path.splitext(name)[-1]=='.png']
for i ,filename in enumerate(filenames):
    img_arr = imageio.cv2.imread(os.path.join(data_dir,filename))
    img_t = torch.from_numpy(img_arr)
    img_t = img_t.permute(2, 0, 1)
    img_t = img_t[:3]
    batch[i] = img_t
batch = batch.float()

n_channels = batch.shape[1]
for c in range(n_channels):
    mean = torch.mean(batch[:,c])
    std = torch.std(batch[:,c])
    batch[:,c] = (batch[:,c] - mean)/std
print(batch)
print(batch.shape)

在pytorch中,处理单张图片时候用到的是CHW格式,而在处理一个批次时,用到的是NCHW格式,N是批次大小。所以这里用到的是n_channels=batch.shape[1]

5. 三维图像:体数据

以上的内容都是对二维图像进行操作,而在某些情况下,例如CT的医学成像应用程序,这通常需要大量的从头到脚的大量图像序列,而这一些序列代表的就是人体的一份份切片,也就是二维图像。CT图像通常是灰度图像,意味着每个像素点不是彩色的,而是只有一个强度值,这个值表示在那个特定位置X射线通过身体组织后剩余的强度。这些强度值通常被编码为12位或更高,这意味着它们有比8位灰度图像(0到255的范围)更高的强度范围。这个高强度范围使得CT图像能够展现出更细致的组织密度差异,对于检测各种体内结构,如骨骼、器官和异常组织等非常有用。由于CT扫描是三维的,它包含了多个连续的切片,这些切片堆叠在一起构成了整个扫描区域的三维体数据。在处理CT数据时,通常会处理这个三维数组,而不仅仅是单个二维图像。三维体数据使得医生和算法能够更好地理解和分析身体内部的结构。

dir_path = '...'
vol_arr = imageio.volread(dir_path,'DICOM')
print(vol_arr.shape)
vol = torch.from_numpy(vol_arr).float()
vol = torch.unsqueeze(vol,0)
print(vol.shape)

6. 表示表格数据

加载csv文件最常用的三种是:python自带的csv模块、numpy、pandas

import torch
import numpy as np
wine_path = '.\\deeply\\data\\p1ch4\\tabular-wine\\winequality-white.csv'
wine_numpy = np.loadtxt(wine_path, dtype=np.float32, delimiter=";",skiprows=1)
print(wine_numpy)
wine_tensor = torch.from_numpy(wine_numpy)
print(wine_tensor.shape,wine_tensor.dtype)

col_list = next(csv.reader(open(wine_path), delimiter= ';'))
print(col_list)
[[ 7.    0.27  0.36 ...  0.45  8.8   6.  ]
 [ 6.3   0.3   0.34 ...  0.49  9.5   6.  ]
 [ 8.1   0.28  0.4  ...  0.44 10.1   6.  ]
 ...
 [ 6.5   0.24  0.19 ...  0.46  9.4   6.  ]
 [ 5.5   0.29  0.3  ...  0.38 12.8   7.  ]
 [ 6.    0.21  0.38 ...  0.32 11.8   6.  ]]
torch.Size([4898, 12]) torch.float32
['fixed acidity', 'volatile acidity', 'citric acid', 'residual sugar', 'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density', 'pH', 'sulphates', 'alcohol', 'quality']

7. 独热编码

独热编码比较陌生,但它很容易理解:

独热编码(One-Hot Encoding)是一种处理分类数据的方法,常用于机器学习和数据分析领域。在独热编码中,每个类别都被表示为一个二进制向量,这个向量中只有一个元素是1,其余都是0。这种表示法使得不同的类别之间在数值上彼此独立,没有任何数值上的大小关系。

特点:

  1. 二进制向量:每个类别由一个长度等于类别总数的向量表示。
  2. 单一激活位:在每个类别的向量中,只有一个位置被置为1(表示当前类别),其余位置都是0。
  3. 去除数值关系:由于每个类别都由独立的位表示,因此避免了不同类别间可能存在的数值上的比较或排序。

示例:

假设有一个类别变量,包含三个可能的类别:猫、狗和鸟。在独热编码中,这些类别将被编码为:

  • 猫:[1, 0, 0]
  • 狗:[0, 1, 0]
  • 鸟:[0, 0, 1]

应用:

  • 机器学习模型:许多机器学习算法和模型要求输入数据是数值形式。独热编码能够将非数值类别特征转换为数值形式,使其能够被这些模型处理。
  • 去除类别间的偏序关系:在一些情况下,类别数据可能会被错误地解释为有序数据。例如,如果直接使用数字1、2、3来表示猫、狗、鸟,模型可能会错误地假设狗大于猫,鸟大于狗。独热编码消除了这种假设。
###独热编码
###使用scatter_()方法获得独热编码,该方法将沿着参数提供的索引方向将源张量的值填充进输入张量中
target_onehot = torch.zeros(target.shape[0],10)
target_onehot.scatter_(1, target.unsqueeze(1), 1.0)
print(target_onehot,target_onehot.shape)

8. 分类与阈值

在这里插入图片描述

我们用第六点:表示表格数据,来作为例子,为了更好衔接并且脱离csv文件,我先把上面代码放下来:

import torch
import numpy as np

# 葡萄酒评分
wine_path = '.\\deeply\\data\\p1ch4\\tabular-wine\\winequality-white.csv'
wine_numpy = np.loadtxt(wine_path, dtype=np.float32, delimiter=";",skiprows=1)  ###skiprows=1表示不读第一行,因为其中包含列名
wine_tensor = torch.from_numpy(wine_numpy)

# 表示分数
data = wine_tensor[:,:-1]
target = wine_tensor[:,-1].long()
"""
data = wine_tensor[:,:-1]:这行代码获取了除了最后一列之外的所有列,即葡萄酒的特征。
target = wine_tensor[:,-1].long():这行代码获取了最后一列,并将其转换为长整型(long),这一列是葡萄酒的评分(目标标签)。
"""

# 计算均值和方差
data_mean = torch.mean(data, dim=0)
data_var = torch.var(data, dim=0)

# 标准化数据
data_normalized = (data - data_mean)/torch.sqrt(data_var)
bad_index = target <= 3  # 在这一列中筛选
print(target)
print(bad_index)
print(target.shape, bad_index.shape, bad_index.sum())
# 输出:
tensor([6, 6, 6,  ..., 6, 7, 6]) 
tensor([False, False, False,  ..., False, False, False])
torch.Size([4898]) torch.Size([4898]) tensor(20)

知道了我们不需要的索引,所以现在可以剔除不需要的数据了:

bad_data = data[bad_index]
print(bad_data.shape)
# 输出: torch.Size([20, 11])

下面就是一系列常见的操作了,我会在我觉得需要的地方加以补充和注释:

# 分为好中劣三等
bad_data = data[target <= 3]
mid_data = data[(target > 3) & (target < 7)]
good_data = data[target >= 7]
# 对每一列取均值
bad_mean = torch.mean(bad_data,dim=0)
mid_mean = torch.mean(mid_data,dim=0)
good_mean = torch.mean(good_data,dim=0)
# 使用二氧化硫总量的阈值来区分酒的好劣
total_sulfur_threshold = 141.83  # 设定阈值
total_sulfur_data = data[:,6]  # 从 data 张量中提取第7列(索引为6),这列代表总硫化物含量

# 比较筛选操作,这里不要和上面代码块意义一样,也是筛选,只是没有使用符号而已
predicted_indexes = torch.lt(total_sulfur_data,total_sulfur_threshold)
# 得到真正好酒的索引
actual_indexes = target > 5
print(actual_indexes.shape,actual_indexes.dtype,actual_indexes.sum(),actual_indexes)
# 检验预测与实际结果是否相符
# item()方法 	将数组元素复制到标准Python标量并返回它。
n_matches = torch.sum(actual_indexes & predicted_indexes).item()
n_predicted = torch.sum(predicted_indexes).item()
n_actual = torch.sum(actual_indexes).item()
print(f'预测得到的优质酒数量:',n_matches)
print(f'2700瓶中的预测准确率:',n_matches/n_predicted)
print(f'整个数据集中的预测准确率:',n_matches/n_actual)

9. 处理时间序列

在表示平面表中组织的数据时,我们发现表中的每一行都是独立于其他行的,它们的顺序毫无关系,换句话说没有那一列对那些出现较早或者较晚的信息进行编码。那如果有一组数据是要我们观察它是如何一年一年变化的或者有一组数据是共享单车的使用情况的,调查共享单车的使用情况有时间,季节等,这时就需要将一维多通道数据转化为二维多通道数据。如下图所示:
在这里插入图片描述

下面就来给出代码,以及我学习过程中有疑惑地方的解释:

bikes_numpy = np.loadtxt(
              '.\\deeply\\data\\p1ch4\\bike-sharing-dataset\\hour-fixed.csv',
              dtype = np.float32,
              delimiter = ",",
              skiprows =1,
              converters={1: lambda x: float(x[8:10])})
bikes = torch.from_numpy(bikes_numpy)

有疑惑的地方就是converters,这个的意思就是假设在csv文件里面有一列为日期XXXX-XX-XX(年月日)当我们困惑如何将它们存起来时,converters可以解决,上面代码的意思就是他将日期中的日XX提取出来并分开为X和X,两个单独为一列。当然你也可以根据自己需求选择。

# 使用view()按时间段调整数据
daily_bikes = bikes.view(-1, 24, bikes.shape[1])

view(): 这个方法用于重新塑形张量,而不改变其数据。这里的 -1, 24, bikes.shape[1] 意味着将数据重塑为一个三维张量。-1 表示该维度的大小由其他维度确定,24 表示每天有24小时,bikes.shape[1] 保持原始数据的特征数不变。

原始形状:一个二维数组,形状为 (17520, 17)

变换后的形状:一个三维数组,形状为 (730, 24, 17)

# 调整为 NxCxL 次序
daily_bikes = daily_bikes.transpose(1, 2)

transpose(1, 2): 这个方法用于交换张量中的两个维度。这里,它交换了第二和第三维度(维度索引从0开始计数)调整时候变为(730, 17, 24)

全部代码:

bikes_numpy = np.loadtxt(
              '.\\deeply\\data\\p1ch4\\bike-sharing-dataset\\hour-fixed.csv',
              dtype = np.float32,
              delimiter = ",",
              skiprows =1,
              converters={1: lambda x: float(x[8:10])})
bikes = torch.from_numpy(bikes_numpy)
# 使用view()按时间段调整数据
daily_bikes = bikes.view(-1, 24, bikes.shape[1])
# 调整为NxCxL次序
daily_bikes = daily_bikes.transpose(1,2)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[工业自动化-12]:西门子S7-15xxx编程 - PLC从站 - ET200 SP系列详解

目录 一、概述 1.1 概述 二、系统组成 2.1 概述 2.2 与主站的通信接口模块 2.3 总线适配器 2.4 基座单元 2.5 电子模块 2.6 服务器模块 一、概述 1.1 概述 PLC ET200 SP 是西门子&#xff08;Siemens&#xff09;公司生产的一款模块化可编程逻辑控制器&#xff08;PL…

苹果手机安装未上架APP应用测试教程

STEP 2&#xff1a;找到下载的描述文件&#xff08;如果没有找到&#xff0c;请到 设置 - 通用 - 描述文件 中查看&#xff09; STEP 3&#xff1a;安装描述文件 STEP 4&#xff1a;输入解锁密码安装描述文件 STEP 5&#xff1a;同意免责声明&#xff0c;安装描述文件 STEP 6…

开发知识点-Ant-Design-Vue

Ant-Design-Vue a-input a-input Vue组件 a-spin 加载中的效果 data字段 mounted钩子函数 Ant Design Vue 组件库 list-type“picture-card” 上传的图片作为卡片展示 name show-upload-list action :beforeUpload“handleBeforeUpload” :headers“customHeaders” :disabl…

springboot调用第三方接口json转换成对象

请求接口是一个比较常见的需求&#xff0c;接口返回一般是一个json类型&#xff0c;需要进行组装成对应的类&#xff0c;例 {"status_code": 200,"message": "success","data": {"cost": 286.6933,"bom_list": […

人工智能基础——Python:Matplotlib与绘图设计

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

使用ResponseSelector实现校园招聘FAQ机器人

本文主要介绍使用ResponseSelector实现校园招聘FAQ机器人&#xff0c;回答面试流程和面试结果查询的FAQ问题。FAQ机器人功能分为业务无关的功能和业务相关的功能2类。 一.data/nlu.yml文件   与普通意图相比&#xff0c;ResponseSelector训练数据中的意图采用group/intent格…

Vue 3 打印解决方案:Vue-Plugin-HiPrint

文章目录 1. Vue-Plugin-HiPrint 简介2. 安装和使用2.1 安装2.2 引入并注册插件2.3 在组件中使用 3. 配置和高级用法4. 示例应用5. 总结 &#x1f389;欢迎来到Java学习路线专栏~Vue 3 打印解决方案&#xff1a;Vue-Plugin-HiPrint ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f37…

x3daudio1_7.dll怎么解决?x3daudio1_7.dll丢失的5个详细处理方法

首先&#xff0c;让我们来了解一下X3DAudio1_7.dll丢失的原因。X3DAudio1_7.dll是一个非常重要的动态链接库文件&#xff0c;它负责处理计算机中的音频输出。然而&#xff0c;由于各种原因&#xff0c;例如软件安装错误、病毒感染、系统升级等&#xff0c;我们可能会遇到X3DAud…

超强C语言跨年烟花代码,精美无比,附源码分步解析

现在大家是不是都觉得程序员不懂浪漫&#xff1f;那真的大错特错&#xff0c;今天就让你们看看什么是程序员的浪漫&#xff01; 我们今天就来写写《烟花》表白程序&#xff0c;不要惊讶&#xff0c;不要激动&#xff0c;学会了快去拿给心中的那个人看&#xff01;&#xff01;…

【论文解读】针对生成任务的多模态图学习

一、简要介绍 多模态学习结合了多种数据模式&#xff0c;拓宽了模型可以利用的数据的类型和复杂性&#xff1a;例如&#xff0c;从纯文本到图像映射对。大多数多模态学习算法专注于建模来自两种模式的简单的一对一数据对&#xff0c;如图像-标题对&#xff0c;或音频文本对。然…

玩转ansible之参数调试和文件操作篇

更多IT技术文章&#xff0c;欢迎关注微信公众号“运维之美” 玩转ansible之参数调试和文件操作篇 01 剧本调试和帮助02 使用场景举例 上节我们学习了使用ansible进行软件安装&#xff0c;那么安装完软件后&#xff0c;就需要linux系统和软件配置修改了&#xff0c;对于linux主机…

Java程序设计2023-第八次上机练习

8-1简单文本编辑器 编写简单文本编辑器&#xff0c;该程序可以新建、打开、编辑和保存文本文件。当用户点击New时&#xff0c;新建一个文件&#xff0c;用户可以编辑文件内容&#xff0c;然后点击Save保存文件。用户点击Open时&#xff0c;选择一个已有文件&#xff0c;然后可…

leetcode:206. 反转链表

一、题目 函数原型&#xff1a; struct ListNode* reverseList(struct ListNode* head) 二、思路 要对链表进行反转&#xff0c;可以有两种方法&#xff1a; 1.改变链表中每个结点之间的指针域指向&#xff0c;最后返回尾结点即可。 2.新建一个链表&#xff0c;将原链表中的结点…

gorm之项目实战-使用gen以及定义表间关系

gorm之项目实战 ER图 关系整理 一对一关系&#xff1a; User 和 UserLog&#xff1a; 一个用户对应一个用户日志&#xff0c;通过 User 模型的主键与 UserLog 模型的外键建立一对一关系。 一对多关系&#xff1a; User 和 Teacher&#xff1a; 一个用户可以对应多个老师&…

win10网络和Internet设置

win10网络设置 win10进入网络设置的常用入口有两个 第一个入口 桌面右下角右键网络图标&#xff0c;然后打开“网络和Internt设置” 第二个入口 桌面的“我的网络”快捷方式&#xff0c;或者我的电脑进去后&#xff0c;左侧栏找到“网络” 右键“属性” 可以看到&#xff0c;…

【论文阅读VLDB13】Online, Asynchronous Schema Change in F1

Online, Asynchronous Schema Change in F1 ABSTRACT 在一个globally 分布式数据库&#xff0c;with shared data, stateless servers, and no global membership.进行一个schema演变。证明许多常见的模式更改可能会导致异常和数据库损坏&#xff0c;通过将破坏引起的模式更改…

Git 命令详解

系列文章目录 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 C技能系列 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream we…

消息队列简介

消息队列 在认识rabbitMQ之前&#xff0c;我们需要先认识下消息队列。 消息队列&#xff0c;一般简称为MQ&#xff08;Message Queue&#xff09;。先不管消息(Message)这个词&#xff0c;先看看队列(Queue)。 队列就是一种先进先出的数据结构。 所以消息队列可以简单理解为&a…

rasa train nlu详解:1.2-_train_graph()函数

本文使用《使用ResponseSelector实现校园招聘FAQ机器人》中的例子&#xff0c;主要详解介绍_train_graph()函数中变量的具体值。 一.rasa/model_training.py/_train_graph()函数   _train_graph()函数实现&#xff0c;如下所示&#xff1a; def _train_graph(file_importer…

Kubernetes基础(七)-Pod资源Limits与Requests

在k8s的集群环境中&#xff0c;资源的合理分配和使用非常重要。毕竟容器化要解决的问题之一就是资源的充分利用。在集群中分配资源的时候就不得不提到Limits和Requests。 1 Namespace配额 Kubernetes 是允许管理员在命名空间中指定资源 Requests 和 Limits 的&#xff0c;这一…