pytorch 回归分类常用函数
torch 训练相关
Pytorch 使用 GPU
设备转换
2 things must be on GPU: model, tensors, 处于同设备(CPU 或 GPU)的数据才能够互相运算,否则需要转换到同一设备
1
2
3
4
5
6
7
8
9
10
11
12# For nvidia GPU
cuda_device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# For arm-based Apple M1's GPU
device = torch.device("mps" if torch.backends.mps.is_available() else "cpu")
cpu_device = torch.device("cpu")
# use case
model = model.to(cuda_device)
tensor = tensor.to(device)
model = model.to(cpu_device)torch.cuda()
和tensor.to(torch.device("cuda"))
区别Early versions of pytorch had
.cuda()
and.cpu()
methods to move tensors and models from cpu to gpu and back. However, this made code writing a bit cumbersome. Later versions introduced.to()
that basically takes care of everything in an elegant way:推荐使用新版的
tensor.to(torch.device("cuda"))
注意:tensor.to()
执行的不是 inplace
操作,因此需要赋值;module.to()
执行的是 inplace 操作。
tensor 在 cpu 与 gpu 之间
想要修改模型参数,然后继续使用:
- 将其从 gpu 拷贝一份,使用:
.cpu().detach()
返回 tensor 形式 或.cpu().detach().numpy()
返回 numpy 形式 - 然后,对 tensor 或者 numpy 进行修改 最后,将 CPU 中修改的 tensor(numpy 需要转换为 tensor)拷贝到 gpu 中去:.cuda() 或 .to(device=torch.device('gpu'))
即使 copy.deepcopy 了 tensor, tensor 也是在 gpu 中的,需要转到 cpu
Copy PyTorch Model using deepcopy() and state_dict() - Knowledge Transfer Pytorch 的 12 个坑 - 知乎
- 将其从 gpu 拷贝一份,使用:
model.train() 和 model.eval()
model.train()
: 在使用 pytorch
构建神经网络的时候,训练过程中会在程序上方添加一句
model.train(),作用是启用 batch normalization 和 drop out。
model.eval()
: 测试过程中会使用
model.eval(),这时神经网络会沿用 batch normalization 的值,并不使用 drop
out。
如果模型中有 BN 层 (Batch Normalization)和 Dropout,需要在训练时添加
model.train()
,在测试时添加 model.eval()
。其中
model.train()是保证 BN 层用每一批数据的均值和方差,而
model.eval()
是保证 BN 用全部训练数据的均值和方差;而对于
Dropout,model.train()是随机取一部分网络连接来训练更新参数,而
model.eval()
是利用到了所有网络连接。
如果没有 BN 层 (Batch Normalization)和 Dropout 这两种层,就不用写了。
python - What does model.train() do in PyTorch? - Stack Overflow [PyTorch 学习笔记] 7.3 使用 GPU 训练模型 - 知乎
小知识
Loss.item()
The
.item()
method extracts the loss’s value as a Python float, so that you can do some operations, such as sum and average operations..item()
moves the data to CPU. It converts or extracts the loss’s value as a Python float. and the plain python float number can only live on the CPU.In Pytorch, when dataset = cifar, the type(dataset.targets) is list
注意 pytorch 读取 MNIST 读出来的
dataset.targets
是 Tensor,但是读取 CIFAR10 读取出来的不是 Tensor,而是 list. 统一训练的时候,注意判断Time
CPU 跑 MNIST 多分类逻辑回归: 6 min 左右 GPU 跑 MNIST 多分类逻辑回归: 1min30 min 左右
accuracy
- a binary classification model using logistic regression on MNIST can converges to 98% accuracy
- a multi-class classification model using logistic regression on MNIST can converges to 92% accuracy
参考: python - Logistic Regression implementation with MNIST - not converging? - Stack Overflow
复制创建独立新模型
The PyTorch model 是可变对象,因此直接赋值是浅拷贝,需要使用 `copy.deepcopy()` 或者 `model.state_dict()` 来进行深拷贝。
1
2
import copy
modelB = copy.deepcopy(modelA)
[Copy PyTorch Model using deepcopy() and state_dict() - Knowledge Transfer](https://androidkt.com/copy-pytorch-model-using-deepcopy-and-state_dict/)
numpy 和 torch 的 矩阵乘
两个矩阵相乘: np.dot(A,B)
或者
np.matmul(A, B)
多个矩阵相乘: 每两个使用 dot
或者 matmul
或直接使用 @
符号 对应元素相乘:
np.multiply
或者 *
torch.mul()
是对应元素相乘(可广播),torch.mm()
是矩阵相乘 torch.mul() 和
torch.mm() 区别_mob604756f6df2a 的技术博客_51CTO 博客
jupyter notebook 缓存问题
在外部更改了调用的函数的代码,但是它依然使用旧的缓存的代码,解决方法:
Put in the following two cells at the beggining of your code and it will automatically reload any new version of your code:
1
2%load_ext autoreload
%autoreload 2
交叉熵
交叉熵预测结果的概率矩阵,求预测概率最大的值,可以使用的函数:
1 | torch.max(input, dim, keepdim=False) 返回 (max, max_indices) |
常见形式:
1 | outputs = model(images) |
或
1 | outputs = model(images) |
nn.Parameter 初始化在 GPU 设备上
softmax 和 sigmoid
激活函数 | sigmoid | softmax |
---|---|---|
分类 | 一般用于二值分类,可以但不建议用于多值分类,准确率低 | 可以用于二值以及多值分类 |
使用注意 | 分类不明确的,概率性的,使用 sigmoid | 分类互斥,可以明确输出是哪个类别的使用 softmax |
交叉熵 | BCE: binary cross-entropy | categorical cross-entropy |
machine learning - Sigmoid activation for multi-class classification? - Stack Overflow
binary crossentropy related
torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')
:
weight 是 sigmoid 预测的类别概率,If given, has to be
a Tensor of size nbatch
: [batch_size,
number_class],(需要梯度,float 类别) 'reduction='mean'
:
the sum of the output will be divided by the number of elements in the
output.
nn.BCEWithLogitsLoss()
封装了 sigmoid
所以直接把模型的输入传进去即可。
1 | input = torch.randn(3, requires_grad=True) |
Difference between BCELoss and BCEWithLogitsLoss in PyTorch - Knowledge Transfer
soft targets vs hard target
soft targets 就是 softmax 得出的各类的概率 一般使用 soft target 的 loss function
hard target 包含的信息量(信息熵)很低, soft target 包含的信息量大,拥有不同类之间关系的信息(比如同时分类驴和马的时候,尽管某张图片是马,但是 soft target 就不会像 hard target 那样只有马的 index 处的值为 1,其余为 0,而是在驴的部分也会有概率。)
MNIST softmax logistic regression 参数
1 | Model: "sequential" |