目录
引入
对于上一篇代码,一般来说要实现多次迭代,则需要循环下面这几步
zhat = net.forward(x)
loss = loss_function(zhat,y.long())
loss.backward()
opt.step()
opt.zero_grad()
问题在于,实际情况中数据量较大,所有数据都要一遍正向传播和反向传播消耗时间,计算量过大这里就采用深度学习入门级优化算法:小批量随机梯度下降 -- 每次迭代前都会从整体的样本中抽一批固定数目的样本组成批次(batch)B,并用B中的样本进行梯度计算,一减少样本量。
使用mini-batch的优点:(对比传统的梯度下降
更容易找到全局最优解
如果是每一次都带入全部数据训练,就意味着每次迭代过程的特征值是相同的,那么梯度方向只受到权重的偏导数的影响,这会使得梯度下降方向改变较小,容易落入局部最优点(如图)。而mini-batch每次使用的特征值是不同的也就意味这迭代过程中梯度方向还会受到特征值的影响,更容易找到全局最优点。
如图:
图中的随机梯度下降是最极端的情况:每一次只抽一个样本
缺点:
由上图可以直观的看到,迭代次数会变多
要定义的两个超参数:
batch_size,
要抽取的数据大小
epochs
先要知道:对于算法而言,如果一直学习同样的一个数据,会让它只执着与样本,失去一定的泛化能力(类似于机器学习中的过拟合)。但是对于mini-batch而言,每次迭代只学习了一小批数据,我们需要一个全体数据被学习了多少次,用epochs来控制
所以循环层数我们可以确定,由epochs做最外层循环,batch做内层循环
引入数据
TensorDataset
用来将特征张量和标签值打包,
from torch.utils.data import TensorDataset
import torch
a = torch.randn(size=(500,2,3,4))
b = torch.randn(size=(500,6,7))
c = torch.randn(size=(500,1))
print(TensorDataset(a,b,c)) # As long as the first dimension is equal,it can be marged.
for i in TensorDataset(a,b,c):
print(i)
break
print : <torch.utils.data.dataset.TensorDataset object at 0x7f8d6459d9a0>
合并的就是a的2,3,4. b的6,7 c的1
DataLoader
用来切割小批量的类
from torch.utils.data import TensorDataset,DataLoader
import torch
a = torch.randn(size=(500,2,3,4))
b = torch.randn(size=(500,6,7))
c = torch.randn(size=(500,1))
# print(TensorDataset(a,b,c)) # As long as the first dimension is equal,it can be marged.
#
# for i in TensorDataset(a,b,c):
# print(i)
# break
data = TensorDataset(a,c)
data_set = DataLoader(data,
batch_size=120,
shuffle=True, # Whether to disturb the data before division?
drop_last=False # Discard the last batch?
)
for j in data_set:
print(j)
就是切割刚刚的数据,按照规定好的大小