pytorch、jupyter初识

前言

  如何逐渐掌握深度学习呢,是一个难题,网上参差不齐没有一个非常好非常全面的教程,只能一点一点自己累计,寻找例程来模仿主要理解他是怎么一步步完成任务的、思考一个普遍性的解决问题的过程,如何搭建深度学习的神经网络框架,现在暂时选择pytorch
  然后,目前推荐搭建框架过程使用jupyter notebook,所以也要学习如何使用它,那么我想在每一阶段都解决和思考一些问题记录下来,来一步步稳扎稳打的学习深度学习

个人思路

  其实,深度学习说难不难,说简单肯定不简单,你真的可以甚至1天快速入门、上手,只要你懂一些python语法,稍微看看比较通俗的神经网络的介绍文章,学一种搭建框架的方式就能让你用上你设计的网络结构,大批量的规则化的图像信息甚至也可以从网上获取,然后非常方便的使用、训练、测试。
  但是你想真正用神经网络来解决问题你自己的实际问题,那么这些将远远不够,至少我是这样认为的,所以我寻找了很多比较有顺序的深度学习教程(pytorch的),都需要一篇篇的仔细阅读,深化概念,让之后的进阶操作能更快理解。


学习阶段————初次接触

思考:

  • 如何将一大批尺寸不一、随机的图像统一标准化的作为深度学习的输入、以及同时集合这些输入的label–对应的解,即真实值(来和输出层的计算值比较损失)?
  • 神经网络的框架如何根据自己的要求、向适合解决问题的网络结构改进?
  • 学习如何使用GPU来训练模型?
  • jupyter notebook 中如何正常运行pytorch网络?

一、在Morvan莫烦的pytorch教程中,再次理解神经网络

1.1 神经网络是什么

  • 之前虽然理解了一种说法,好像没提出来,这里讲一讲,但不讲太多,没啥意义
  • 首先,人们希望模仿人类的大脑,即生物神经网络,人类如何形成条件反射?如何学习?如何记忆?大脑内神经元如何工作?神经元之间有什么样的联系?
  • 人工神经网络相比,相似,又不相似,所有神经元的连接在同一时间都是固定的,不会凭空产生新联结,它是一种逐次接近正确答案的训练手段,其中“误差反向传递”起到关键作用

1.2 神经网络的简单结构概念

  • Gradient Descent:梯度下降    Cost Function:损失函数
  • 输入层、隐含层(第1层。。。第n层)、输出层就对应着特征–>代表特征1–>…–>代表特征n–>输出,这些代表特征是越来越抽象的,人越来越无法理解,但计算机就对他比较敏感了
  • 迁移学习:即在当你现有的一般神经网络足够处理比如图片内容种类识别、字符识别的任务后。如果我们在输出层前再加入几层神经网络来训练,就能来完成进阶的任务,比如不仅识别数字,还能知道数字的书写字体。。等等

2.1 选择Pytorch

  • 好用、使用广泛、新颖、直观、动态建立框架
  • torchvision里已经有一些它搭建好的网络,比如resnet(可以可以,我知道例程是这样用的了),然后你用这个已有的网络来训练自己的任务

jupyter notebook工作目录更改为自定义,即在属性栏启动目录将userprofile/..双引号内的内容改为自己希望前往的目录地址,重启即可

2.2 什么是Variable

  •   它在神经网络的训练中是一个关键,为什么这么说?思考一下,神经网络的反向传播算法常用梯度下降法,那其中如何求梯度呢?
      大家都知道就是求偏导数,导数就是梯度,torch里求导数的小帮手就是variable,将tensor张量放进variable中,开启自动求梯度的配置

    1
    variable = Variable(tensor,requires_grad=True) #requires_grad = True

    那么,你以后含variable的运算就都和variable本身建立了某种联系,可以快速得到以后的结果相对variable的梯度

    1
    2
    v_out = torch.mean(variable*variable)  #例如求个平均数的运算
    v_out.backward() #求梯度
  • variable变量不同于tensor,但是variable.data可以得到tensor,如果想进行tensor和numpy_array的转换,那么就要xx.data先得到tensor

  • variable的运算和tensor相似,但不完全相同

2.3 激励函数(AF–activation function)?

  •   激励函数广泛应用在各种层,各种用,可是为什么要激励函数呢?因为复杂问题中,输入输出往往都不是线性关系,不是线性,你就不能简单在他们中间乘个系数。
      进阶的操作就是,在输入做完简单线性处理(乘k)的结果代入一个非线性函数
  •   常用的非线性激活函数由relusigmoidtanh方程,甚至可以自己创造激励函数来求解,不过要注意,这些激励函数必须都是可以微分的,因为需要求梯度求导
  •   当隐藏层不多时,可以尝试任意一个激励函数;不过当隐藏层中含有非常多个layer,就有慎重选择,可能出现梯度爆炸梯度消失(我也不太懂,再学学)。其次,具体案例中,少量隐藏层可以有多种选择,卷积神经网络首选relu循环神经网络首选relutanh

如何应用activation function

  • 理解代码然后实验即可
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import torch
    import torch.nn.functional as F
    from torch.autograd import Variable
    import matplotlib.pyplot as plt

    # fake data

    x = torch.linspace(-5, 5, 200) # x data (tensor), shape=(100, 1)
    x = Variable(x)
    x_np = x.data.numpy() # numpy array for plotting

    # following are popular activation functions

    y_relu = torch.relu(x).data.numpy()
    y_sigmoid = torch.sigmoid(x).data.numpy()
    y_tanh = torch.tanh(x).data.numpy()
    y_softplus = F.softplus(x).data.numpy() # there's no softplus in torch

3.1 构建网络:回归

  • 利用Pytorch建立一个简单的神经网络

    1
    2
    3
    4
    5
    6
    7
    8
    class Net(torch.nn.Module):
    def __init__(self, xxx, xxx, xxx, ...):
    super(Net, self).__init__()
    # xxxxxxxx

    def forward(self, x):
    # xxxxxxxx
    return x
  • 定义一个实际的神经网络

    1
    net = Net(xxx=1, xxx=10, xxx=1, ...)
  • 定义优化器optimizer和损失函数loss function

    1
    2
    optimizer = torch.optim.SGD(net.parameters(), lr=0.2)  #net.parameters():包含了神经网络的所有参数  lr:学习率(步长)
    loss_func = torch.nn.MSELoss() # this is for regression mean squared loss
  • 那么在训练的时候

    • 首先定义网络的输出位置prediction,真正计算损失loss
    • 每次利用优化器清除掉网络中之前计算的梯度
    • 然后开始运行反向传播算法
    • 最后向正确方向迈出一步,用计算出的梯度再计算出新一轮的网络参数
    1
    2
    3
    4
    5
    prediction = net(x)     # input x and predict based on x
    loss = loss_func(prediction, y) # must be (1. nn output, 2. target)
    optimizer.zero_grad() # clear gradients for next train
    loss.backward() # backpropagation, compute gradients
    optimizer.step() # apply gradients

    当然本节是对于简单的回归问题,所以定义输出量的变量简单,损失计算也是简单的均方差算法

3.2 构建网络:分类

  • 与简单的回归神经网络不同的是,分类神经网络的输入量和输出量都不只有一个
  • 输入量可以是一组坐标,甚至可以是一张图片的一个三维张量,而输出则可以是一个输入张量对所有类别的概率判断
  • 分类的损失函数选择和回归是不一样的,教程中选择了loss_func = torch.nn.CrossEntropyLoss()
  • 当然,对于我要解决的字符识别问题而言,输入就要复杂得多,远不是一对坐标那么简单,输出的类别也会有很多,所以更透彻的学习将在第二阶段进行
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×