pytorch函数学习记录
torch.nn.MSEloss
计算公式:
loss_fn = torch.nn.MSELoss()
例子
import torch
loss_fn = torch.nn.MSELoss()
input = torch.randn(1,2)
target = torch.autograd.Variable(torch.randn(1,2))
loss = loss_fn(input, target)
print(input); print(target); print(loss)
print(input.size(), target.size(), loss.size())
运行结果
loss=((input1-target1)**2+(input2-target2)**2)/2=0.1996
PyTorch中F.cross_entropy()
计算交叉熵我们需要首先计算softmax,然后log,然后再和target做计算,这个函数已经包含了这个过程,所以计算分类损失时就不用另外计算了。
这个是参数的说明,可以看到input和target的维度是不同的,N表示有用的样本,比如正样本或者负样本的个数,C就是类别的个数。
对target的说明:target的内容是每个类别的索引,比如有21个类别,则target中的内容就是0-21之间的一个数,集体为什么可以参考这篇文章
打印模型的参数量和模型结构
这个需要先安装一个torchsummary ,直接pip就行,很方便,安装成功之后就可以使用了
import torch
import torch.nn as nn
# 构建基本模型
class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(32)
self.relu1 = nn.LeakyReLU(0.1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(64)
self.relu2 = nn.LeakyReLU(0.1)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1, bias=False)
self.bn3 = nn.BatchNorm2d(128)
self.relu3 = nn.LeakyReLU(0.1)
def forward(self, x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu1(x)
x = self.conv2(x)
x = self.bn2(x)
x = self.relu2(x)
x = self.conv3(x)
x = self.bn3(x)
output = self.relu3(x)
return output
# 这个是需要安装一个包,直接pip就可以
from torchsummary import summary
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
moduel = MyNet().to(device)
# 这个函数默认在cuda上面,你可以在后面指定运行在cpu还是cuda
summary(moduel, input_size=(3, 416, 416))# 打印参数量和内容
print(moduel)# 打印模型结构
这个包是不是很nice
torch.cat([a,b],dim=1)
outputs = torch.cat([x, tum], dim=1)
tensor的堆叠,a,b要用括号扩住,dim是在哪个维度堆叠
否则会提示你 tuple tensor 等信息
dim省略的话,默认在第0个维度上进行堆叠,看看你的要求是在哪个维度上堆叠,维度不同,结果不同
torch.add(a,b)
c4 = torch.add(c4, f4)
tensor的相加,就是两个维度相同的tensor对应元素加和,
nn.Upsample(scale_factor=2.5, mode=‘nearest’)
nn.Upsample(scale_factor=2.5, mode='nearest')
scale_factor=2.5是采样的scale,他是任意的,可以采样到任意大小。mode是采样的模式。
获得tensor维度
pytorch中:
x.size()# 括号里跟几就是第几维度,没有就是全得
np中:
np.shape(x)[0]# 获取x矩阵的第0维度
x.shape[0] #和上边是一个意思,多种写法而已
计算和sum
torch.sum(x, dim=0)# 将x在0维度上求和
裁剪clamp
torch.clamp(input, min, max, out=None) → Tensor
input(Tensor):输入张量
min:限制范围下限
max:限制范围上限
out(Tensor):输出张量
| min, if input < min
output = | input, if min <= input <= max
| max, if input > max
pytorch基本运算rand,mm,max,topk,cat,permute,squeeze
生成随机数:
torch.rand()
torch.randn()
tensor乘法:
torch.mm(tensor1, tensor2)
返回tensor最大值, 前K个最大值:
max:返回input1中最大的数,和这个数的索引
value, index = input1.max(dim,keepdim=True)
value, index = torch.max(input, dim)
value, index = torch.topk(input, k, dim)
tensor拼接:
torch.cat(list, index)
tensor转置:
torch.Tensor.permute(0,1,2,3,4)
unsqueeze:添加维度 [3,4] -> [1,3,4]
torch.Tensor.unsqueeze(dim)
torch.unsqueeze(tensor, dim)
squeeze:去掉维数为1的维度 [1,3,4] -> [3,4]
torch.Tensor.squeeze()
torch.squeeze(tensor)
nn.Sequential,nn.ModuleList,nn.Sequential(collections.OrderedDict
nn.Sequential(collections.OrderedDict和nn.Sequential的效果差不过,这两个函数都已经实现了forward的前向传播,不用你自己写
区别:nn.Sequential不能对里边的模块进行命名,默认(0,1,2)
nn.Sequential(collections.OrderedDict可以对模块进行命名,
比如:
# Example of using Sequential
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
# Example of using Sequential with OrderedDict
model = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1,20,5)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(20,64,5)),
('relu2', nn.ReLU())
]))
因为里边已经实现了forward,所以里边的顺序已经不能进行修改,所以灵活性比较差,一般的应用场景就是我们已经确定好这个网络是顺序是固定不变的,不如上边的代码。
nn.ModuleList:
nn.ModuleList:是将各个模块组合成一个list,这个模块内部没有实现forward函数,需要自己实现,比如我们在实现fpn网络时都需要上下采样来和前面的层进行堆叠,这里我们就需要这个模块来灵活的构建forword前项传播来达成我们的目标。
这个是参考这边文章写的需要更详细的内容可以点进去看看。