第2章 Pytoech基础

在第2章里面基础的东西,比如pytorch怎么安装等等的也跳过。

2.4 numpy与tensor

x与y都是torch里面的tensor。

x.add(y)与x.add_(y)的区别:x.add(y)把x与y相加起来,但是不改变x的值,需要用新的存储单位存放数据,x.add_(y),依然是把x,y加起来,但是结果直接更新在x里面。

deep learning with Python 2nd 中文版_标量


torch.tensor与torch.Tensor的区别:torch.tensor是通过传入的数据推断数据类型,torch.Tensor默认使用数据类型是FloatTensor。torch.tensor(1)返回一个固定值1,torch.Tensor返回一个大小为1的张量,值为随机初始化的值。

deep learning with Python 2nd 中文版_数据_02


修改tensor形状:x.reshape() ,x.view().

指定维度增加一个“1”:torch.unsqueeze()

deep learning with Python 2nd 中文版_反向传播_03


索引操作

在指定维度上选择一些行或者列:跟numpy一样操作(x[:,:-2])

获取非0元素的下标:torch.nonzero()

使用二元值进行选择:torch.masked_select()

在指定维度上选择数据:torch.gather()

根据指定索引补充数据:x.scatter_()

deep learning with Python 2nd 中文版_标量_04


广播机制,跟numpy一样会自动拓展

deep learning with Python 2nd 中文版_反向传播_05


归并操作,比较操作都跟numpy一样。就不管了。

矩阵操作,torch中的矩阵操作跟numpy中是不同的。在numpy中直接dot()就行了,在torch中,dot()是对1D张量的操作,mm()是对2D张量的操作,bmm()是对3D张量的操作。

deep learning with Python 2nd 中文版_数据_06

2.5Tensor与Autograd

学习,使用pytorch的自动求导功能。

标量反向传播:

deep learning with Python 2nd 中文版_反向传播_07


非标量反向传播:

非标量的反向传播跟标量反向传播不同的是需要传入一个张量参数。

deep learning with Python 2nd 中文版_标量_08

2.6使用numoy实现机器学习

一个小例子,给定一个数组x,然后基于表达式y=3x^2+2,加上一些噪声数据变成另一组数据y。然后通过梯度下降法迭代学习到3跟这个2。

deep learning with Python 2nd 中文版_标量_09

2.7使用Tensor及Antograd实现机器学习

deep learning with Python 2nd 中文版_反向传播_10

第3章 pytorch神经网络工具箱

3.1神经网络核心组件

核心组件主要包括:
层:神经网络的基本结构,将输入张量转换为输出张量
模型:层构成的网络
损失函数:参数学习的目标函数
优化器:如何使损失函数最小

3.2实现神经网络实例

例子用的是比较经典的手写数字识别,数据集是MNIST。

首先就是下载数据集:

deep learning with Python 2nd 中文版_标量_11


定义超参数跟生成器:

deep learning with Python 2nd 中文版_反向传播_12


构建网络模型:模型很简单,就是3个全连接层,nn.linear()用数学表达就是Ax+b,然后再进行归一化nn.BatchNorma1d(),除了最后一次,每层都归一化和用relu激活函数激活。

deep learning with Python 2nd 中文版_数据_13


把模型放入GPU中,并定义损失函数和优化器:

deep learning with Python 2nd 中文版_数据_14


开始训练模型:代码比较简单,调用训练模式model.train(),然后out = model(img), loss = criterion(out, label)前向传播预测结果,得到loss,接着调用loss.backward()反向传播更新模型参数。训练集跑完调用model.eval()进入测试模型跑测试集。重复20次训练集跟测试集结束。

losses = []
acces = []
eval_losses = []
eval_acces = []
for epoch in range(num_epoches):
    train_loss = 0
    train_acc = 0
    model.train()
    if epoch%5==0:
        optimizer.param_groups[0]['lr']*=0.9
        print(optimizer.param_groups[0]['lr'])
        for img, label in train_loader:
            img=img.to(device)
            label = label.to(device)
            img = img.view(img.size(0), -1)
            out = model(img)
            loss = criterion(out, label)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            train_loss += loss.item()
            _, pred = out.max(1)
            num_correct = (pred == label).sum().item()
            acc = num_correct / img.shape[0]
            train_acc += acc
            
    losses.append(train_loss / len(train_loader))
    acces.append(train_acc / len(train_loader))
    eval_loss = 0
    eval_acc = 0
    model.eval()
    for img, label in test_loader:
        img=img.to(device)
        label = label.to(device)
        img = img.view(img.size(0), -1)
        out = model(img)
        loss = criterion(out, label)
        eval_loss += loss.item()
        _, pred = out.max(1)
        num_correct = (pred == label).sum().item()
        acc = num_correct / img.shape[0]
        eval_acc += acc
    eval_losses.append(eval_loss / len(test_loader))
    eval_acces.append(eval_acc / len(test_loader))
    print('epoch: {}, Train Loss: {:.4f}, Train Acc: {:.4f}, Test Loss: {:.4f}, Test Acc: {:.4f}'
          .format(epoch, train_loss / len(train_loader), train_acc / len(train_loader), 
                     eval_loss / len(test_loader), eval_acc / len(test_loader)))

很快结果就跑出来了:

deep learning with Python 2nd 中文版_数据_15