我也是无意中入了强化学习的领域,因为我原本研究云计算的任务调度,我发现近几年的工作都是基于强化学习的。所以感觉强化学习一定是大趋势,恰好现在ChatGPT这些人工智能产品出现,更是助推了强化学习的风。那么为什么ChatGPT使用强化学习而非监督学习,其实监督学习在图像识别等等人工智能应用中已经非常成熟了。
我的理解是:监督学习只会墨守成规,而强化学习会创新,如乔布斯总是说“用户不知道自己想要什么,我们要为其创造出来,引导其使用”,这一点从乔布斯引导用户使用鼠标到全触屏手机得到了明显的体现。如果让强化学习智能体按着监督学习的方式去学习,那么将人工智能限定于人类固有的思维当中,在现有的基础上搜索答案,不会产生什么创造性的结果。
而且,人类的答案也并非总是对的,有时候我们也不知道自己想要的是什么,强化学习智能体可以帮我们探索,给出我们意想不到的答案,这就是强化学习的魅力。
继续代码规划之模型存储和重复加载
我们学习的时候要注意一点,要在懂和速度之间进行平衡,有许多东西是工具,不是我们的目标本身,我们会用即可,不要深究,你要是深究就会编程一个DAG的深度遍历,永远到不了头,而且严重偏离目标。比如我们不必了解pytorch内部是如何工作的,只要会用即可,我们不必知道为什么模型要存储成.pkl文件,你只要会存会取即可
import torch
import matplotlib.pyplot as plt
x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)
y=x.pow(2)+0.2*torch.rand(x.size())
def save():
#定义网络
net1=torch.nn.Sequential(torch.nn.Linear(1,10),torch.nn.ReLU(),torch.nn.Linear(10,1))
#优化器
optimizer=torch.optim.SGD(net1.parameters(),lr=0.1)
#定义损失函数
loss_f=torch.nn.MSELoss()
#开训
for i in range(100):
prediction=net1(x)
loss=loss_f(prediction,y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
#OK了
#打印结果,绘图
plt.figure(1,figsize=(10,3))
plt.subplot(131)
plt.title('Title')
plt.scatter(x.data.numpy(),y.data.numpy())
plt.plot(x.data.numpy(),prediction.data.numpy(),'r-',lw=5)
#存储学习好的网络
torch.save(net1,'net.pkl')
torch.save(net1.state_dict(),'net_params.pkl')
#重新加载网络函数
def restore_net():
net2=torch.load('net.pkl')
prediction=net2(x)
#绘制结果
plt.subplot(132)
plt.title('net2')
plt.scatter(x.data.numpy(),y.data.numpy())#绘制散点图
plt.plot(x.data.numpy(),prediction.data.numpy(),'r-',lw=5)
#重新加载模型的参数
def restore_netparams():
#如果加载模型参数,就得先建立一个神经网络模型,再赋值
net3=torch.nn.Sequential(torch.nn.Linear(1,10),torch.nn.ReLU(),torch.nn.Linear(10,1))
#建参数复制
net3.load_state_dict(torch.load('net_params.pkl'))
prediction=net3(x)
#绘制结果
plt.subplot(133)
plt.title('nets3')
plt.scatter(x.data.numpy(),y.data.numpy())
plt.plot(x.data.numpy(),prediction.data.numpy(),'r-',lw=5)
plt.show()
save()
restore_net()
restore_netparams()
注意,要多次运行才会有效果,因为我没有设置内部循环
然后再来试试批量训练的效果
import torch
import torch.utils.data as Data
torch.manual_seed(1)
batch_sizes=5
#通过torch.linspace函数创建了两个大小为10的张量x和y,分别代表输入特征和目标值。
x=torch.linspace(1,10,10)
y=torch.linspace(10,1,10)
#组成数据集
torch_dataset=Data.TensorDataset(x,y)
#批量加载数据
loader=Data.DataLoader(dataset=torch_dataset,batch_size=batch_sizes,shuffle=True,num_workers=2)#这怎么有点类似spark等大数据引擎的计算机制
def show_batch():
for i in range(3):
for step,(batch_x,batch_y) in enumerate(loader):
print('Epoch: ', i, '| Step: ', step, '| batch x: ',
batch_x.numpy(), '| batch y: ', batch_y.numpy())
if __name__ == '__main__':
show_batch()
然后是不同优化器的效果
import torch
import torch.utils.data as Data
import torch.nn.functional as F
import matplotlib.pyplot as plt
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()))
plt.scatter(x.data.numpy(),y.data.numpy())
plt.show()
#加载数据
torch_dataset=Data.TensorDataset(x,y)
loader=Data.DataLoader(dataset=torch_dataset,batch_size=BATCH_SIZE,shuffle=True,num_workers=2)
#定义神经网络
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.hidden=torch.nn.Linear(1,20)
self.output=torch.nn.Linear(20,1)
def forward(self,x):
x=F.relu(self.hidden(x))
x=self.predict(x)
return x
if __name__ == '__main__':
# different nets
net_SGD = Net()
net_Momentum = Net()
net_RMSprop = Net()
net_Adam = Net()
nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]
# different optimizers
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_f=torch.nn.MSELoss()
loss_his=[[],[],[],[]]
#训练
for i in range(EPOCH):
print("epoch:",i)
for step,(b_x,b_y) in enumerate(loader):
for net ,opt,l_his in zip(nets,optimizers,loss_his):
predict=net(b_x)
loss=loss_f(predict,b_y)
opt.zero_grad()
loss.backward()
opt.step()
l_his.append(loss.data.numpy())
#绘制不同优化器的损失函数值
labels=['SGD', 'Momentum', 'RMSprop', 'Adam']
for i,l_his in enumerate(loss_his):
plt.plot(l_his,label=labels[i])
plt.legend(loc='best')
plt.xlabel('xsteps')
plt.ylabel('loss')
plt.ylim(0,0.2)
plt.show()