pytorch学习笔记_1_常用函数
- pytroch
张量维度变化
view函数
-
.view()
函数简介
PyTorch中的.view()
函数是一个用于改变张量形状的方法。它类似于NumPy中的.reshape()
函数,可以通过重新排列张量的维度来改变其形状,而不改变张量的数据。
在深度学习中,.view()
函数常用于调整输入数据的形状以适应模型的输入要求,或者在网络层之间传递数据时进行形状的转换。
.view()
函数的语法如下,shape是一个整数元组,用于指定新的张量形状,新形状的元素个数必须与原形状的元素个数相同。函数返回一个具有指定形状的新张量,但与原始张量共享数据存储,因此它们指向相同的内存区域。:
New_Tensor = Tensor.view(*shape)
-
.view()
相当于reshape、resize,重新调整Tensor的形状。
1 | import torch |
-
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) tensor([[ 0, 1], [ 2, 3], [ 4, 5], [ 6, 7], [ 8, 9], [10, 11], [12, 13], [14, 15]]) tensor([[ 0, 1, 2, 3, 4, 5, 6, 7], [ 8, 9, 10, 11, 12, 13, 14, 15]]) tensor([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]])
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
- view中一个参数定为-1,代表自动调整这个维度上的元素个数,以保证元素的总数不变。
```python
import torch
a1 = torch.arange(0,16)
print(a1)
a2 = a1.view(-1, 16)
a3 = a1.view(-1, 8)
a4 = a1.view(-1, 4)
a5 = a1.view(-1, 2)
a6 = a1.view(4*4, -1)
a7 = a1.view(1*4, -1)
a8 = a1.view(2*4, -1)
a9 = a1.view(-1) # 展平为一维
print(a2)
print(a3)
print(a4)
print(a5)
print(a6)
print(a7)
print(a8)
1 | tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) |
torch.where()
- torch.where(condition, x, y) → Tensor
返回一个新的张量,其中的元素是从 x 或 y 中选择的元素,取决于 condition 中的元素是 True 还是 False。
如果 condition 中的元素是 True,则输出中的对应元素取自 x,否则取自 y。
参数:- condition (BoolTensor) – 一个包含布尔值的张量。
- x (Tensor) – 一个包含要选择的元素的张量。
- y (Tensor) – 一个包含要选择的元素的张量。
返回: - 一个张量,包含从 x 或 y 中选择的元素。
- 要求:x 和 y 的形状必须相同,或者可以广播到相同的形状。condition 的形状必须与 x 和 y 的形状广播后的形状相同。
1 | import torch |
tensor([[-0.0048, -0.7391, 0.0659],
[ 0.5881, 0.2028, -0.7898],
[ 0.9274, 0.0735, -1.4954]])
tensor([[ 1.1377, -0.6713, -1.5883],
[ 0.4658, -0.7398, 0.3812],
[ 0.8525, 0.5940, -1.3472]])
tensor([[ 1.1377, -0.6713, 0.0659],
[ 0.5881, 0.2028, 0.3812],
[ 0.9274, 0.0735, -1.3472]])
model.train() 和 model.eval()
pytorch可以给我们提供两种方式来切换训练和评估(推断)的模式,分别是:model.train()
和 model.eval()
。
一般用法是:在训练开始之前写上 model.trian() ,在测试时写上 model.eval() 。
1. model.train()
在使用 pytorch 构建神经网络的时候,训练过程中会在程序上方添加一句model.train(),作用是 启用 batch normalization 和 dropout 。
如果模型中有BN层(Batch Normalization)和 Dropout ,需要在 训练时 添加 model.train()。
model.train() 是保证 BN 层能够用到 每一批数据 的均值和方差。对于 Dropout,model.train() 是 随机取一部分 网络连接来训练更新参数。
2. model.eval()
model.eval()的作用是 不启用 Batch Normalization 和 Dropout。
如果模型中有 BN 层(Batch Normalization)和 Dropout,在 测试时 添加 model.eval()。
model.eval() 是保证 BN 层能够用 全部训练数据 的均值和方差,即测试过程中要保证 BN 层的均值和方差不变。对于 Dropout,model.eval() 是利用到了 所有 网络连接,即不进行随机舍弃神经元。
为什么测试时要用 model.eval() ?
训练完 train 样本后,生成的模型 model 要用来测试样本了。在 model(test) 之前,需要加上model.eval(),否则的话,有输入数据,即使不训练,它也会改变权值。这是 model 中含有 BN 层和 Dropout 所带来的的性质。
eval() 时,pytorch 会自动把 BN 和 DropOut 固定住,不会取平均,而是用训练好的值。
不然的话,一旦 test 的 batch_size 过小,很容易就会被 BN 层导致生成图片颜色失真极大。
eval() 在非训练的时候是需要加的,没有这句代码,一些网络层的值会发生变动,不会固定,你神经网络每一次生成的结果也是不固定的,生成质量可能好也可能不好。
也就是说,测试过程中使用model.eval(),这时神经网络会 沿用 batch normalization 的值,而并 不使用 dropout。
3. 总结与对比
如果模型中有 BN 层(Batch Normalization)和 Dropout,需要在训练时添加 model.train(),在测试时添加 model.eval()。
其中 model.train() 是保证 BN 层用每一批数据的均值和方差,而 model.eval() 是保证 BN 用全部训练数据的均值和方差;而对于 Dropout,model.train() 是随机取一部分网络连接来训练更新参数,而 model.eval() 是利用到了所有网络连接。
model.eval()
不启用 BatchNormalization 和 Dropout,保证BN和dropout不发生变化,pytorch框架会自动把BN和Dropout固定住,不会取平均,而是用训练好的值,不然的话,一旦test的batch_size过小,很容易就会被BN层影响结果。
Batch Normalization
其作用对网络中间的每层进行归一化处理,并且使用变换重构(Batch Normalization Transform)保证每层提取的特征分布不会被破坏。训练时是针对每个mini-batch的,但是测试是针对单张图片的,即不存在batch的概念。由于网络训练完成后参数是固定的,每个batch的均值和方差是不变的,因此直接结算所有batch的均值和方差。所有Batch Normalization的训练和测试时的操作不同。
Dropout
其作用克服Overfitting,在每个训练批次中,通过忽略一半的特征检测器,可以明显的减少过拟合现象。