3 PyTorch读入各类形式的数据

欢迎订阅本专栏:《PyTorch深度学习实践》
订阅地址:https://blog.csdn.net/sinat_33761963/category_9720080.html

  • 第二章:认识Tensor的类型、创建、存储、api等,打好Tensor的基础,是进行PyTorch深度学习实践的重中之重的基础。
  • 第三章:学习PyTorch如何读入各种外部数据
  • 第四章:利用PyTorch从头到尾创建、训练、评估一个模型,理解与熟悉PyTorch实现模型的每个步骤,用到的模块与方法。
  • 第五章:学习如何利用PyTorch提供的3种方法去创建各种模型结构。
  • 第六章:利用PyTorch实现简单与经典的模型全过程:简单二分类、手写字体识别、词向量的实现、自编码器实现。
  • 第七章利用PyTorch实现复杂模型:翻译机(nlp领域)、生成对抗网络(GAN)、强化学习(RL)、风格迁移(cv领域)。
  • 第八章:PyTorch的其他高级用法:模型在不同框架之间的迁移、可视化、多个GPU并行计算。

在现实场景中,数据由很多种形式存在,如存在表格中的数据、时间序列数据、图像数据、视频数据、文本数据等。在使用pytorch建立深度学习模型前,无论什么样的数据我们都要转换成tensor的形式, 并做好预处理,为喂入模型做准备。因此本章的主要内容是讲解如何读入各类数据、转换成tensor、并预处理好的过程。

3.1 表格式数据

数据形式:
表格式数据是比较常见的数据形式,一般存放再excel, csv, database中。其每一行是一个样本,每一列是样本的一个特性,每个样本之间是独立的即行与行之间没有顺序关系(和时间序列数据的最大差异)。

数据类型:
每一列的特性在表格类数据类型都可能不同,比如“温度”是数值型,“颜色”是字符串。
而一个pytorch tensor中的数值类型都是需要相同的,因此这就需要转换了。

读入数据:
常用的方法有:csv module, NumPy, Pandas
使用Pandas在时间和内存上都较为高效,但由于本文在将pytorch, 且前文也提到了与NumPy的交互,因此这里先介绍Numpy获取:

import numpy as np

path = "data.csv"
data = np.loadtxt(path, dtype=np.float32, delimiter=",")

检查数据:
可以通过这种方式检查数据大小,和列名

import csv

col_list = next(csv.reader(open(path), delimiter=','))

print(data.shape)
print(col_list)

转换成tensor:

import torch
data = torch.from_numpy(data)

print(data.shape)
print(data.type)

预处理数据:
现在数据以tensor形式存在,但还不可以直接喂给模型,需要做一些预处理。
(1)分割特征集与标签

features = data[:, :-1]
label = data[:, -1]

(2)处理label的格式
若是进行连续变量的预测则label应为浮点型数据, 若是进行分类模型则label需要转换成One-hot格式。

# 预测时:
label_long = data[:, -1].long()

# 分类时:
label_onehot = torch.zeros(label_long.shape[0], 10) # 构建N*C的矩阵,N为样本数量,C为类别数量
label_onehot.scatter_(1, label_long.unsqueeze(1), 1.0)
  • scatter_有下划线,表示是在原tensor上进行直接操作,操作后的结果将代替原tensor
  • scatter中的参数,1表示是在维度为1上做操作;第2个参数指在该索引上填充值;第3个参数指填充值为1.0
  • unsqueeze(1)指增加一个维度

(3)标准化特征
特征的数值范围悬殊会导致建模的不准确性,需要将每个特征都进行标准正态分布的转换。

features_mean = torch.mean(features, dim=0)
features_var = torch.bar(features, dim=0)

features_norm = (features - features_mean) / torch.sqrt(features_var)

3.2 文本类数据

数据形式:
由N行文本组成,一般每行是一篇文章或一个句子。如

我 是 中 国 人
我 爱 我 的 祖 国

读入数据

with open(path, 'r', encoding='utf-8') as f:
    line = f.read()

清理与预处理数据:


def clean(s):
    punctuation = '.,:"!?“”_-'
    word_list = s.lower().replace('\n', '').split()
    word_list = [word.strip(punctuation) for word in word_list]
    return word_list

words_in_line = clean(line)

构建词典:

word_list = sorted(set(clean(line)))
word2index_dict = {word: i for (i, word) in enumerate(word_list)}

构建one-hot编码:
文字应根据词典转换成对应的one-hot形式。

word_tensor = torch.zeros(len(words_in_line), len(word2index)_dict) # 创建一个矩阵存放one-hot向量
for i, word in enumerate(words_in_line):
    word_index = word2index_dict[word]
    word_tensor[i][word_index] = 1  # 将对应位置上的值改为1.

构建text embedding:
one-hot存在维度爆炸影响模型训练与向量之间无含义关联等缺点。目前常用都是使用嵌入式词向量,如word2vec, glove, elmo等通过大语料上的训练得到词向量。

3.3 图像类数据

数据形式:
图像是以长,高,颜色通道三类信息组成:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KuTm5Zyd-1581678968312)(./image/7.png)]

读入一张图像:

import imageio

# 读入以array格式存储
img_arr = imageio.imread('image.jpg')
print(ima_arr.shape)  # (720, 1280, 3)

# 转换为tensor
img = torch.from_numpy(img_arr)

# 维度更换为C*H*W
out = torch.transpose(img, 0, 2)

读入一批图像:

import os

batch_size = 100
batch = torch.zeros(100, 3, 256, 256, dtype=torch.unit8)

data_dir = "data/"
filenames = [name for name in os.listdir(data_dir) if os.path.splittext(name) == '.png']
for i, filename in enumarate(filenames):
    img_arr = imageio.imread(filename)
    batch[i] = torch.transpose(torch.from_numpy(img_arr), 0, 2)

batch的大小:(batch_size, C, H, W),这个数据形式一般可以直接进入模型训练了。

标准化:
(1)归一化

batch = batch.float()
batch /= 255.0

(2)标准正态分布化

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

3.4 立体数据

数据形式:
所谓立体数据即有多张图片组成的数据,如医院里的CT影像,如视频(由多帧图片组成)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q3DrjjSP-1581678968314)(./image/8.png)]
但其实,立体数据只是比图像数据要多一个维度而已,N个立体数据的大小为:NCDHW,其中D是数据的深度,若包含三张图片则深度为3.

数据读入:

dir_path = 'data/xxx'
vol_arr = imageio.volread(dir_path)
print(vol_arr.shape)  # (99,512,512)

# 转换
vol = torch.from _numpy(vol_arr)
vol = torch.transpose(vol, 0, 2)  # (512, 512, 99)
vol = torch.unsequeeze(vol, 0)   # (1, 512, 512, 99)
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页