0%

深度学习-6day

使用张量表征真实数据

新的知识

1
2
3
4
5
·将真实数据表示为pytorch张量
·处理一系列数据类型
·从文件加载数据
·将数据转换为张量
·塑造张量,使他们作为神经网络模型的输入

张量使pytorch中的数据的构建块,神经网络将张量作为输入,并生成张量作为输出,在神经网络内部所有操作其实都是张量之间的操作,神经网络中所有的参数都是张量,要想熟悉pytorch这样的工具,关键是需要了解如何对张量执行操作

处理图像

卷积神经网络的引入彻底的改变了计算机视觉,通过使用成对的输入和期望的输出样本来训练端到端网络,而常见图像加载,要将数据转换为张量所表示

图像应该别表示为一个排列在具有高度和宽度的规则网格中的标量集合,其中高度和宽度以像素为单位,每一个网格点都有一个标量,将被表示为一个灰度图像,或者每个网格点有多个标量,这时每个标量通常会呈现不同的颜色,或者不同的特性

添加颜色通道

有几种方法可以将颜色编码为数字,最常见的方法是RGB,其中颜色由三个数字定义,分别白哦是红绿蓝的强度,我们可以把颜色通道看作是一个灰度强度图,如下图,其中每一个rgb通道都捕获了光谱的特定部分

加载图像文件

图像有几种不同的文件格式,但是在python中由很多的加载图像的方法,从使用imageio模块加载png格式的图像开始

1
2
3
4
import imageio

image_arr = imageio.imread('图片路径')
print(image_arr.shape)

此时img是一个具有三个维度的类numpy数组是对象,2个空间维度尺寸–宽度和高度,第三个维度对应红绿蓝色通道,

改变布局

可以使用张量的permute方法是每一个新的维度利用旧的维度得到一个合适的布局,给定输入张量,先布局通道2,然后是0和1,从而得到一个合适的布局

1
2
img = torch.from_numpy(image_arr)
out = img.permute(2,0,1)

解释一下为什么要改变布局,在深度学习和PyTorch中, 改变图像的布局(如 img.permute(2,0,1) )的主要原因是为了适配神经网络的输入要求 。

  • 原始图片的布局

  • 用 imageio.imread 读取的图片,通常是 (高度, 宽度, 通道) ,即 (H, W, C) ,比如 (256, 256, 3) 。

  • 这种布局是大多数图像处理库(如OpenCV、PIL、imageio)的默认格式。

  • PyTorch的张量布局要求

  • PyTorch 的大多数神经网络(如卷积神经网络)要求输入格式为 (通道, 高度, 宽度) ,即 (C, H, W) 。

  • 例如,RGB图片应为 (3, 256, 256) 。

  • 为什么要这样做?

  • 这样做可以让网络高效地批量处理多张图片(batch),并且与PyTorch的底层实现和加速方式兼容。

  • 如果不转换,直接把 (H, W, C) 的图片输入网络,会导致维度不匹配,报错。

  • permute(2,0,1) 的作用

  • 把原本的 (H, W, C) 变成 (C, H, W) ,即把通道维度移到最前面。

改变图像布局是为了让图片数据符合PyTorch神经网络的输入格式要求,保证模型能够正确处理和训练。

如果你后续要把多张图片组成一个 batch,还需要保证它们的 shape 都是 (C, H, W) ,这样才能直接堆叠成四维张量 (N, C, H, W) (N为图片数量)。

该操作并没有复制张量数据,而是让out和img使用相同的底层存储,

到目前位置,我们只描述了单幅图像,创建一个多图像的数据集作为神经网络的输入,沿着第一维度批量存储图像,以获得一个N x C x H x W的张量

与使用stack构建张量相比,更有效的替代方法是我们可以预先分配一个适当大小的张量,并使用从目录中加载的图像填充他

1
2
batch_size = 3
batch = torch.zeros(batch_size,3,256,dtype=torch.unint8)

这表明我们的批处理将三幅高度256,宽度256的rgb图像组成,现在可以从一个输入目录中加载所有的png图像,并将它们存储在张量中

1
2
3
4
5
6
7
8
9
import os
data_dir = '文件目录'
filenames = [name for name in os.listdir(data_dir)]
for i, filename in enumerate(filename):
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
正规化数据

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

需要做的就是将张量转换为浮点数并对像素的值进行归一化处理,将张量强制转化为浮点数并归一化,正规化的一种方式是将像素值除以255

1
2
batch = batch.float() 
batch /= 255.0

正规化的另一种方法是计算输入数据的均值和标准查,并对其进行缩放,使每一个通道的均值为0,标准差为1:

1
2
3
4
5
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

还可以对输入进行其他的操作,如旋转和缩放啊还有裁剪,这样可能有助于训练,也有可能使任意输入复合网络的输入要求