【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)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自然语言处理(一):RNN

「循环神经网络」&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一个非常经典的面向序列的模型&#xff0c;可以对自然语言句子或是其他时序信号进行建模。进一步讲&#xff0c;它只有一个物理RNN单元&#xff0c;但是这个RNN单元可以按照时间步骤进行展开…

立冬特辑-----链表OJ题优选合集~~

目录 ​​​​​​​前言&#x1f333; 1.链表中倒数第k个结点&#x1f338; 1.1 思路 1.2 代码 2. 链表的回文结构&#x1fab8; 2.1 思路 2.2 代码 3.相交链表&#x1f32a;️ 3.1 思路 3.2 代码 4.环形链表I&#x1f30a;&#x1f6f3;️ 4.1 思路 4.2 代码 4…

Redis(三)

4、分布式锁 4.1 、基本原理和实现方式对比 分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路 那么…

HTTP-FLV详解及分析

文章目录 前言一、HTTP-FLV 简介1、市场上使用 http-flv 的商家2、http-flv、rtmp 和 hls 直播的优缺点3、http-flv 技术实现 二、Nginx 配置 http-flv1、Windows 安装 nginx&#xff0c;已经集成 nginx-http-flv-module2、nginx.conf 配置文件3、运行 nginx 服务器4、ffmpeg 推…

FiRa标准——MAC实现(二)

在IEEE 802.15.4z标准中&#xff0c;最关键的就是引入了STS&#xff08;加扰时间戳序列&#xff09;&#xff0c;实现了安全测距&#xff0c;大大提高了测距应用的安全性能。在FiRa的实现中&#xff0c;其密钥派生功能是非常重要的一个部分&#xff0c;本文首先对FiRa MAC中加密…

MeterSphere 任意文件读取漏洞(CVE-2023-25814)

MeterSphere 任意文件读取漏洞&#xff08;CVE-2023-25814&#xff09; 免责声明漏洞描述漏洞影响漏洞危害网络测绘Fofa: title"MeterSphere" 漏洞复现1. 构造poc2. 发送数据包3. 查看文件 免责声明 仅用于技术交流,目的是向相关安全人员展示漏洞利用方式,以便更好地…

Python异常处理:三种不同方法的探索与最佳实践

Python异常处理&#xff1a;三种不同方法的探索与最佳实践 前言 本文旨在探讨Python中三种不同的异常处理方法。通过深入理解各种异常处理策略&#xff0c;我们可以更好地应对不同的编程场景&#xff0c;选择最适合自己需求的方法。 异常处理在编程中扮演着至关重要的角色。合…

吴恩达《机器学习》7-1->7-4:过拟合问题、代价函数、线性回归的正则化、正则化的逻辑回归模型

一、过拟合的本质 过拟合是指模型在训练集上表现良好&#xff0c;但在新数据上的泛化能力较差。考虑到多项式回归的例子&#xff0c;我们可以通过几个模型的比较来理解过拟合的本质。 线性模型&#xff08;欠拟合&#xff09;&#xff1a; 第一个模型是一个线性模型&#xff0…

云效流水线docker部署 :node.js镜像部署VUE项目

文章目录 引言I 流水线配置1.1 项目dockerfile1.2 Node.js 镜像构建1.3 docker 部署引言 云效流水线配置实现docker 部署微服务项目:https://blog.csdn.net/z929118967/article/details/133687120?spm=1001.2014.3001.5501 配置dockerfile-> 镜像构建->docker部署。 …

使用jdk21预览版 --enable-preview

异常 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project sb3: Compilation failure [ERROR] --enable-preview 一起使用时无效 [ERROR] &#xff08;仅发行版 21 支持预览语言功能&#xff09; 解决…

已解决:rm: 无法删除“/opt/module/zookeeper-3.4.10/zkData/zookeeper_server.pid“: 权限不够

解决&#xff1a; ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg Stopping zookeeper ... /opt/module/zookeeper-3.4.10/bin/zkServer.sh: 第 182 行:kill: (4149) - 不允许的操作 rm: 无法删除"/opt/module/zooke…

SparkSQL语法优化

SparkSQL在整个执行计划处理的过程中&#xff0c;使用了Catalyst 优化器。 1 基于RBO的优化 在Spark 3.0 版本中&#xff0c;Catalyst 总共有 81 条优化规则&#xff08;Rules&#xff09;&#xff0c;分成 27 组&#xff08;Batches&#xff09;&#xff0c;其中有些规则会被归…