欢迎订阅本专栏:《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、并预处理好的过程。
数据形式:
表格式数据是比较常见的数据形式,一般存放再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)
(3)标准化特征
特征的数值范围悬殊会导致建模的不准确性,需要将每个特征都进行标准正态分布的转换。
features_mean = torch.mean(features, dim=0)
features_var = torch.bar(features, dim=0)
features_norm = (features - features_mean) / torch.sqrt(features_var)
数据形式:
由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等通过大语料上的训练得到词向量。
数据形式:
图像是以长,高,颜色通道三类信息组成:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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
数据形式:
所谓立体数据即有多张图片组成的数据,如医院里的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)