Pytorch
- 数据集
- 读取
- transforms
- 定义模型
- 保存加载
- 模式
- cuda
- Tensor
- 运算
- 改变形状
- 操作
- 常用操作
- 梯度
- 优化
- 自定义
- 激活函数和梯度计算
- 数据集
- transform
- 损失函数
- 可视化
- loss
- 优化
- optimizer
- 学习率
- 调试
- 查看model
- 错误总结
- Tensor
数据集
trainloader=torch.utils.data.DataLoader(Dataset类)
读取
ImageFolder假设所有的文件按文件夹保存好,每个文件夹下面存贮同一类别的图片,文件夹的名字为分类的名字。
dataset=ImageFolder('ROOT')#数据集路径
dataset.imgs #所有图片的路径和对应的label
dataset[0][0]#第0张图像数据
dataset[0][1]#第0张的label
transforms
针对PIL:
CenterCrop:在图片的中间区域进行裁
RandomCrop:在一个随机的位置进行裁
RandomHorizontalFlip:以0.5的概率水平翻转给定的PIL图像
RandomVerticalFlip:以0.5的概率竖直翻转给定的PIL图像
RandomResizedCrop:将PIL图像裁剪成任意大小和纵横比
Grayscale:将图像转换为灰度图像
RandomGrayscale:将图像以一定的概率转换为灰度图像
FiceCrop:把图像裁剪为四个角和一个中心
Pad:填充
ColorJitter:随机改变图像的亮度对比度和饱和度
more
定义模型
class Mynet(nn.Module)
保存加载
# 保存
torch.save(model.state_dict(), '\parameter.pt')#.pt/.pth
# 加载
model = Mynet()
model.load_state_dict(torch.load('\parameter.pt'))
# 保存
torch.save(model, '\model.pt')
# 加载
model = torch.load('\model.pt')
cpu加载gpu参数
model.load_state_dict(torch.load('model.pth',map_location='cpu'))
see more link
模式
model.train()#训练
model.eval()#evaluate模式
cuda
查看变量的设备x.device
单gpu
device = torch.device("cuda: 0" if torch.cuda.is_available() else "cpu")
model.to(device)
mytensor = my_tensor.to(device)
input=input.cuda()
input=Variable(input)
model=model.cuda()
多gpu
if torch.cuda.device_count() > 1:
model = nn.DataParallel(model)
model.to(device)
input = data.to(device)
output = model(input)
Tensor
device dtype 定义
dtype = torch.float
device = torch.device("cpu")#"cuda:0"
x = torch.randn(N, D_in, device=device, dtype=dtype)
运算
乘x.mm(w1)
reluh.clamp(min=0)
夹紧torch.clamp(input, min, max, out=None)
x.t()
改变形状
复制扩展:x.repeat(n,m,d)
按维度复制n、m、d次
操作
- 选取:按index索引
torch.index_select(tensor,dim,index)
按masktorch.masked_select(tensor,mask)
- 找出不为0的位置:
torch.nonzero
- 按给定index重新组合:
torch.gather(tensor,dim,index)
- 插入:
a.scatter_(dim,matrix_refer_to_dim,x)
a插入的数 x被插入的 - 拆:
torch.unbind(x,dim)
- 取一段:
a.narrow(dim,start,num)
常用操作
model.parameters()#模型参数
顺序模型
model = torch.nn.Sequential(
torch.nn.Linear(D_in, H),
torch.nn.ReLU(),
torch.nn.Linear(H, D_out),
)
梯度
后向传播loss.backward()
清空model.zero_grad()
优化
optimizer = torch.optim.Adam(model.parameters(),lr=learning_rate)
...
optimizer.step()
自定义
激活函数和梯度计算
class MyReLU(torch.autograd.Function):
@staticmethod
def forward(ctx, input):
ctx.save_for_backward(input)
return input.clamp(min=0)
@staticmethod
def backward(ctx, grad_output):
input, = ctx.saved_tensors
grad_input = grad_output.clone()
grad_input[input < 0] = 0
return grad_input
数据集
class Mydataset(Dataset):
def __init__(self,...)
self.xx=xxx
def __getitem__(self,index):
return xxx
def __len__(self):
return len(xxx)
transform
transform_train1 = transforms.Compose([
transforms.ToPILImage(),
transforms.CenterCrop(32),#PIL操作
transforms.Lambda(lambda img: myfunction(img, [args**]))
transforms.Grayscale(num_output_channels=1),#PIL
transforms.ToTensor(),
transforms.Nomalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]))#output[channel] = (input[channel] - mean[channel]) / std[channel]
损失函数
参考自定义loss 返回标量
可视化
- 创建图像网格
img_grid = torchvision.utils.make_grid(images)
- Tensorboard
创建路径
#tensorboard
from torch.utils.tensorboard import SummaryWriter
# default `log_dir` is "runs" - we'll be more specific here
writer = SummaryWriter('../runs/antsbees')
展示样本图
# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()
# show images
matplotlib_imshow(img_grid, one_channel=True)
# write to tensorboard
writer.add_image('标题', img_grid)
展示网络结构
net=Net()
writer.add_graph(net, images)#graph网络结构
样本低维映射
# helper function 低维映射
def select_n_random(data, labels, n=100):
'''
Selects n random datapoints and their corresponding labels from a dataset
'''
assert len(data) == len(labels)
perm = torch.randperm(len(data))
return data[perm][:n], labels[perm][:n]
# select random images and their target indices
images, labels = select_n_random(images,labels)
# get the class labels for each image
class_labels = [classes[lab] for lab in labels]
# log embeddings
features = images.view(-1, 224 * 224)
#projector
writer.add_embedding(features,
metadata=class_labels,
label_img=images,global_step=2)#.unsqueeze(1)
跟踪模型训练
running_loss += loss.item()
if i % 10 == 9: # every 10 mini-batches...
# ...log the running loss
writer.add_scalar('training loss',
running_loss / 10,
epoch * len(trainloader) + i)#loss写入tensorboard scalar
# ...log a Matplotlib Figure showing the model's predictions on a
# random mini-batch
writer.add_figure('predictions vs. actuals',
plot_classes_preds(net, inputs, labels),
global_step=epoch * len(trainloader) + i)#写测试结果images 详见antsbeetensorboard.ipynb
running_loss = 0.0
loss
criterion = nn.CrossEntropyLoss()
loss = criterion(outputs, labels)
CrossEntropyLoss
交叉熵损失,会把labels转换成0010one-hot形式BCELoss
二元交叉熵损失,两个输入要相同大小
优化
包:torch.optim
optimizer
类函数
load_state_dict(state_dict):加载optimizer状态。
state_dict():以dict返回optimizer的状态。包含两项:state - 一个保存了当前优化状态的dict,param_groups - 一个包含了全部参数组的dict。
add_param_group(param_group)-给 optimizer 管理的参数组中增加一组参数,可为该组参数定制 lr,momentum, weight_decay 等,在 finetune 中常用。
step(closure) :进行单次优化 (参数更新)。
zero_grad() :清空所有被优化过的Variable的梯度。
清除梯度optimizer.zero_grad()
更新optimizer.step()
梯度
- SGD 随机梯度下降
- ASGD平均随机梯度下降算法
- Adagrad
- Adadelta自适应学习率调整
- RMSprop
- Adam自适应矩估计
- Adamax(Adamd的无穷范数变种)
- SparseAdam
- L-BFGS拟牛顿
10.Rprop(适用于fullbatch)
学习率
torch.optim.lr_scheduler
官方Doc 格式
scheduler = ...
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
在optimizer.step()后scheduler.step()
- LambdaLR自定义网络层的学习率
- MultiplicativeLR
- StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)
- MultiStepLR
- ExponentialLR指数
- CosineAnnealingLR
- ReduceLROnPlateau自适应
调试
查看model
model参数
for name, param in model.named_parameters():
print(name,param,param.grad)#名字、参数、梯度
optimizer
optimizer.state_dict()['param_groups'][0]['lr']#查看lr
#Adam (
#Parameter Group 0
# amsgrad: False
# betas: (0.9, 0.999)
# eps: 1e-07
# initial_lr: 0.0003
# lr: 0.0003
# weight_decay: 1e-05
)
错误总结
Tensor
- for提取出来1-Dtensor值维度为0
for value in tensor:#若tensor大于1维则提取一整块,
#若tensor.size()=[10],value.size()=[]