前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PyTorch深度学习(2)

PyTorch深度学习(2)

作者头像
何武凡
发布2023-03-09 17:10:55
3260
发布2023-03-09 17:10:55
举报

Deep Learning = Learning Hierarchical Representations 深度学习即学习层次的表征。

1. 卷积神经网络

1.1 神经网络可视化(Visualization of neural networks)

神经网络每一层的操作有点像将空间某些区域进行折叠

1.2 卷积神经网络的起源(Convolutional Neural Network;CNN)

受到Fukushima在视觉皮层建模方面的启发,使用简单/复杂的细胞层次结构,结合有监督的训练和反向传播,由Yann LeCun教授于88-89年在多伦多大学开发了第一个CNN。

Fukushima的工作具体是什么呢? 手写数字识别。首次提出应用多层简单或者复杂的细胞结构建模,特征:手工加无监督聚类学习。无反向传播。

1.3 卷积神经网络分解

通用的CNN架构能被分解为以下几个基本结构。

  • 标准化(Normalisation):对比度标准化等
  • 滤波器组(Filter banks):边缘检测等
  • 非线性化(Non-linearities):稀疏化、ReLU等
  • 池化(pooling):最大池化(max pooling)等

2. 自然信号数据(Natural Signals)

2.1 自然信号数据特性

  • 周期性:在时域很多模式都会重复出现
  • 局部性:相邻的点较相远的点来说更具关联性
  • 合成性:复杂的事物可以由简单的事物组合而成。字母->单词->句子->文章

2.2 对应神经网络中的处理方法

  • 周期性\rightarrow参数共享如果数据存在周期性,可以使用参数共享,即卷积核。
  • 局部性\rightarrow稀疏如果数据存在局部性,那么每个神经元只需要与前几个神经元连接
  • 合成性\rightarrow多层即神经网络中多层网络合成最终的结果

3. Pytorch实现Mnist手写字识别

代码语言:javascript
复制
# load package and data
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import matplotlib.pyplot as plt

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 神经网络模型偏爱标准化数据,原因是均值为0方差为1的数据在sigmoid、tanh经过激活函数后求导得到的导数很大,
# 反之原始数据不仅分布不均(噪声大)而且数值通常都很大(本例中数值范围是0~255),激活函数后求导得到的导数
# 则接近与0,这也被称为梯度消失。
# 目录放自己下载好的mnist目录,没有下载将download=True,自己新建一个存放数据目录即可
train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('../LSTM_mnist/mnist', train=True, download=False,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       # mnist数据集均值0.1307,标准差0.3081
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=64, shuffle=True)

test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('../LSTM_mnist/mnist', train=False, transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=1000, shuffle=True)
代码语言:javascript
复制
# define model
class SimpleCNN(nn.Module):
    def __init__(self, input_size, n_feature, output_size):
        super(SimpleCNN, self).__init__()
        self.n_feature = n_feature
        # 关于nn.Conv2d()中参数的解释
        # in_channels (int): Number of channels in the input image
        # out_channels (int): Number of channels produced by the convolution
        # kernel_size (int or tuple): Size of the convolving kernel
        # default stride=1, padding=0, dilation=1, groups=1
        # [groupsc参数详解](https://www.jianshu.com/p/20ba3d8f283c)
        # [图解卷积神经网络中stride, padding等操作可视化](https://github.com/vdumoulin/conv_arithmetic)
        # input: (N, C_in, H_in, W_in)
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=n_feature, kernel_size=5)
        self.conv2 = nn.Conv2d(n_feature, n_feature, kernel_size=5)
        self.fc1 = nn.Linear(n_feature*4*4, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = self.conv1(x)  # Mnist数据原始大小(28*28)28-5+1 = 24 (24*24*n_feature)
        x = F.relu(x)
        x = F.max_pool2d(x, kernel_size=2)  # (12*12*n_feature)
        x = self.conv2(x)  # 12-5+1 = 8 (8*8*n_feature)
        x = F.relu(x)
        x = F.max_pool2d(x, kernel_size=2)  # (4*4*n_feature)这里解释了上面全连接时为啥是4*4
        x = x.view(-1, self.n_feature*4*4)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        x = F.log_softmax(x, dim=1)
        return x
代码语言:javascript
复制
# hyper parameters
epochs = 1
input_size = 28*28
output_size = 10
n_features = 6
lr = 0.01

model = SimpleCNN(input_size, n_features, output_size)
model.to(device)
# optimizer
optimizer = optim.SGD(model.parameters(), lr, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model)))

# model train
for epoch in range(epochs):
    model.train()
    for i, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)

        output = model(data)
        loss = F.nll_loss(output, target)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        if i % 100 == 0:
            print('Train Epoch [{}/{}], [{}/{} ({:.0f}%)], Loss: {:.4f}'.format(
                epoch+1, epochs, i*len(data), len(train_loader.dataset),
                100*i/len(train_loader), loss.item()))
# model eval
model.eval()
test_loss = 0
correct = 0
accuracy_list = []
for data, target in test_loader:
    data, target = data.to(device), target.to(device)

    output = model(data)
    test_loss += F.nll_loss(output, target, reduction='sum').item()
    pred = output.data.max(1, keepdim=True)[1]  # get the index of the max log-probability
    correct += pred.eq(target.data.view_as(pred)).cpu().sum().item()

test_loss /= len(test_loader.dataset)
accuracy = 100. * correct / len(test_loader.dataset)
accuracy_list.append(accuracy)
print('\nTest set Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
    test_loss, correct, len(test_loader.dataset), accuracy))
代码语言:javascript
复制
# 几个预测的实例可视化
for i in range(10):
    plt.subplot(2, 5, i+1)
    plt.imshow(data[i][0])
    plt.title("Prediction: {}".format(
        output.data.max(1, keepdim=True)[1][i].item()))
plt.show()

4. 补充

  1. 可以做一个有趣的实验即打乱图片中的像素后CNN识别正确率下降,而全连接网络则不会,即与最开始提到的三个特性以及对于神经网络采取的假设是吻合的。
  2. 参考2中是对卷积神经网络全面的介绍,包括CNN中常用那些层,以及常用的模型和参数多少计算。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 卷积神经网络
    • 1.1 神经网络可视化(Visualization of neural networks)
      • 1.2 卷积神经网络的起源(Convolutional Neural Network;CNN)
        • 1.3 卷积神经网络分解
        • 2. 自然信号数据(Natural Signals)
          • 2.1 自然信号数据特性
            • 2.2 对应神经网络中的处理方法
            • 3. Pytorch实现Mnist手写字识别
            • 4. 补充
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档