Pytorch学习

2019-11-27

感悟:最近跟着师兄搞元学习(Meta Learning)跟One-shot Imitation Learning,看各种论文看的是一头雾水,文章中用的神经网络知识很多哦,而自己总是想系统的学习下神经网络,却总是找借口没学。所以拟定计划每天进行2h的pytorch学习,通过跑一些经典神经网络,以提高对其认识。
之前已经配置好pytorch环境了,今天将其整合到了Pycharm,其实很简单就在settings中将Project Interpreter设置为Anaconda\python.exe就大功告成了,也可以使用GPU进行tensor的运算
学习思路:先将官网的60min的tutorial过一下,以为很好过结果就卡在了第二章了。进行不下去了,特此总结记录下,感觉任重而道远/(ㄒoㄒ)/~~
Chap1-Why is Pytorch很简单,基本上顺着就下来了,除了最后一步,当时设置Project Interpreter的时候,设置为Anaconda\Scripts\conda.exe,配置错误,导致无法运行GPU。
Chap2-AUTOGRAD : 这部分看的就挺懵逼的,稍微罗列下自己困惑,没事多回头看看,看想通了不。

  1. .backward()只能针对标量,之后才能调用.grad去查看梯度
    认知:并不是只针对标量,只是标量的时候不用参数,而对tensor求导时需要传进去一个同shape的tensor gradient-------现在我们解释2.3.1节留下的问题,为什么在y.backward()时,如果y是标量,则不需要为backward()传入任何参数;否则,需要传入一个与y同形的Tensor? 简单来说就是为了避免向量(甚至更高维张量)对张量求导,而转换成标量对张量求导。举个例子,假设形状为 m x n 的矩阵 X 经过运算得到了 p x q 的矩阵 Y,Y 又经过运算得到了 s x t 的矩阵 Z。那么按照前面讲的规则,dZ/dY 应该是一个 s x t x p x q 四维张量,dY/dX 是一个 p x q x m x n的四维张量。问题来了,怎样反向传播?怎样将两个四维张量相乘???这要怎么乘???就算能解决两个四维张量怎么乘的问题,四维和三维的张量又怎么乘?导数的导数又怎么求,这一连串的问题,感觉要疯掉…… 为了避免这个问题,我们不允许张量对张量求导,只允许标量对张量求导,求导结果是和自变量同形的张量。所以必要时我们要把张量通过将所有张量的元素加权求和的方式转换为标量,举个例子,假设y由自变量x计算而来,w是和y同形的张量,则y.backward(w)的含义是:先计算l = torch.sum(y * w),则l是个标量,然后求l对自变量x的导数–参考链接
  2. Function什么鬼与.grad_fn关系
  3. 为什么out.backward(),之后对z.grad与y.grad的结果都为none

2019-11-28

  1. Tensor,Matrix=2D tensor,Vector=1D tensor,Scalar = 0D tensor

2019-12-1

哎,书到用时方恨少,事因经过始知难!想学机器人前言的学习算法,如元学习,深度强化学习等,发现自己神经网络一窍不通,只是单纯的上过课,没有融会贯通过,连皮毛也够不到。于是乎,准备开始利用Pytorch,进行系统的深度神经网络的学习,学着学着发现python储备也不够,只好边看边查。虽说比较费时,但效果自我感觉还行,比较有针对性地学习python碰到那个函数不懂的之类的直接学习。而且微积分,线性代数等等也需要温习与深化。一个矩阵求导就看懵逼了半天。预计要填的坑有:线性代数,微积分,python,pytorch,深度神经网络,数据结构,计算机视觉,视觉伺服,学习人类,深度强化学习,元学习,一次示教模仿学习。

  1. Python中的yield用法:初看以为跟return一样,可是又细细想了下,return的话,一般返回之后就跳出程序不会再回来了。而yield却不是如此,带yield的函数是一个生成器而不是函数了,它的每次执行会继续从上次yield后的程序执行,如下代码所述,是要产生小批量数据集,当第一次yield执行后代码会暂时跳出返回10对特征与标签数据,当下次又执行data_iter,函数会直接从for循环里执行,即i=10,产生下一组小批量数据了。
def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))

    #print(indices)
    random.shuffle(indices)  # 样本的读取顺序是随机的
    #print(indices)
    for i in range(0, num_examples, batch_size):
        j = torch.LongTensor(indices[i: min(i + batch_size, num_examples)]) # 最后一次可能不足一个batch
        #if i == 0:
            #print(j)
        yield  features.index_select(0, j), labels.index_select(0, j)

2019-12-3

对《动手学深度学习》(PyTorch版)部分代码解读

一、3.3.3定义模型代码解读:
Part 1

  1. class LinearNet(nn.Module): 定义了一个继承了nn.Module的LinearNet 类
  2. def init(self, n_feature): 类的实例初始化,self为类的实例,n_feature为用LinearNet类定义一个实例时需要传入的参数,此处含义为输入特征数。
    (注:只有在类中定义的函数,才需要传入self变量,普通函数并不需要,类似this)
  3. super(LinearNet, self).init() :使用LinearNet的继承类nn.Module类来对实例self进行初始化
  4. self.linear = nn.Linear(n_feature, 1):使用nn.Linear类来定义self的一个线性层,此处self.linear名字可以任起名,如self.LP只需要与下面的forward函数一致就可以。此处定义的线性连接层,输入特征为2,输出为1。则y=x*W^T+b(注:在nn.Linear的源码中对于W的定义是(output_feature, input_feature),此处即为一行两列的行向量[w1,w2],因此需要转置)
  5. def forward(self, x): 定义前向传播函数,参数self为类的实例,x为输入样本。本例中为[1000X2]的矩阵,则y的计算通过前面初始化定义的线性层得到,即通过y=x*W^T+b计算得到,同时返回出去。
class LinearNet(nn.Module):
    def __init__(self, n_feature):
        super(LinearNet, self).__init__()
        self.linear = nn.Linear(n_feature, 1)
    # forward 定义前向传播
    def forward(self, x):
        y = self.linear(x)
        return y

net = LinearNet(num_inputs)
print(net) # 使用print可以打印出网络的结构

打印出的网络结构如下:
LinearNet(
(LP): Linear(in_features=2, out_features=1, bias=True)
)
上述代码等价写法:

# 写法一
net = nn.Sequential(
    nn.Linear(num_inputs, 1)
    # 此处还可以传入其他层
    )

# 写法二
net = nn.Sequential()
net.add_module('linear', nn.Linear(num_inputs, 1))
# net.add_module ......

# 写法三
from collections import OrderedDict
net = nn.Sequential(OrderedDict([
          ('linear', nn.Linear(num_inputs, 1))
          # ......
        ]))

print(net)
print(net[0])

Sequential是一个有序的容器,网络层将按照在传入Sequential的顺序依次被添加到计算图中。
Part 2:

num_epochs = 100
for epoch in range(1, num_epochs + 1): # 迭代100轮
    for X, y in data_iter: # 每一轮遍历数据集,每次随机取出一个batch size大小的样本与标签集
        print("X: %s",X)
        output = net(X) # 输入的X,进入到forward函数的参数x中,输出即也就是y的返回
        print("Output: %s",output)
        l = loss(output, y.view(-1, 1)) # 计算loss,里面有.sum()求和的操作,这样做的原因是,loss不能直接求梯度,因为它是tensor,所以先求和转换成标量再求梯度
        print("l: %s",l)
        optimizer.zero_grad() # 梯度清零,等价于net.zero_grad(),要不会累积
        l.backward()
        optimizer.step() 
    print('epoch %d, loss: %f' % (epoch, l.item()))

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值