持续更新
------------------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中的数据长度。所以需要设置tqdm的total属性。
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:
结果说明直接运行脚本,__name__ == ‘__main__’ 恒成立,所以运行主程序之后运行了方法test()
运行test.py:
import执行会执行主程序+import后调用的方法。此处调用了main()。其__name__属性为import的文件名。
小结:
无论脚本运行还是import,都会先执行主程序。(要import所有可能的库,所以这是合理的)。然后脚本运行__name__ 为’__main__';import的__name__为文件名。