Linux命令+Pytorch框架学习ing

以前的框架学习,过于花里胡哨,本章开始,从实际应用出发!包含单机多卡使用

一. Linux命令

1. 复制文件/文件夹

cp 源文件地址 目标文件夹地址
cp -r 源文件夹地址 目标文件夹地址

2. 删除文件/文件夹

rm -f 文件地址
rm -r  文件夹地址

3. 修改或移动 文件/文件夹名

# 修改
mv 文件名  新文件名
mv 文件夹名/ 新文件夹名/

# 移动
mv 文件名  目标地址/
mv 文件夹名 目标文件夹地址/    #(目标文件夹已存在)

4 查看磁盘内空间大小

du -h --max-depth=1

查看当前目录及当前目录下一级文件或文件夹各自使用的总空间大小,参考链接

二. Pytorch框架学习

1. Pytorch中clone(),detach()在反向传播时的用法

  参考博文:PyTorch中的clone(),detach()及相关扩展

  总结:如果 a=b.clone().操作 , 则反向传播时梯度从a传到b可以; 而detach()下a直接脱离原计算图。

2. Pycharm字体放大

任务栏放大:参考博文

  • File --> Settings --> Apperance .

代码界面,鼠标滚动缩放:参考博文

  • File —> setting —> Keymap —>在搜*寻框中输入:increase —> Increase Font Size(双击) —> 在弹出的对话框中选择Add Mouse Shortcut ;
  • 同理,缩小则是搜索 decrease.

2. 输出前K个最大值--torch.topk(input, k, dim=None, largest=True, sorted=True)

  参考博文

  • dim:指定维度,否则是最后一个维度 例如 N1N2-->N1K
  • largest:True,最大;False,最小
  • sorted:返回的K值有序

  输出:value,index------index代表的value原本的序号

3. 查看实际运行时调用的cuda版本

import torch
print(torch.version.cuda)

4. 单机多卡 DDP

这里模型采用的torch1.10,故采用torchrun运行,参考博文

  1. rank
  • 多机多卡:代表某一台机器
  • 单机多卡:代表某一块GPU
  1. world_size
  • 多机多卡:代表有几台机器
  • 单机多卡:代表有几块GPU
  1. local_rank
  • 多机多卡:代表某一块GPU的编号
  • 单机多卡:代表某一块GPU的编号

实操demo

  终端运行
torchrun --nproc_per_node=2 ddp_demo.py --batchSize 64 --epochs 10
  采用单机双卡,注意这里,博文中所述--local_rank不是我们设定的,由代码机器自动获取,目前我print会出现两次,应该有方法解决,等下次自己的模型需要再来补充。

点击查看代码
# ddp_demo.py
import torch
import torch.nn as nn
from torch.optim import SGD
from torch.autograd import Variable
from torch.utils.data import Dataset, DataLoader
from torch.utils.data.distributed import DistributedSampler
import os
import argparse


# 定义一个随机数据集
class RandomDataset(Dataset):
    def __init__(self, dataset_size, image_size=32):
        images = torch.randn(dataset_size, 3, image_size, image_size)
        labels = torch.zeros(dataset_size, dtype=int)
        self.data = list(zip(images, labels))

    def __getitem__(self, index):
        return self.data[index]

    def __len__(self):
        return len(self.data)


# 定义模型
class Model(nn.Module):
    def __init__(self, num_classes):
        super(Model, self).__init__()
        self.conv2d = nn.Conv2d(3, 16, 3)
        self.fc = nn.Linear(30 * 30 * 16, num_classes)
        self.softmax = nn.Softmax(dim=1)

    def forward(self, x):
        batch_size = x.shape[0]
        x = self.conv2d(x)
        x = x.reshape(batch_size, -1)
        x = self.fc(x)
        out = self.softmax(x)
        return out


parser = argparse.ArgumentParser()
parser.add_argument('--gpu_id', type=str, default='0,1')
parser.add_argument('--batchSize', type=int, default=64)
parser.add_argument('--epochs', type=int, default=5)
parser.add_argument('--dataset-size', type=int, default=1024)
parser.add_argument('--num-classes', type=int, default=10)
# parser.add_argument('--local_rank', type=int, default=0)
config = parser.parse_args()

os.environ['CUDA_VISIBLE_DEVICES'] = config.gpu_id
torch.distributed.init_process_group(backend="nccl")

local_rank = torch.distributed.get_rank()
torch.cuda.set_device(local_rank)
device = torch.device("cuda", local_rank)

# 实例化模型、数据集和加载器loader
model = Model(config.num_classes)

dataset = RandomDataset(config.dataset_size)
sampler = DistributedSampler(dataset)  # 这个sampler会自动分配数据到各个gpu上
loader = DataLoader(dataset, batch_size=config.batchSize, sampler=sampler)

# loader = DataLoader(dataset, batch_size=config.batchSize, shuffle=True)
loss_func = nn.CrossEntropyLoss()

if torch.cuda.is_available():
    model.cuda()
model = torch.nn.parallel.DistributedDataParallel(model)
optimizer = SGD(model.parameters(), lr=0.1, momentum=0.9)

# 开始训练
for epoch in range(config.epochs):
    for step, (images, labels) in enumerate(loader):
        if torch.cuda.is_available():
            images = images.cuda()
            labels = labels.cuda()
        preds = model(images)
        # print(f"data: {images.device}, model: {next(model.parameters()).device}")
        loss = loss_func(preds, labels)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        print(f'Step: {step}, Loss: {loss.item()}')

    print(f'Epoch {epoch} Finished !')

5. 程序死机--如何关闭

  1. 命令行 xkill --- 选择窗口直接关闭
  2. ps -ef |grep python 然后kill -9 进程号

三. 实际代码操作

1.torch 复制维度

import torch
a = torch.rand(size=(2,3,2))

a = a.repeat(1,2,1) --> 得到(2,6,2)第二个维度会复制全部,这里是完全叠加的一个操作,即后三个是复制前三个数据

a = a.repeat_interleave(2, dim=1) --> 得到(2,6,2)这里的复制是间隔复制,假如初始是 1,2,3  ,复制后为 1,1,2,2,3,3

2.判断nan值

import numpy as np
import torch
a = torch.rand(size=(2,3,2))
print(np.isnan(a.numpy()))

3. one-hot 与 单值标签互转

# one-hot -> 数值
>>> import torch
>>> onehot
array([[0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]])
>>> np.argmax(onehot,1)
array([1, 2, 2, 3], dtype=int64)
>>> torch.topk(torch.tensor(onehot), 1)[1].squeeze(1)
tensor([1, 2, 2, 3])

# 数值-》one-hot
>>> import numpy as np
>>> label = [1,2,2,3]
>>> np.eye(4)[label]
array([[0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]])

>>> import torch 
>>> import torch.nn.functional as F
labels = torch.tensor([0,1,2])
num_classes = 3
one_hot_labels = F.one_hot(labels, num_classes)

3. 百分比 print

print("百分比为:{:.2f}%".format(count / all_count))

4. json文件读取 和 保存

json格式:{'name1':{'key1':..., 'key2':..., },'name2':{'key1':..., 'key2':..., }}

import json
# 读取
def load_json(filename):  
    with open(filename, mode='r', encoding='utf-8') as f:
        data = json.load(f)
    return data

#保存
def save_json(data, filename, save_pretty=False, sort_keys=False):   # save_pretty这里的意思就是按照优雅的格式存储,就有换行有缩进; sort_keys代表关键字按照首字母排序(??)
    with open(filename, mode='w', encoding='utf-8') as f:
        if save_pretty:
            f.write(json.dumps(data, indent=4, sort_keys=sort_keys))
        else:
            json.dump(data, f)

5. text文件读取

text格式:第一行xxxx 第二行xxxx

def load_lines(filename):
    with open(filename, mode='r', encoding='utf-8') as f:
        return [e.strip("\n") for e in f.readlines()]
posted @ 2022-03-13 11:03  steven_zhao1001  阅读(178)  评论(0)    收藏  举报