动手学深度学习V2每日笔记(深度卷积神经网络AlexNet)

本文主要参考沐神的视频教程
https://www.bilibili.com/video/BV1h54y1L7oe/spm_id_from=333.788.recommend_more_video.0&vd_source=c7bfc6ce0ea0cbe43aa288ba2713e56d
文档教程 https://zh-v2.d2l.ai/

本文的主要内容对沐神提供的代码中个人不太理解的内容进行笔记记录,内容不会特别严谨仅供参考。

1.函数目录

2. 深度卷积神经网络AlexNet

  • AlexNet赢了2012年lmageNet 竞赛·
  • 更深更大的 LeNet·
  • 主要改进:
    • 丢弃法
    • ReLu
    • MaxPooling
  • 计算机视觉方法论的改变
    在这里插入图片描述
LeNet操作输出形状AlexNet操作输出形状
输入层\1x28x28输入层\3x224x224
卷积层kernel=5、padding=2、stride=1、output_channel=66x28x28卷积层kernel=11、stride=4、output_channel=9696x54x54
平均池化层kernel=2、padding=0、stride=26x14x14最大池化层kernel=3、stride=296x26x26
卷积层kernel=5、padding=0、stride=1、output_channel=1616x10x10卷积层kernel=5、padding=2、output_channel=256256x26x26
平均池化层kernel=2、padding=0、stride=216x5x5最大池化层kernel=3、stride=2256x12x12
全连接层480->120120卷积层kernel=3、padding=1、output_channel=384384x12x12
全连接层120->8484卷积层kernel=3、padding=1、output_channel=384384x12x12
全连接层84->1010卷积层kernel=3、padding=1、output_channel=256256x12x12
\\\最大池化层kernel=3、stride=2256x5x5
\\\全连接层256x5x5->40964096
\\\全连接层4096->40964096
\\\全连接层4096->10001000

在这里插入图片描述
从LeNet(左)到AlexNet(右)
更多细节

  • 激活函数从sigmoid变成了Relu(减缓梯度消失)
  • 隐藏全连接层后加入了丢弃层
  • 数据增强

3 代码实现

3.1 模型

import torch
from torch import nnclass Reshape(torch.nn.Module):def forward(self, x):return x.view(-1, 1, 28, 28)net = nn.Sequential(nn.Conv2d(in_channels=1, out_channels=96, kernel_size=11, stride=4, padding=1),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2),nn.Conv2d(in_channels=96, out_channels=256, kernel_size=5, padding=2),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2),nn.Conv2d(in_channels=256, out_channels=384, kernel_size=3, padding=1),nn.ReLU(),nn.Conv2d(in_channels=384, out_channels=384, kernel_size=3, padding=1),nn.ReLU(),nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, padding=1),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2),nn.Flatten(),nn.Linear(256*5*5, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096,10)
)# X = torch.rand((1,1,224,224), dtype=torch.float32)
# for layer in net:
#     X = layer(X)
#     print(layer.__class__.__name__, 'output shape:\t',X.shape)

3.2 训练

import torch
from torch import nnimport model
import tools
from model import net
from d2l import torch as d2l
import pandas as pd
from tools import *if __name__ == "__main__":batch_size = 128train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size, resize=224)AlexNet = model.nettrain_process = train_ch6(AlexNet,train_iter,test_iter,10,0.01,tools.try_gpu())tools.matplot_acc_loss(train_process)

tools文件

import pandas as pd
import torch
import matplotlib.pyplot as plt
from torch import nn
import time
import numpy as npclass Timer:  #@save"""记录多次运行时间"""def __init__(self):self.times = []self.start()def start(self):"""启动计时器"""self.tik = time.time()def stop(self):"""停止计时器并将时间记录在列表中"""self.times.append(time.time() - self.tik)return self.times[-1]def avg(self):"""返回平均时间"""return sum(self.times) / len(self.times)def sum(self):"""返回时间总和"""return sum(self.times)def cumsum(self):"""返回累计时间"""return np.array(self.times).cumsum().tolist()argmax = lambda x, *args, **kwargs: x.argmax(*args, **kwargs) #返回最大值的索引下标
astype = lambda x, *args, **kwargs: x.type(*args, **kwargs)  # 转换数据类型
reduce_sum = lambda x, *args, **kwargs: x.sum(*args, **kwargs)  # 求和# 对多个变量累加
class Accumulator:"""For accumulating sums over `n` variables."""def __init__(self, n):"""Defined in :numref:`sec_utils`"""self.data = [0.0] * ndef add(self, *args):self.data = [a + float(b) for a, b in zip(self.data, args)]def reset(self):self.data = [0.0] * len(self.data)def __getitem__(self, idx):return self.data[idx]# 计算正确预测的数量
def accuracy(y_hat, y):"""Compute the number of correct predictions.Defined in :numref:`sec_utils`"""if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:y_hat = argmax(y_hat, axis=1)cmp = astype(y_hat, y.dtype) == yreturn float(reduce_sum(astype(cmp, y.dtype)))# 单轮训练
def train_epoch(net, train_iter, loss, trainer):if isinstance(net, nn.Module):net.train()metric_train = Accumulator(3)for X, y in train_iter:y_hat = net(X)l = loss(y_hat, y)if isinstance(trainer, torch.optim.Optimizer):trainer.zero_grad()l.mean().backward()trainer.step()else:l.sum().backward()trainer(X.shape[0])metric_train.add(float(l.sum()), accuracy(y_hat, y), y.numel())#返回训练损失和训练精度return metric_train[0]/metric_train[2], metric_train[1]/metric_train[2]# 单轮训练
def train_epoch_gpu(net, train_iter, loss, trainer,device):if isinstance(net, nn.Module):net.train()metric_train = Accumulator(3)for i, (X, y) in enumerate(train_iter):X, y = X.to(device), y.to(device)y_hat = net(X)l = loss(y_hat, y)if isinstance(trainer, torch.optim.Optimizer):trainer.zero_grad()l.backward()trainer.step()else:l.sum().backward()trainer(X.shape[0])metric_train.add(l * X.shape[0], accuracy(y_hat, y), X.shape[0])#返回训练损失和训练精度return metric_train[0]/metric_train[2], metric_train[1]/metric_train[2]# 用于计算验证集上的准确率
def evalution_loss_accuracy(net, data_iter, loss):if isinstance(net, torch.nn.Module):net.eval()meteric = Accumulator(3)with torch.no_grad():for X, y in data_iter:l = loss(net(X), y)meteric.add(float(l.sum())*X.shape[0], accuracy(net(X), y), X.shape[0])return meteric[0]/meteric[2], meteric[1]/meteric[2]# 用于计算验证集上的准确率
def evalution_loss_accuracy_gpu(net, data_iter, loss, device='None'):if isinstance(net, torch.nn.Module):net.eval()if not device:#将net层的第一个元素拿出来看其在那个设备上device = next(iter(net.parameters())).devicemeteric = Accumulator(3)with torch.no_grad():for X, y in data_iter:if isinstance(X, list):X = [x.to(device) for x in X]else:X = X.to(device)  # 赋值给 X,将数据移动到GPU中y = y.to(device)  # 赋值给 y,将数据移动到GPU中l = loss(net(X), y)meteric.add(l * X.shape[0], accuracy(net(X), y), X.shape[0])# meteric.add(float(l.sum()), accuracy(net(X), y), y.numel())  # 转为浮点数return meteric[0]/meteric[2], meteric[1]/meteric[2]def matplot_acc_loss(train_process):# 显示每一次迭代后的训练集和验证集的损失函数和准确率plt.figure(figsize=(12, 4))plt.subplot(1, 2, 1)plt.plot(train_process['epoch'], train_process.train_loss_all, "ro-", label="Train loss")plt.plot(train_process['epoch'], train_process.val_loss_all, "bs-", label="Val loss")plt.legend()plt.xlabel("epoch")plt.ylabel("Loss")plt.subplot(1, 2, 2)plt.plot(train_process['epoch'], train_process.train_acc_all, "ro-", label="Train acc")plt.plot(train_process['epoch'], train_process.val_acc_all, "bs-", label="Val acc")plt.xlabel("epoch")plt.ylabel("acc")plt.legend()plt.show()def gpu(i=0):"""Get a GPU device.Defined in :numref:`sec_use_gpu`"""return torch.device(f'cuda:{i}')def cpu():"""Get the CPU device.Defined in :numref:`sec_use_gpu`"""return torch.device('cpu')
def num_gpus():"""Get the number of available GPUs.Defined in :numref:`sec_use_gpu`"""return torch.cuda.device_count()def try_gpu(i=0):"""Return gpu(i) if exists, otherwise return cpu().Defined in :numref:`sec_use_gpu`"""if num_gpus() >= i + 1:return gpu(i)return cpu()def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):"""用GPU训练模型(在第六章定义)"""#模型参数初始化def init_weights(m):if type(m) == nn.Linear or type(m) == nn.Conv2d:nn.init.xavier_uniform_(m.weight)net.apply(init_weights)print("training on", device)net.to(device)# 定义优化器ptimizer = torch.optim.SGD(net.parameters(), lr=lr)# 定义损失函数loss = nn.CrossEntropyLoss()# 训练集损失函数# 训练集损失列表train_loss_all = []train_acc_all = []# 验证集损失列表val_loss_all = []val_acc_all = []timer = Timer()timer.start()for epoch in range(num_epochs):train_loss, train_acc = train_epoch_gpu(net, train_iter, loss, ptimizer, device)val_loss, val_acc = evalution_loss_accuracy_gpu(net, test_iter, loss, device)train_loss_all.append(train_loss)train_acc_all.append(train_acc)val_loss_all.append(val_loss)val_acc_all.append(val_acc)print("{} train loss:{:.4f} train acc: {:.4f}".format(epoch, train_loss_all[-1], train_acc_all[-1]))print("{} val loss:{:.4f} val acc: {:.4f}".format(epoch, val_loss_all[-1], val_acc_all[-1]))print("训练和验证耗费的时间{:.0f}m{:.0f}s".format(timer.stop() // 60, timer.stop() % 60))train_process = pd.DataFrame(data={"epoch": range(num_epochs),"train_loss_all": train_loss_all,"val_loss_all": val_loss_all,"train_acc_all": train_acc_all,"val_acc_all": val_acc_all, })return train_process

4 QA

问题1:老师,ImageNet数据集是怎么构建的,现在看是不是要成为历史了?
ImageNet数据集仍然还是一个很重要的数据集。在多数卷积神经网络中还是使用该数据集验证模型性能。

问题2:为什么2000年的时候,神经网络被核方法代替?是因为神经网络运算量太大,数据多,硬件跟不上吗?
主要是核方法有很好理论,同时在2000年的时候深度神经网络计算不动。

问题3:nlp领域,cnn也代替了人工特征工程吗?如何看待nlp领域transformer、bert、deepfm这些方法和cv领域cnn方法的区别?
nlp与cnn在设计思路上是没有区别的。

问题4:alexNet让机器自己寻找特征,这些找到的特征都符合人类的逻辑吗?如果不复合的话,要怎么解释?
AlexNet寻找的特征通常是不符合人类的逻辑。其优化的目标是让机器模型可以更好的分类,再此过程中并没有考虑人的因素。因此深度学习神经网络解释性较差。

问题7:从发展视角来看,CNN完爆MLP吗?未来MLP是否有可能由于某些技术成为主流?
CNN就是一个特殊的MLP,MLP可以做更多的结构化设计。Transformer你也可以认为是MLP加一起其他东西的设计。

问题11:我们在一个识别细胞的程序里做了颜色+几何变换的增强后效果反倒比只做几何变化的增强效果差。这个可能是因为什么?
这个现象属于正常现象。数据增强加多变差不是一个很奇怪的事情。

问题13:没太明白为什么leNet不属于深度卷积神经网络?
对于好的研究成果也要学会包装和营销。取一个好的名字很重要。突出自己工作内容的创新。

问题16:作为一个行外汉,感觉现在新的CV领域模型也越来越少,大家都在搞demo。老师如何看待这件事呢?
这是技术发展的必然过程。这是一个好的现象。大家搞demo可以将技术落地,搞出产品。现在去做CNN的设计比较难。

问题17:网络要求输入的size是固定的,实际使用的时候图片不一定是要求的size,如果强行resize成网络要求的size,会不会最后的效果要差?
当图片过大的时候,通常会将短边压缩到要求的宽度然后再冲里面随机扣除符合要求的图片去做训练或者测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394056.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13021.Nvidia AGX orin 平台学习记录

文章目录 1 Jetson AGX 开发板编译环境搭建1.1 官方资料包下载1.2 开发者手册1.2.1 安装jetpack 2 更新Image文件2.1 自编译的Image内核文件更新到系统 3 编译文档3.1 编译内核步骤3.1.1 下载kernel_src 源码包3.1.2 编译内核 3.2 编译内核工具链下载3.2 orin 介绍 4 csi_trace…

Shell定时上传日志到HDFS

Shell定时上传日志到HDFS 一、任务需求二、实现思路三、具体实现流程3.1 规划文件上传目录3.2 开发 shell 脚本3.3 授予 shell 可执行权限3.4 手动执行查看3.4 定时执行 shell 脚本 一、任务需求 公司在线服务器每天都会产生网站运行日志,为了避免志文件过大&#…

QT Word文档控件QAxWidget C++退出

我们知道每次加载word控件&#xff0c;都会导致后台启动一个WINWORD.EXE 如何安全退出呢 1、一个最简单的例子 QT core gui axcontainer MainWindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QAxWidget> #include…

【强化学习的数学原理】课程笔记--6(Actor-Critic方法)

目录 Actor-Critic 方法QAC 算法Advantage Actor-Critic 算法Baseline invariance Off-policy Actor-Critic重要性采样 Deterministic Policy Gradient (DPG) 系列笔记&#xff1a; 【强化学习的数学原理】课程笔记–1&#xff08;基本概念&#xff0c;贝尔曼公式&#xff09; …

Java哈希算法

哈希算法 哈希算法1.概述2.哈希碰撞3.常用的哈希算法4.哈希算法的用途4.1校验下载文件4.2存储用户密码MD5加密5.SHA-1加密小结&#xff1a; 哈希算法 1.概述 哈希算法&#xff08;Hash&#xff09;又称摘要算法&#xff08;Digest&#xff09;&#xff0c;它的作用是&#xf…

[软件测试·研究向] MuJava 工具遇到的问题汇总和体会

MuJava 是初学者&#xff08;研究向&#xff09;常常会去使用的一个工具&#xff0c;也是 Java 软件测试的一个老牌工具。用于为 Java 代码生成变异体和运行单元测试。但是此工具已经有十年没有更新了&#xff0c;这款软件可以说现在已经不能够支持对主流软件框架运行测试。但是…

软考-软件设计师 (计算机组成和体系结构习题)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

优秀的行为验证码的应用场景与行业案例

应用场景 登录注册 &#xff1a; 验证码适用于App、Web及小程序等用户注册场景&#xff0c;可以抵御自动机恶意注册&#xff0c;垃圾注册、抵御撞库登录、暴力破解、验证账号敏感信息的修改&#xff0c;同时可以有效阻止撞库攻击&#xff0c;从源头进行防护&#xff0c;保障正…

ip地址冲突会影响整个网络吗

在数字化时代&#xff0c;网络已成为连接世界的桥梁&#xff0c;而IP地址则是这座桥梁上不可或缺的“门牌号”。然而&#xff0c;当这个独特的身份标识出现冲突时&#xff0c;整个网络的稳定运行将面临严峻挑战。IP地址冲突&#xff0c;这一看似微小的技术问题&#xff0c;实则…

【电路笔记】-无源衰减器

无源衰减器 文章目录 无源衰减器1、概述2、简单衰减器3、无源衰减器示例14、无源衰减器设计5、切换式衰减器6、总结无源衰减器是一种特殊类型的电气或电子双向电路,由完全电阻元件组成。 1、概述 无源衰减器基本上是两个端口电阻网络,旨在将电源提供的功率削弱或“衰减”(因…

递归深度问题和尾调用的关系

当我们在编写计算阶乘的函数&#xff0c;一般我们都会会选择使用迭代或递归的方法来实现。下面就让我们看看&#xff0c;同一个函数的两种实现方法。首先&#xff0c;是使用迭代方式实现的函数&#xff0c;我们使用循环的方式来计算阶乘&#xff1a; // 阶乘函数&#xff0c;计…

java之多线程篇

一、基本概念 1.什么是线程&#xff1f; 线程就是&#xff0c;操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。简单理解就是&#xff1a;应用软件中互相独立&#xff0c;可以同时运行的功能 2.什么是多线程&#xff1f; 有了多线…

无人机之飞行控制系统篇

一、飞行控制系统组成 包括惯性测量单位、GPS接收机、气压高度计、空速计等传感器&#xff0c;以及飞控计算机、伺服作动器等设备。 二、飞行控制原理 通过传感器实时感知无人机的飞行状态&#xff0c;将数据传输给飞控计算机进行处理&#xff0c;计算机再根据预设的飞行计划和…

13-按键的元件模型创建

1.画线的时候&#xff0c;栅格切为10mil 2.放置管脚的时候&#xff0c;栅格切为100mil

开发框架DevExpress XAF v24.2产品路线图预览——增强跨平台性

DevExpress XAF是一款强大的现代应用程序框架&#xff0c;允许同时开发ASP.NET和WinForms。XAF采用模块化设计&#xff0c;开发人员可以选择内建模块&#xff0c;也可以自行创建&#xff0c;从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。 DevExpress XAF是一…

LLaMA- Adapter V2: Parameter-Efficient Visual Instruction Model

发表时间&#xff1a;28 Apr 2023 论文链接&#xff1a;https://arxiv.org/pdf/2304.15010 作者单位&#xff1a; Shanghai Artificial Intelligence Laboratory Motivation&#xff1a;如何有效地将大型语言模型 (LLM) 转换为指令追随者最近是一个流行的研究方向&#xff0…

Linux基于centOS7【内存与OS的随谈】,进程初学【PCB】【fork】【进程排队】

冯诺依曼体系结构——存储器 存储器主要指的是内存&#xff0c;它有个特点就是掉电易失 磁盘等其它输入和输出设备 为什么要在计算机体系结构中要存在内存 我们知道&#xff0c;CPU的处理速度很快很快&#xff0c;但输入设备&#xff0c;以及输出设备&#xff0c;是相对很慢的…

sql注入靶场搭建

1.安装小皮面板&#xff08;PhpStudy&#xff09; 1.从官网下载&#xff1a;http://www.xp.cn 2、Sqli-labs环境安装 准备好sqli-labs-php7-master文件 3.安装之前确保本地没有下载mysql服务器 如果电脑下载了MySQL可以把MySQL的服务停掉 此电脑>右键>管理>服务…

QModbus例程分析

由于有一个Modebus上位机的需要&#xff0c;分析一下QModbus Slave的源代码&#xff0c;方便后面的开发。 什么是Modbus Modbus是一种常用的串行通信协议&#xff0c;被广泛应用于工业自动化领域。它最初由Modicon&#xff08;目前属于施耐德电气公司&#xff09;于1979年开发…

C++:vector容器

概览 std::vector是C标准模板库(STL)中的一种动态数组容器。它提供了一种类似于数组的数据结构&#xff0c;但是具有动态大小和更安全的内存管理。 定义和基本特性 std::vector是C标准库中的一 个序列容器&#xff0c;它代表了能够动态改变大小的数组。与普通数组一样&#x…