0%

深度学习-7day

三维图像:体数据

前文所提到如何加载和表示二维图像,在某些情况下,例如设计到ct的医学成像应用程序,我们通常需要处理从头到叫的大量图像序列,每一个序列代表人体的一个切片,ct中只有一个单一的强度通道,类似于灰度通道,这意味着通道维度通常在原生数据格式中被忽略,因此原生数据通常有三个维度

存储体数据的张量和图像没任何区别,在通道维度之后,我们有一个额外的维度,即深度,从而得到一个5维的张量

加载特定格式

使用imageio模块中的volread函数加载一个ct扫描样本,该函数接受将目录作为参数,并将所有医学数字成像和通信文件汇编为一个numpy三维数组

1
2
3
4
5
6
import imageio

dir_path = "图像路径"
vol_arr = imageio.voread(dir_path,'DICOM')
print(vol_arr.shape)

由于没有通道信息,布局与pytorch期望的不同,我们必须使用unsqueeze为通道维度流出空间

1
2
vol = torch.from_numpy(vol_arr).float()
vol = torch.unsqueeze(vol,0)

表示表格数据

在机器学习中遇到最简单的数据形式是电子表格,csv文件或者是数据库,无论介质是什么,他都是一张表,每一行包含一个样本或者是记录,其中的列包含关于样本的一部分信息

列可以包含数字,如特定位置的温度或者是标签,以及表示样本属性的字符串,因此,表格数据通常是不是同构的

使用真实的数据集

作为深度学习的实践者,是将真实世界的异构数据编码为浮点数张量,以供神经网络使用,在互联网上我们可以免费或者大量的白哦个数据集,github上有一堆免费开源的数据集

下面举一个例子,葡萄酒的质量数据集是一个免费提供的表格数据集,它包含葡萄牙北部葡萄酒的化学特征以及感官质量评分,可以直接从github上下载

在这个数据集上一个可能的机器学习任务是根据化学特征预测质量评分,如下图所示,我们希望找到数据中化学特征列和质量评分列之间的关系

加载葡萄酒数据张量

我们需要一种比在文本编辑器中打开文件更有用的检查数据的方法,让我们看啊可能如何使用python加载数据,然后将其转化为张量,pytorch提供了几种可选的加载csv文件的方法

1
2
3
·python自带的csv模块
·numpy
·pandas

建议使用numpy,pytorch具有出色的numpy互操作性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 导入csv模块,用于处理CSV文件
import csv
# 导入numpy库并简写为np,numpy是一个强大的数值计算库
import numpy as np
# 设置红酒质量数据集的文件路径,使用绝对路径确保能准确找到文件
wine_path = "E:\\code\\staticlist\\explore-RedwineQuality-Data-master\\wineQualityReds.csv"
# 使用numpy的loadtxt函数加载CSV数据:
# - dtype=np.float32 指定数据类型为32位浮点数
# - delimiter="," 指定CSV文件的分隔符为逗号
# - skiprows=1 跳过第一行(通常是标题行)
wineq_numpy = np.loadtxt(wine_path, dtype=np.float32, delimiter=",", skiprows=1)
# 打印加载的数据数组,查看数据内容
print(wineq_numpy)


输出
[[1.000e+00 7.400e+00 5.900e-01 ... 5.000e-01 9.000e+00 4.000e+00]
[2.000e+00 7.800e+00 8.800e-01 ... 6.800e-01 9.800e+00 5.000e+00]
[3.000e+00 7.800e+00 7.600e-01 ... 6.500e-01 9.800e+00 5.000e+00]
...
[1.597e+03 6.300e+00 5.100e-01 ... 7.500e-01 1.100e+01 6.000e+00]
[1.598e+03 5.900e+00 6.450e-01 ... 7.100e-01 1.020e+01 5.000e+00]
[1.599e+03 6.000e+00 3.100e-01 ... 6.600e-01 1.100e+01 6.000e+00]]

这里我们之规定了二维数组的类型,用于分割每一行数据的分隔符以及不读取第一行,可以检查一下是否读取了所有的数据

1
2
col_list = next(csv.reader(open(wine_path), delimiter=','))#打开指定路径的csv文件,使用reader创建一个csv读取器,设置分隔符为都好,使用next获取文件的第一行,将这些列名存储在变量中
print(wineq_numpy.shape,col_list)

继续将numpy数组转化为pytorch张量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
wineq = torch.from_numpy(wineq_numpy)
print(wineq.shape,wineq.dtype,wineq.stride,wineq.storage)#对张量的一些操作

输出
torch.Size([1599, 13]) torch.float32 <built-in method stride of Tensor object at 0x00000242184A4A50> <bound method Tensor.storage of tensor([[1.0000e+00, 7.4000e+00, 5.9000e-01, ..., 5.0000e-01, 9.0000e+00,
4.0000e+00],
[2.0000e+00, 7.8000e+00, 8.8000e-01, ..., 6.8000e-01, 9.8000e+00,
5.0000e+00],
[3.0000e+00, 7.8000e+00, 7.6000e-01, ..., 6.5000e-01, 9.8000e+00,
5.0000e+00],
...,
[1.5970e+03, 6.3000e+00, 5.1000e-01, ..., 7.5000e-01, 1.1000e+01,
6.0000e+00],
[3.0000e+00, 7.8000e+00, 7.6000e-01, ..., 6.5000e-01, 9.8000e+00,
5.0000e+00],
...,
[1.5970e+03, 6.3000e+00, 5.1000e-01, ..., 7.5000e-01, 1.1000e+01,
6.0000e+00],
[1.5980e+03, 5.9000e+00, 6.4500e-01, ..., 7.1000e-01, 1.0200e+01,
5.0000e+00],
...,
[1.5970e+03, 6.3000e+00, 5.1000e-01, ..., 7.5000e-01, 1.1000e+01,
6.0000e+00],
[1.5980e+03, 5.9000e+00, 6.4500e-01, ..., 7.1000e-01, 1.0200e+01,
...,
[1.5970e+03, 6.3000e+00, 5.1000e-01, ..., 7.5000e-01, 1.1000e+01,
6.0000e+00],
[1.5980e+03, 5.9000e+00, 6.4500e-01, ..., 7.1000e-01, 1.0200e+01,
[1.5970e+03, 6.3000e+00, 5.1000e-01, ..., 7.5000e-01, 1.1000e+01,
6.0000e+00],
[1.5980e+03, 5.9000e+00, 6.4500e-01, ..., 7.1000e-01, 1.0200e+01,
[1.5980e+03, 5.9000e+00, 6.4500e-01, ..., 7.1000e-01, 1.0200e+01,
5.0000e+00],
5.0000e+00],
[1.5990e+03, 6.0000e+00, 3.1000e-01, ..., 6.6000e-01, 1.1000e+01,
[1.5990e+03, 6.0000e+00, 3.1000e-01, ..., 6.6000e-01, 1.1000e+01,
6.0000e+00]])>

至此,我们从数据集中获得了一个浮点数的torch.Tensor对象,它包含所有列,也包括表示质量评分的最后一列

表示分数

我们可以将分数视为一个连续变量,把它当作一个实数,然后执行回归任务,或者将其视为一个标签,并尝试在分类任务总根据化学特征分析猜测标签,然后执行回归任务,或者将其视为一个标签,并尝试在分类任务中根据化学特征分析猜测标签,将其保存在单独的张量中,这样就可以将分数作为基本事实而不必将其输入模型中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
data = wineq[:, :-1]
print(data,data.shape)
输出
tensor([[1.0000e+00, 7.4000e+00, 5.9000e-01, ..., 3.3800e+00, 5.0000e-01,
9.0000e+00],
[2.0000e+00, 7.8000e+00, 8.8000e-01, ..., 3.2000e+00, 6.8000e-01,
9.8000e+00],
[3.0000e+00, 7.8000e+00, 7.6000e-01, ..., 3.2600e+00, 6.5000e-01,
9.8000e+00],
...,
[1.5970e+03, 6.3000e+00, 5.1000e-01, ..., 3.4200e+00, 7.5000e-01,
1.1000e+01],
[1.5980e+03, 5.9000e+00, 6.4500e-01, ..., 3.5700e+00, 7.1000e-01,
1.0200e+01],
[1.5990e+03, 6.0000e+00, 3.1000e-01, ..., 3.3900e+00, 6.6000e-01,
1.1000e+01]]) torch.Size([1599, 12])

如果想要将target张量转换为标签张量,我们可以有 两种方法,这取决于我们使用分类数据的策略或目的

1
2
3
4
5
6
7
8
9
10
11
data = wineq[:, :-1].long()
print(data)

输出
tensor([[ 1, 7, 0, ..., 3, 0, 9],
[ 2, 7, 0, ..., 3, 0, 9],
[ 3, 7, 0, ..., 3, 0, 9],
...,
[1597, 6, 0, ..., 3, 0, 11],
[1598, 5, 0, ..., 3, 0, 10],
[1599, 6, 0, ..., 3, 0, 11]])