pytorch机器学习小技巧总结

持续更新

------------------2202.12.15更新--------------------

seed 随机种子

seed随即种子的作用是使控制随机数。任何和随机有关的东西都可以设置随机种子。而且设置好了随机种子之后,每次随机的数都是一样的。不设置随机种子数每次生成的随机数不同。
需要注意的是每次random操作前都需要设置,否则:

import numpy as np
seed = 1234
np.random.seed(seed)
a = np.random.random(10)
b = np.random.random(10)
print(a)
print(b)
[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581 0.27259261
 0.27646426 0.80187218 0.95813935 0.87593263]
[0.35781727 0.50099513 0.68346294 0.71270203 0.37025075 0.56119619
 0.50308317 0.01376845 0.77282662 0.88264119]

会看到结果并不相同。正确使用方式是:

import numpy as np
seed = 1234
np.random.seed(seed)
a = np.random.random(10)
np.random.seed(seed)
b = np.random.random(10)
print(a)
print(b)
[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581 0.27259261
 0.27646426 0.80187218 0.95813935 0.87593263]
[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581 0.27259261
 0.27646426 0.80187218 0.95813935 0.87593263]

tdqm可视化进度条

不多说,直接上代码和效果图:

from tqdm import tqdm
from time import sleep

for epoch in range(2):
    for i in enumerate(tqdm(range(10))):
        sleep(0.1)

效果如下:
在这里插入图片描述
非常炫酷。
这可以直接配合DataLoader使用:

train_set = MyDataSet(data=X_train, label=Y_train)  # 通过继承Dataset类的MyDataSet类打包数据,方便后面使用Dataloader方法分类
nb_epoch = 10  # 训练的次数
batch_size = 128  # Batch Size
train_data = DataLoader(train_set, batch_size=batch_size, shuffle=True) 
for epoch in range(nb_epoch):
    model.train()
    # 开始训练
    for batchsz, (data, label) in enumerate(tqdm(train_data)):
     # 你的训练代码

我遇到一个问题需要使用zip,直接使用会没有进度条。因为tqdm无法直接识别zip中的数据长度。所以需要设置tqdmtotal属性。

for epoch in range(2):
    for _, _ in tqdm(zip(range(10), range(10)), total=10):
        sleep(0.1)

你说total你不知道设置多少?
在机器学习中一般就是:

total= int((train_data.shape[0])/batch_size)

其中train_data就是一个epoch中遍历的训练集的样本数。也即是说total就是每一个epoch中有多少个batch。

实现一个循环读取多个Dataloader的batch

难免有这样的需求:想要在每个batch循环中读取不同的DataLoader的数据。咋办:

import torch
from itertools import cycle
from tqdm import tqdm
from torch.utils.data import Dataset, DataLoader


class MyDataSet(Dataset):
    def __init__(self, data, label):
        self.data = data
        self.label = label
        self.length = data.shape[0]

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

    def __len__(self):
        return self.length


BATCH_SIZE = 8  # 每个batch的大小,取5或者8
# 生成测试数据
x1 = torch.linspace(0, 9, 10)  # x(torch tensor)
y1 = torch.linspace(10, 19, 10)  # y(torch tensor)

x2 = torch.linspace(20, 29, 10)  # x(torch tensor)
y2 = torch.linspace(30, 39, 10)  # y(torch tensor)

x3 = torch.linspace(40, 49, 10)  # x(torch tensor)
y3 = torch.linspace(50, 59, 10)  # y(torch tensor)
torch_dataset1 = MyDataSet(data=x1, label=y1)
torch_dataset2 = MyDataSet(data=x2, label=y2)
torch_dataset3 = MyDataSet(data=x3, label=y3)
# 把 dataset 放入 DataLoader
loader1 = DataLoader(
    dataset=torch_dataset1,  # 数据,封装进Data.TensorDataset()类的数据
    batch_size=BATCH_SIZE,  # 每块的大小
    shuffle=True,  # 要不要打乱数据 (打乱比较好)
    num_workers=2,  # 多进程(multiprocess)来读数据
)

loader2 = DataLoader(
    dataset=torch_dataset2,  # 数据,封装进Data.TensorDataset()类的数据
    batch_size=BATCH_SIZE,  # 每块的大小
    shuffle=True,  # 要不要打乱数据 (打乱比较好)
    num_workers=2,  # 多进程(multiprocess)来读数据
)
loader3 = DataLoader(
    dataset=torch_dataset3,  # 数据,封装进Data.TensorDataset()类的数据
    batch_size=BATCH_SIZE,  # 每块的大小
    shuffle=True,  # 要不要打乱数据 (打乱比较好)
    num_workers=2,  # 多进程(multiprocess)来读数据
)


def main():
    for epoch in range(3):
        # 在一轮中迭代获取每个batch(把全部的数据分成小块一块块的训练)
        for step, data in enumerate(tqdm(zip(cycle(loader1), loader2, loader3), total=2)):
            batch1, batch2, batch3 = data
            batch_x1, batch_y1 = batch1
            batch_x2, batch_y2 = batch2
            batch_x3, batch_y3 = batch3
            print('Epoch: ', epoch, '| Step: ', step, '| batch x1: ',
                  batch_x1, '| batch y1: ', batch_y1, '| batch x2: ',
                  batch_x2, '| batch y2: ', batch_y2, '| batch x3: ',
                  batch_x3, '| batch y3: ', batch_y3)


if __name__ == '__main__':
    main()

完美!
------------------2202.12.17更新--------------------

name 属性

python.py文件运行的方式有两种,一种是脚本运行,一种被import 导入运行。
为了更好地做实验,在写两个文件如下:
第一个文件supNet.py:

print("主程序执行了")
def main():
    print(__name__)
    print("main执行了")

def test():
    print("test执行了")

if __name__ == '__main__':
    print(__name__)
    test()

if __name__ == 'supNet':
    print('被import了')

第二个文件test.py:

import supNet
supNet.main()

我们直接运行supNet:
image-20201207172509313
结果说明直接运行脚本,__name__ == ‘__main__’ 恒成立,所以运行主程序之后运行了方法test()
运行test.py:image-20201207172537786
import执行会执行主程序+import后调用的方法。此处调用了main()。其__name__属性为import的文件名。

小结
无论脚本运行还是import,都会先执行主程序。(要import所有可能的库,所以这是合理的)。然后脚本运行__name__ 为’__main__';import的__name__为文件名。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值