《深度学习之Pytorch实战计算机视觉》阅读笔记 第10章:循环神经网络

1. 循环神经网络

  • 主要用于处理序列相关问题
  • 可以随意控制输入数据及输出数据的数量
  • 简化模型
    20190905091433.png
  • 展开模型
    20190905091540.png
    10.Pytorch实战之循环神经网络 - 图3是最初输入的隐藏层,在一般情况下该隐藏层使用零进行初始化,即全部参数都是零
  • RNN展开
    20190905092046.png
    W表示权重参数,tanh是使用的激活函数
    计算公式如下: 10.Pytorch实战之循环神经网络 - 图5%0A#card=math&code=H%7Bt%2B1%7D%3Dtanh%28H_t%5Ctimes%20W%7BHH%7D%2BX%7Bt%2B1%7D%5Ctimes%20W%7BXH%7D%29%0A&height=20&id=ujlY1)
    则输出结果为: 10.Pytorch实战之循环神经网络 - 图6
    RNN能够很好的对输入的序列数据进行处理,但是不能长期记忆。如果近期输入的数据发生了变化,则会对当前的输出结果产生重大影响。

2. 手写数字识别

  • RNN模型 RNN定义中的一些参数:

    1. class RNN(torch.nn.Module):
    2. def __init__(self):
    3. super(RNN,self).__init__()
    4. self.rnn=torch.nn.RNN(
    5. input_size=28,
    6. hidden_size=128,
    7. num_layers=1,
    8. batch_first=True
    9. )
    10. self.output=torch.nn.Linear(128,10)
    11. def forward(self,input):
    12. output,_=self.rnn(input,None)
    13. output=self.output(output[:,-1,:])
    14. return output
    • input_size:用于指定输入数据的特征数
    • hidden_size:指定最后隐藏层的输出特征数
    • num_layers:RNN循环层的堆叠数量,default=1
    • bias:偏置,default=True
    • batch_fist:在RNN模型的输入层和输出层用到的数据默认维度是(seq,batch,feature),如果指定参数为True,输入层和输出层的数据维度对应为(batch,seq,feature)
  • 数据加载

    1. transform =transforms.Compose([
    2. transforms.ToTensor(),
    3. # 灰度图通道数是1
    4. transforms.Normalize([0.5],[0.5])
    5. ])
    6. dataset_train=datasets.MNIST(
    7. root='../data',
    8. transform=transform,
    9. train=True,
    10. download=True
    11. )
    12. dataset_test=datasets.MNIST(
    13. root="../data",
    14. transform=transform,
    15. train=False
    16. )
    17. train_load=torch.utils.data.DataLoader(
    18. dataset=dataset_train,
    19. batch_size=64,
    20. shuffle=True
    21. )
    22. test_load=torch.utils.data.DataLoader(
    23. dataset=dataset_test,
    24. batch_size=64,
    25. shuffle=True
    26. )
  • 训练
    输出结果:
    20190905105023.png

    1. epoch_n=10
    2. for epoch in range(epoch_n):
    3. running_loss=0.0
    4. running_correct=0
    5. testing_correct=0
    6. print("Epoch {}/{}".format(epoch,epoch_n))
    7. print("*"*20)
    8. for data in train_load:
    9. x_train,y_train=data
    10. x_train=x_train.view(-1,28,28)
    11. x_train,y_train=Variable(x_train),Variable(y_train)
    12. y_pred=model(x_train)
    13. loss=loss_f(y_pred,y_train)
    14. _,pred=torch.max(y_pred.data,1)
    15. optimizer.zero_grad()
    16. loss.backward()
    17. optimizer.step()
    18. running_loss+=loss.item()
    19. running_correct+=torch.sum(pred==y_train.data)
    20. for data in test_load:
    21. x_test,y_test=data
    22. x_test=x_test.view(-1,28,28)
    23. x_test,y_test=Variable(x_test),Variable(y_test)
    24. outputs=model(x_test)
    25. _,pred=torch.max(outputs.data,1)
    26. testing_correct+=torch.sum(pred==y_test.data)
    27. print("Loss is {:.4f},Train Accuracy is {:.4f}%,Test Accuracy is {:.4f}%".\
    28. format(running_loss/len(dataset_train),100*running_correct/len(dataset_train),100*testing_correct/len(dataset_test)))