批训练
import torch
import torch.utils.data as Data
BATCH_SIZE = 5
x = torch.linspace(1, 10, 10) # this is x data
y = torch.linspace(10, 1, 10) # this is y data
torch_dataset = Data.TensorDataset(x, y)
loader = Data.DataLoader(
dataset=torch_dataset,
batch_size=BATCH_SIZE,
shuffle=True, # 是否随机打乱数据
num_workers=2, # 使用几个线程/进程
)
if __name__ == "__main__":
for epoch in range(3):
for step, (batch_x, batch_y) in enumerate(loader):
# training...
print('Epoch: ', epoch, '| Step:', step, '| batch x:',
batch_x.numpy(), '| batch y:', batch_y.numpy())
Optimizer 优化器
SGD
喝醉的人,回家的时候,摇摇晃晃,曲折无比,走了很多弯路
w + = − L e a r n i n g w += -Learning w+=−Learning \; r a t e ∗ d x rate * dx rate∗dx
Momentum
将这个喝醉的人放到斜坡上,这个人就会不自觉的依靠惯性向下走,走得弯路也就少了
m
=
b
1
∗
m
−
L
e
a
r
n
i
n
g
m = b1 * m - Learning
m=b1∗m−Learning
\;
r
a
t
e
∗
d
x
rate * dx
rate∗dx
W
+
=
m
W += m
W+=m
AdaGrad
学习率上动了手脚,使得每个参数的更新都会有自己与众不同的学习效率。
给他一双不好走的鞋子,鞋子变成了向前走的阻力,逼着他向前直着走。
v
+
=
d
x
2
v += dx^2
v+=dx2
W
+
=
−
L
e
a
r
n
i
n
g
W += -Learning
W+=−Learning
\;
r
a
t
e
∗
d
x
/
v
rate * dx / \sqrt v
rate∗dx/v
RMsProp
将 Momentum 与 AdaGrad 结合
m
=
b
1
∗
m
+
(
1
−
b
1
)
∗
d
x
m = b1 * m +(1-b1) * dx
m=b1∗m+(1−b1)∗dx ------>Momentum
b
2
∗
v
+
(
1
−
b
2
)
∗
d
x
2
b2 *v +(1-b2)*dx^2
b2∗v+(1−b2)∗dx2 ------------->AdaGrad
W
+
=
−
L
e
a
r
n
i
n
g
W += -Learning
W+=−Learning
\;
r
a
t
e
∗
m
/
v
rate * m/ \sqrt v
rate∗m/v
import torch
import torch.utils.data as Data
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.pyplot as plt
# hyper parameters
LR = 0.01
BATCH_SIZE = 32
EPOCH = 12
x = torch.unsqueeze(torch.linspace(-1, 1, 1000), dim=1)
y = x.pow(2) + 0.1 * torch.normal(torch.zeros(*x.size()))
# plot dataset
# plot.scatter(x.numpy(), y.numpy())
# plt.show()
torch_dataset = Data.TensorDataset(x, y)
loader = Data.DataLoader(dataset=torch_dataset, batch_size=BATCH_SIZE, shuffle=True)
# default network
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(1, 20) # hidden layer
self.predict = torch.nn.Linear(20, 1) # output layer
def forward(self, x):
x = F.relu(self.hidden(x)) # activation function for hidden layer
x = self.predict(x) # linear output
return x
# different nets
net_SGD = Net()
net_Momentum = Net()
net_RMSprop = Net()
net_Adam = Net()
nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]
opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam]
loss_func = torch.nn.MSELoss()
losses_his = [[], [], [], []] # record loss
for epoch in range(EPOCH):
print(epoch)
for step, (batch_x, batch_y) in enumerate(loader):
b_x, b_y = Variable(batch_x), Variable(batch_y)
for net, opt, l_his in zip(nets, optimizers, losses_his):
output = net(b_x) # get output for every net
loss = loss_func(output, b_y) # compute loss for every net
opt.zero_grad() # clear gradients for next train
loss.backward() # backpropagation, compute gradients
opt.step() # apply gradients
l_his.append(loss.item()) # loss recoder
labels = ['SGD', 'Momentum', 'RMSprop', 'Adam']
for i, l_his in enumerate(losses_his):
plt.plot(l_his, label=labels[i])
plt.legend(loc='best')
plt.xlabel('Steps')
plt.ylabel('Loss')
plt.ylim((0, 0.2))
plt.show()