1.常用代码
1. 关于数据的格式以及数据的处理
在这里主要介绍关于数据的常见存储格式,以及这些数据如何做处理
1.0 pandas包的使用
在进行数据清理之前,一般是要使用pandas包对数据进行一些处理,将数据转化为dataFrame再进行一些数据清洗操作是我们一贯的流程. pandas的下载就是使用简单的指令 1
pip install pandas(视系统而定)
1.0.1 读取数据的常用函数
数据读取函数 | 说明 |
---|---|
pandas.read_csv() | 读取csv文件中的数据并且转化为dataframe |
pandas.read_excel() | 读取excel文件中的数据并且转化为dataframe |
以此类推 | 差不多 |
以下为代码的展示用例:
1 | import pandas as pd |
1.0.2 pandas中两种常用的数据结构
pandas中有两种常用的数据结构,series以及dataframe,分别对应一维数组和二维数组,大概可以这样子理解(其中dataframe还可以理解为多个series的组合,怪怪的),pandas提供了很多奇奇怪怪的api用来清洗数据.
和张量很像,但是有一点和张量不是很一样,series和dataframe虽然是一维和二维的关系,但是实际上series并不是dataFrame中的每一个行,而是每一个列
比如这个样子
1 | arr = square["name"] |
实际上获取到的是某个索引为name的列,因为dataframe的大致结构是这样子的
name | ..... | |
---|---|---|
0 | 张三 | |
1 | 李四 | |
2 | 王五 |
对于series,需要注意的事情大概只有以下几个 1. Series 中的数据是有序的。 2. 可以将 Series 视为带有索引的一维数组。 3. 索引可以是唯一的,但不是必须的。 4. 数据可以是标量、列表、NumPy 数组等。
此外 series和一维数组也是有一定区别的,其实是个双层结构,包含"索引"和"数值",其他的api请自行查阅文档获取
不过另外有一个值得注意的点,对于这两种pandas的数据结构,[]的用法很灵活
Series:
对于 Series,可以通过布尔索引进行元素的筛选。 1
arr=arr[0,1,0,1] # 这样子是获取整个series的第一个和第三个元素
布尔索引是一种利用布尔条件来选择元素的方法。 当使用 [] 内部加上判断语句时,实际上是在进行布尔索引操作,返回的是满足条件的元素构成的新 Series。 1
2
3arr = arr[arr>0] # 这一列中所有大于0的元素都会进入新的series
# 实际上底层是根据张量运算得到了一共布尔数组,再根据布尔数组选取元素形成新的series
也可以加上另一个索引序列,用来选择对应位置的元素。这两个索引序列可以是布尔值,也可以是整数索引,比如下面整个例子
1 | all_features.dtypes[all_features.dtypes != 'object'].index # 不等于object的列的索引 |
DataFrame:
对于 DataFrame,[] 的用法更加灵活。
可以在 [] 内部使用判断语句,返回满足条件的行(或列)构成的新 DataFrame。 还可以使用另一个索引序列,可以是布尔值、整数索引、切片等,用来选择对应的行和列。
1.0.3 dataframe数据清洗的常用函数
实现对于缺失的处理
1 | # 删除包含缺失值的行或列(需要添加参数) |
数据切片
1 | 选择指定的列 |
一些计算 1
2
3
4df.mean() 计算每列的平均值。
df.median() 计算每列的中位数。
df.mode() 计算每列的众数。
df.count() 计算每列非缺失值的数量。1
2
3pandas.get_dummies(df, dummy_na=True)
df.atypes(int) # 强制转化为int
下方为一共房价数据的清洗的详细操作
1 | with open('./train.csv','r') as file: |
1.1 对于数据的保存和读取
1.1.1 pt格式的数据保存以及读取
pt格式是pytorch的缩写,也是不需要进行数据转化的默认保存方式
对于张量都可以使用该种格式进行保存和读取
代码示例如下,对于单一张量,可以直接使用save和load函数进行读取
1 | import torch |
通过这种文件存取的方式可以将数据进行一个简单的存储,值得一提的是,这种方法同样可以存储张量列表并且按照顺序进行读取
1 | torch.save([x2,y2],'目标地址') |
1.1.2 对于csv的数据保存和处理
ps: 对于csv文件的创建需要另一个包os的参与,这里不做解释
csv文件指的是"逗号分隔符",某种意义上来说和excel处理数据的方式是一样的,按顺序存取,一般来说都是用这个文件格式去存储数据的
对于csv文件,需要使用pandas库中的read_csv函数进行文件读取
1 | with open('./xxx.csv','r') as file: |
注意一下,这里的data并不是常规的数据,而是被称之为dataframe的数据结构,是pandas整个包所规定的
我们可以通过某种手段来进行dataFrame到tensor或者dataset这种便于训练的数据结构的转变
对于DataFrame形式的数据来说, 对于一些奇奇怪怪的数据,很多都是在整个阶段使用pandas中的函数完成处理的
1.2 对于模型的保存和处理
1.2.1 对于模型的参数处理
后面会加以解释,对于一个模型net,我们可以使用state_dict()函数获取参数
获取参数
1 | //使用save函数进行读取,这一点和正常的张量保存是一样的 |
读取参数 1
2//加载参数可以使用load_state_dict函数,参数为一个张量
net.load_state_dict(torch.load('mlp.params'))
1.2.2 对于模型的保存实例
这段代码来自于一个具体的实验项目,我们根据预训练的地址获取模型的参数
再根据自己创建的函数,构建一个空白的模型对象(空白指的是模型参数是空白的)
类比一下就是枪和弹夹的关系
1 | # 加载预训练模型 |
1.3 如何对数据进行训练读取
这里将按照一个csv格式数据的读取,梳理一下大致数据读取以及创建训练加载器的流程
主要的数据读取可以为以下几个步骤来实现
- csv使用pandas读取为DataFrame对象
- (根据需求处理DataFrame对象中的数据)
- DataFrame对象转化为tensor
- tensor转化为dataset对象
- 根据dataset对象创建dataloader
获得了dataloader以后,就可以进行小批量梯度训练了
下面会根据一个完整的整理过程,创建一个可用的数据读取器,假设我们现在在某个位置存在一个csv数据集合
首先,先使用read_csv函数,将csv文件对象读取为dataFrame数据 1
2with open('目标文件地址','r') as file:
csvreader=pandas.read_csv(file)
dataFrame函数可以直接转化为张量, 张量可以足够大, 上百万条数据都可以整合到一起都可以用tensor进行接收
1 | tensor_from_df = torch.tensor(csvreader.values) |
在这里首先使用values函数,将dataFrame转化为数组,然后再根据整个的基础上创建tensor即可
接下来就是根据tensor创建dataset数据集合
(dataset的作用是可以把任意size相同的张量打包成一个整体,并且可以再建立dataloader以后进行进行分别读取)
使用data包下的TensorDataset函数实现张量和dataset的转换,dataset是比较常用的一种对象,一些pytorch内置的数据集就是用这种方式作为存储的 1
2
3
4
5
6
7from torch.utils.data import TensorDataset
# 在这里实现对于data和labels两个张量的数据绑定
datas = torch.tensor([[1,1], [2,2], [3,3], [4,4], [5,5]])
labels = torch.tensor([2, 4, 6, 8, 10])
dataset = TensorDataset(data, labels)
1 | print('data_n',dataset[0][0]) # 读取到了第0个张量的第0个数据 |
顺利得到了dataset以后,就可以创建dataloader来进行数据的迭代 1
2
3
4
5batch_size=256
train_iter=data.DataLoader(mnist_train,batch_size=256,shuffle=True,num_workers=4)
#将这个数据集划分为256一打,洗牌模式随机抽取,四个线程进行读取
test_iter=data.DataLoader(mnist_test,batch_size=256,shuffle=True,num_workers=4)
# 这样就生成一个类似迭代器的东西了,使用for循环可以进行读取1
2for features,labels in train_iter:
..........................
2. 模型的构建,初始化
2.1 模型的两种创建方式
模型存在两种创建方式,第一种是直接根据运算顺序,用sequential容器进行创建
1 | net=nn.Sequential( |
另一种比较常见的创建方式,是使用继承自module的类进行构建,如图所示
1 |
|
至于模型参数的读取,可以直接使用函数
1 | net.state_dict() |
2.整体的训练流程
整体的训练流程也可以划分为几个步骤
- 获取数据集合并且转化为可以用于训练的形式
- 观察数据结构,制造神经网络
- 定制优化器以及损失函数
- 训练并且迭代(计算梯度,梯度清空,反向传播,迭代)
以Fashion为简单案例
1 | import torch |
3.一些其他需要注意的事项
3.1 维度的划分
在pytorch的许多函数中都存在一个东西dim,代表了张量的维度,熟悉了其他语言中向量的操作以后,肯定很容易可以将其和空间联想起来,但是实际上pytorch组织维度的方式和其他语言有些不一样,在这里将会通过cat,split,softmax三个函数来演示dim的具体划分形式
按照正常来说,张量维度的安排顺序和shape的顺序是一致的,也就是从左到右,从0开始
举例: 1
2
3
4a=torch.ones((1,2,3))
a.size(dim=0) #第0个维度的长度为1
a.size(dim=1) #2
a.size(dim=2) #3
以cat函数为例子 1
2
3
4
5
6
7
8
9# 两个示例张量
x1 = torch.ones((3,2))
x2 = torch.ones((3,2))
# 拼接
concatenated_tensor = torch.cat((x1, x2), dim=1) #(3,4)
# 果然拼接顺序不能按照空间想象...而是直接在第几个维度合并...
# 顺序自然是从shape的从左往右数
以split函数为例子 1
2
3
4print(concatenated_tensor.split(2,dim=1))
# 而split函数也是,在某个维度方向上,按照规定步长进行拆分
# 比如(3,4),按照上面函数的拆分效果就是(3,2),(3,2)
以F包下的softmax为例子 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 对第一个维度的延伸方向构建softmax
print(F.softmax(concatenated_tensor,dim=0))
"""
tensor([[0.3333, 0.3333, 0.3333, 0.3333],
[0.3333, 0.3333, 0.3333, 0.3333],
[0.3333, 0.3333, 0.3333, 0.3333]])
"""
# 对第二个维度的延伸方向构建softmax
print(F.softmax(concatenated_tensor,dim=1))
"""
tensor([[0.2500, 0.2500, 0.2500, 0.2500],
[0.2500, 0.2500, 0.2500, 0.2500],
[0.2500, 0.2500, 0.2500, 0.2500]])
"""
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 xranudvilas@gmail.com