当前位置:   article > 正文

莫烦 pytorch 建造第一个神经网络_plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:

plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=y.data.numpy(), s=

莫烦主页:https://mofanpy.com/

3. 建造第一个神经网络

3.1 Regression 回归(关系拟合)

神经网络可以分成两种类型:分类(如房价问题)和回归(两类或多类)

  1. import torch
  2. from torch.autograd import Variable
  3. import torch.nn.functional as F
  4. import matplotlib.pyplot as plt
  5. # 在torch当中,数据是有维度的
  6. # torch.unsqueeze()把一维数据变成二维数据,torch只会处理二维数据
  7. # [1,2,3,4] 一维数据
  8. # [[1,2,3,4]]二维数据
  9. x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100,1)
  10. y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100,1)
  11. x, y = Variable(x), Variable(y)
  12. # 打印散点图
  13. # plt.scatter(x.data.numpy(), y.data.numpy())
  14. # plt.show()
  15. # 定义Neural Network
  16. # 继承从torch来的模块Module
  17. class Net(torch.nn.Module):
  18. # __init__搭建层所需要的信息
  19. def __init__(self, n_feature, n_hidden, n_output):
  20. # 搭图之前继承Net到这个模块
  21. super(Net, self).__init__()
  22. # 层命名为hidden
  23. self.hidden = torch.nn.Linear(n_feature, n_hidden) # 一层神经网络(隐藏层),输入数据的个数,输出神经元的个数
  24. # 预测的神经层
  25. self.predict = torch.nn.Linear(n_hidden, n_output) # 预测y的值
  26. # forward神经网络前向传递的过程
  27. # 前面的层信息放到forward上面一个一个组合起来,在torch当中搭流程图
  28. def forward(self, x):
  29. x = F.relu(self.hidden(x))
  30. # self.hidden(x)输出n个hidden units,再用激活函数Rule激活
  31. x = self.predict(x)
  32. return x
  33. net = Net(1, 10, 1)
  34. print(net)
  35. # 可视化过程
  36. plt.ion()
  37. plt.show()
  38. # 优化神经网络
  39. # SGD 随机梯度下降
  40. optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
  41. # lr 为学习率,一般小于1。
  42. # 学习率是调节每一次梯度更新的步长,即神经网络优化一次的步幅,神经网络优化类似于寻找某个(Loss)函数的最小值
  43. # 方法就是随机选个点,然后一点一点挪到最小值
  44. # 如果学习率过大,可能你会离某个局部最小值越跳越远
  45. # 计算误差的手段 MSELoss 均方差代价函数
  46. loss_function = torch.nn.MSELoss()
  47. # 开始训练,t为训练步数
  48. for t in range(100):
  49. prediction = net(x) # 预测值
  50. loss = loss_function(prediction, y) # 计算预测值与真实值y两者误差
  51. optimizer.zero_grad() # 把所有参数的梯度降为0
  52. loss.backward() # 反向传递
  53. optimizer.step() # 以学习效率0.5优化梯度
  54. # 可视化过程
  55. if t % 5 == 0:
  56. # plot and show learning process
  57. plt.cla()
  58. plt.scatter(x.data.numpy(), y.data.numpy())
  59. plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
  60. plt.text(0.5, 0, 'Loss=%.4f' % loss.data, fontdict={'size':20, 'color': 'red'})
  61. plt.pause(0.1)
  62. plt.ioff()
  63. plt.show()

3.2 Classification分类

  1. import torch
  2. from torch.autograd import Variable
  3. import torch.nn.functional as F
  4. import matplotlib.pyplot as plt
  5. n_data = torch.ones(100, 2) # data的基数
  6. x0 = torch.normal(2*n_data, 1) # class0 x data (tensor), shape=(100, 2)
  7. # x0数据的标签是0(zeros)
  8. y0 = torch.zeros(100) # class0 y data (tensor), shape=(100, 1)
  9. x1 = torch.normal(-2*n_data, 1) # class1 x data (tensor), shape=(100, 1)
  10. # x1数据的标签是1(ones)
  11. y1 = torch.ones(100) # class1 y data (tensor), shape=(100, 1)
  12. # cat将x0和x1合并在一起当作数据
  13. x = torch.cat((x0, x1), 0).type(torch.FloatTensor) # FloatTensor = 32-bit floating
  14. # 将y0和y1合并在一起当作标签
  15. y = torch.cat((y0, y1), ).type(torch.LongTensor) # LongTensor = 64-bit integer
  16. # x, y = Variable(x), Variable(y)
  17. # 新版本的tensor和Variable合并啦
  18. # 可视化
  19. # plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=y.data.numpy(), s=100, lw=0, cmap='RdYlGn')
  20. # plt.show()
  21. class Net(torch.nn.Module):
  22. def __init__(self, n_feature, n_hidden, n_output):
  23. super(Net, self).__init__()
  24. self.hidden = torch.nn.Linear(n_feature, n_hidden)
  25. self.predict = torch.nn.Linear(n_hidden, n_output)
  26. def forward(self, x):
  27. x = F.relu(self.hidden(x))
  28. x = self.predict(x)
  29. return x
  30. net = Net(2, 10, 2)
  31. # 输出结果为one-hot形式:使用N位状态寄存器来对N个状态进行编码
  32. # 例如,在二分类中
  33. # [0, 1] 为第二类
  34. # [1, 0] 为第一类
  35. # 在三分类中
  36. # [0, 1, 0] 为第二类
  37. print(net)
  38. # 可视化过程
  39. plt.ion()
  40. plt.show()
  41. optimizer = torch.optim.SGD(net.parameters(), lr=0.02)
  42. loss_function = torch.nn.CrossEntropyLoss()
  43. # [0.2, 0.1, 0.7] = 1 预测值,概率总和为 1
  44. # [0, 0, 1]标签值,CrossEntropyLoss计算标签值和预测值间的误差
  45. for t in range(100):
  46. out = net(x) # F.softmax(out)将输出的结果转换成概率值
  47. loss = loss_function(out, y)
  48. optimizer.zero_grad()
  49. loss.backward()
  50. optimizer.step()
  51. if t % 2 == 0:
  52. # plot and show learning process
  53. plt.cla()
  54. prediction = torch.max(F.softmax(out), 1)[1]
  55. # torch.max()的返回值有两个,第一个是max值是多少,第二个是max的index,这里返回的是index
  56. pred_y = prediction.data.numpy().squeeze()
  57. target_y = y.data.numpy()
  58. plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=pred_y, s=100, lw=0, cmap='RdYlGn' )
  59. accuracy = sum(pred_y == target_y) / 200
  60. plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy, fontdict={'size':20, 'color': 'red'})
  61. plt.pause(0.1)
  62. plt.ioff()
  63. plt.show()

3.3 快速搭建法

  1. # 定义神经网络的两种 methods
  2. # method1
  3. class Net(torch.nn.Module):
  4. def __init__(self, n_feature, n_hidden, n_output):
  5. super(Net, self).__init__()
  6. self.hidden = torch.nn.Linear(n_feature, n_hidden)
  7. self.predict = torch.nn.Linear(n_hidden, n_output)
  8. def forward(self, x):
  9. x = F.relu(self.hidden(x)) # relu是一个函数
  10. x = self.predict(x)
  11. return x
  12. net1 = Net(2, 10, 2)
  13. # method2 不用创建class
  14. net2 = torch.nn.Sequential( # 一层一层罗列神经层
  15. torch.nn.Linear(2, 10),
  16. torch.nn.ReLU(), # ReLU是一个类
  17. torch.nn.Linear(10, 2)
  18. )
  19. print(net1)
  20. print(net2)
  1. 输出结果:
  2. Net(
  3. (hidden): Linear(in_features=2, out_features=10, bias=True)
  4. (predict): Linear(in_features=10, out_features=2, bias=True)
  5. )
  6. Sequential(
  7. (0): Linear(in_features=2, out_features=10, bias=True)
  8. (1): ReLU()
  9. (2): Linear(in_features=10, out_features=2, bias=True)
  10. )
  11. Process finished with exit code 0

3.4 保存提取

  1. import torch
  2. from torch.autograd import Variable
  3. import matplotlib.pyplot as plt
  4. torch.manual_seed(1) # reproducible
  5. # fake data
  6. x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1)
  7. y = x.pow(2) + 0.2*torch.rand(x.size()) #noisy y data (tensor), shape=(100,1)
  8. # 保存神经网络
  9. def save():
  10. # save net1
  11. net1 = torch.nn.Sequential(
  12. torch.nn.Linear(1, 10),
  13. torch.nn.ReLU(),
  14. torch.nn.Linear(10, 1)
  15. )
  16. optimizer = torch.optim.SGD(net1.parameters(), lr=0.2)
  17. loss_func = torch.nn.MSELoss()
  18. for t in range(100):
  19. prediction = net1(x)
  20. loss = loss_func(prediction, y)
  21. optimizer.zero_grad()
  22. loss.backward()
  23. optimizer.step()
  24. torch.save(net1, 'net.pkl') # save entire net
  25. torch.save(net1.state_dict(), 'net_params.pkl')
  26. # save parameters,神经网络的状态,包括神经元的参数、dropout的参数
  27. # 速度快,占内存小
  28. # 提取神经网络
  29. def restore_net():
  30. net2 = torch.load('net.pkl')
  31. def restore_params():
  32. # 首先建立一个跟net1一模一样的神经网络
  33. # 然后将net1的参数复制到net3中
  34. net3 = torch.nn.Sequential(
  35. torch.nn.Linear(1, 10),
  36. torch.nn.ReLU(),
  37. torch.nn.Linear(10, 1)
  38. )
  39. net3.load_state_dict(torch.load('net_params.pkl'))
  40. # 保存net1(1.整个网络 2.只有参数)
  41. save()
  42. # 提取整个网络
  43. restore_net()
  44. # 提取网络参数,复制到新网络
  45. restore_params()

3.5 批数据训练(minibatch training)

批训练可以提升速度,相对于单图训练而言的,因为全部数据过大,所以分批。

minibatch 集合了批梯度下降和随机梯度下降的优点。

  1. import torch
  2. import torch.utils.data as Data
  3. # 5个为一组
  4. BATCH_SIZE = 5
  5. # 对于BATCH_SIZE不能整除数据量时,最后返回的是模数
  6. x = torch.linspace(1, 10, 10) # this is x data (torch tensor)
  7. y = torch.linspace(10, 1, 10) # this is y data (torch tensor)
  8. # 定义一个数据库
  9. # 旧版本为torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)
  10. torch_dataset = Data.TensorDataset(x, y)
  11. loader = Data.DataLoader(
  12. dataset=torch_dataset,
  13. batch_size=BATCH_SIZE,
  14. shuffle=True, # shuffle 定义的是要不要在训练时随机打乱数据,然后再随机开始抽样
  15. # num_workers=2, # 每一次loader提取出batch_x和batch_y的时候,用两个进程来提取的,效率更高
  16. )
  17. # epoch是整个训练集被训练算法遍历的次数
  18. for epoch in range(3):
  19. for step, (batch_x, batch_y) in enumerate(loader):
  20. # batch_x, batch_y 是通过 enumerate 提取 x 和 y ,step 是每组(x, y)的序号
  21. # x 有10个数据,BATCH_SIZE 为5,即2个为一组,step 即为2
  22. # 相当于有 n 个训练样本,BATCH_SIZE 为 m,则每个 epoch 都要进行 n/m 个 step
  23. # training...
  24. print('Epoch: ', epoch, '| Step: ', '| batch_x: ',
  25. batch_x.numpy(), '| batch_y: ', batch_y.numpy())
  1. 注意:windows用户如果报RuntimeError,需要把num_workers=2注释掉
  2. 或者可以将epoch迭代写进函数main(),然后if__name__=='__main__':main();

3.6 加速神经网络训练(Speed Up Training)—— 优化器(Optimizer)

1. 准备工作

  1. # prepare
  2. import torch
  3. import torch.utils.data as Data
  4. import torch.nn.functional as F
  5. # hyper parameters
  6. LR = 0.01
  7. BATCH_SIZE = 32
  8. EPOCH = 12
  9. x = torch.unsqueeze(torch.linspace(-1, 1, 1000), dim=1)
  10. y = x.pow(2) + 0.1*torch.normal(torch.zeros(*x.size()))
  11. torch_dataset = Data.TensorDataset(x, y)
  12. loader = Data.DataLoader(dataset=torch_dataset, batch_size=BATCH_SIZE, shuffle=True)
  13. # 默认的神经网络框架
  14. class Net(torch.nn.Module):
  15. def __init__(self,):
  16. super(Net, self).__init__()
  17. self.hidden = torch.nn.Linear(1, 20) # hidden layer 20个神经元的隐藏层
  18. self.predict = torch.nn.Linear(20, 1) # output layer
  19. def forward(self, x):
  20. x = F.relu(self.hidden(x)) # activation function for hidden layer
  21. x = self.predict(x) # linear output
  22. return x

2. 优化方法:大多方法是在更新神经网络参数那一步做改动

  • SGD(Stochastic Gradient Descent)随机梯度下降:醉汉回家的时候,摇摇晃晃地走了很多弯路。

W+=Learningratedx

  1. # 利用默认神经网络框架建立神经网络,并用优化方法进行优化
  2. net_SGD = Net()
  3. # 建立优化器
  4. opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
  • Momentum:如果说 SGD 中梯度影响的是下降的方向的话,Momentum 中梯度影响的就是下降的速度。醉汉回家的路是下坡路,只要他往下走一点点,由于惯性原则 ,他就会不自觉地往下走,走的弯路也会变少。

m=b1mLearningratedx

W+=m

  1. net_Momentum = Net()
  2. opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
  3. # Momentum 和 SGD 就差了一个 b1*m,可以将 SGD 看作是 momentum(动量)=0 的Momentum
  • AdaGrad:在学习率上做改动,每一个参数的更新都会有它与众不同的学习效率,给醉酒的人一双不好走路的鞋子,使他摇晃着走路的脚疼,鞋子变成了走弯路的阻力,逼着他直着走。

v+=dx2

W+=Learningratedx/v

  • RMSProp:把下坡和不好走的鞋子结合起来。Momentum ( 没有考虑Learningrate ) + AdaGrad

v=b1v+(1b1)dx2

W+=Learningratedx/v

  1. net_RMSprop = Net()
  2. opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
  • Adam:考虑了 Momentum 的 Learningrate

m=b1m+(1b1)dxMomentum

v=b2v+(1b2)dx2AdaGrad

W+=Learningratem/v

  1. net_Adam = Net()
  2. opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))

3. 开始训练

  1. loss_func = torch.nn.MSELoss()
  2. losses_his = [] # record loss(history)
  3. for epoch in range(EPOCH):
  4. print(epoch)
  5. for step, (batch_x, batch_y) in enumerate(loader):
  6. for net, opt, l_his in zip(nets, optimizers, losses_his):
  7. output = net(batch_x) # get output for every net
  8. loss = loss_func(output, batch_y) # compute loss for every net
  9. opt.zero_grad() # clear gradients for next train
  10. loss.backward() # backpropagation, compute gradients
  11. opt.step() # apply gradients
  12. # l_his.append(loss.data[0]) # loss recoder
  13. # 新版使用loss.item
  14. # tensor里只有一个数的时候可以用.item()直接提取
  15. l_his.append(loss.item())

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/358113
推荐阅读
相关标签
  

闽ICP备14008679号