网站首页 > 技术文章 正文
如何训练你的神经网络
这篇博客文章将带您了解PyTorch中不同类型的CNN操作。在此博客文章中,我们将使用torch.nn实现一维和二维卷积。
什么是CNN?
卷积神经网络是一种神经网络,主要用于图像处理应用程序。 CNN的其他应用是在顺序数据中,例如音频,时间序列和NLP。 卷积是CNN的主要构建块之一。 术语卷积是指两个函数的数学组合以产生第三个函数。 它合并了两组信息。
在这里我们不会讨论太多的理论。 在线上有很多很棒的资料可供选择。
CNN操作的类型
CNN主要用于围绕图像,音频,视频,文本和时间序列建模的应用程序。 有3种类型的卷积运算。
- 1D卷积-主要用于输入是连续的(例如文本或音频)的地方。
- 2D卷积-主要用于输入为图像的情况。
- 3D卷积-主要用于3D医学成像或检测视频中的事件。 这超出了本博客文章的范围。 我们将只关注前两个。
一维输入的一维卷积
过滤器沿单个尺寸滑动以产生输出。 下图来自该Stackoverflow答案。
2D输入的1D卷积
2D输入的2D卷积
请查看此Stackoverflow答案,以获取有关不同类型的CNN操作的更多信息。
几个关键术语
解释了2D卷积和2D输入的术语。 图片,因为我找不到1D卷积的相关可视化。
卷积运算
为了计算卷积运算后的输出尺寸,我们可以使用以下公式。
内核/滤波器如下图所示在输入信号上滑动。 您可以看到过滤器(绿色正方形)在我们的输入(蓝色正方形)上滑动,并且卷积的总和进入特征图(红色正方形)。
过滤器/内核
使用滤波器对输入图像执行卷积。 卷积的输出称为特征图。
在CNN术语中,3×3矩阵称为"过滤器"或"内核"或"特征检测器",通过在图像上滑动过滤器并计算点积而形成的矩阵称为"卷积特征"或"激活" 地图"或"功能地图"。 重要的是要注意,滤镜充当原始输入图像的特征检测器。
更多过滤器=更多功能图=更多功能。
过滤器不过是数字矩阵。 以下是不同类型的过滤器-
步幅
步幅指定在每个步骤中移动卷积过滤器多少。
如果我们希望重叠减少,我们可以有更大的步幅。 由于我们跳过了潜在的位置,因此这也使得生成的特征图更小。 下图演示了步幅为2。请注意,特征图变得更小。
填充
在这里,我们保留了来自边界的更多信息,并保留了图像的大小。
我们看到特征图的大小小于输入,因为卷积滤波器需要包含在输入中。 如果要保持相同的尺寸,可以使用填充将输入用零包围。
池化
我们应用池化以减少维数。
- 合并可减小输入的大小并使特征尺寸更小。
- 由于较小的空间大小,因此减少了网络中的参数数量。 这有助于防止过度拟合。
- 合并使网络对于图像中的失真具有鲁棒性,因为我们采用邻域中像素值的合计(最大值,总和,平均值等)。
导入库
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
输入数据
首先,我们定义一些输入张量,我们将在整个博客文章中使用这些张量。
input_1d是一维浮点张量。 input_2d是一个二维浮点张量。 input_2d_img是表示图像的3维浮点张量。
input_1d = torch.tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype = torch.float)
input_2d = torch.tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]], dtype = torch.float)
input_2d_img = torch.tensor([[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]], [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]], [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]], dtype = torch.float)
###################### OUTPUT ######################
Input 1D:
input_1d.shape: torch.Size([10])
input_1d:
tensor([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
====================================================================
Input 2D:
input_2d.shape: torch.Size([2, 5])
input_2d:
tensor([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10.]])
====================================================================
input_2d_img:
input_2d_img.shape: torch.Size([3, 3, 10])
input_2d_img:
tensor([[[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]],
[[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]],
[[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]]])
一维卷积
nn.Conv1d()对输入应用一维卷积。 nn.Conv1d()期望输入为[batch_size,input_channels,signal_length]形状。
您可以在PyTorch官方文档中查看完整的参数列表。 必需的参数是—
- in_channels(python:int)—输入信号中的通道数。 这应该等于输入张量中的通道数。
- out_channels(python:int)—卷积产生的通道数。
- kernel_size(python:int或元组)—卷积内核的大小。
Conv1d-输入1d
输入是一维信号,由10个数字组成。 我们将其转换为大小为[1,1,10]的张量。
input_1d = input_1d.unsqueeze(0).unsqueeze(0)
input_1d.shape
###################### OUTPUT ######################
torch.Size([1, 1, 10])
CNN输出,其中out_channels = 1,kernel_size = 3和stride = 1。
cnn1d_1 = nn.Conv1d(in_channels=1, out_channels=1, kernel_size=3, stride=1)
print("cnn1d_1: \n")
print(cnn1d_1(input_1d).shape, "\n")
print(cnn1d_1(input_1d))
###################### OUTPUT ######################
cnn1d_1:
torch.Size([1, 1, 8])
tensor([[[-1.2353, -1.4051, -1.5749, -1.7447, -1.9145, -2.0843, -2.2541, -2.4239]]], grad_fn=<SqueezeBackward1>)
CNN输出,其中out_channels = 1,kernel_size = 3和stride = 2。
cnn1d_2 = nn.Conv1d(in_channels=1, out_channels=1, kernel_size=3, stride=2)
print("cnn1d_2: \n")
print(cnn1d_2(input_1d).shape, "\n")
print(cnn1d_2(input_1d))
###################### OUTPUT ######################
cnn1d_2:
torch.Size([1, 1, 4])
tensor([[[0.5107, 0.3528, 0.1948, 0.0368]]], grad_fn=<SqueezeBackward1>)
CNN输出,其中out_channels = 1,kernel_size = 2和stride = 1。
cnn1d_3 = nn.Conv1d(in_channels=1, out_channels=1, kernel_size=2, stride=1)
print("cnn1d_3: \n")
print(cnn1d_3(input_1d).shape, "\n")
print(cnn1d_3(input_1d))
###################### OUTPUT ######################
cnn1d_3:
torch.Size([1, 1, 9])
tensor([[[0.0978, 0.2221, 0.3465, 0.4708, 0.5952, 0.7196, 0.8439, 0.9683, 1.0926]]], grad_fn=<SqueezeBackward1>)
CNN输出,其中out_channels = 5,kernel_size = 3,stride = 2。
cnn1d_4 = nn.Conv1d(in_channels=1, out_channels=5, kernel_size=3, stride=1)
print("cnn1d_4: \n")
print(cnn1d_4(input_1d).shape, "\n")
print(cnn1d_4(input_1d))
###################### OUTPUT ######################
cnn1d_4:
torch.Size([1, 5, 8])
tensor([[[-1.8410e+00, -2.8884e+00, -3.9358e+00, -4.9832e+00, -6.0307e+00,-7.0781e+00, -8.1255e+00, -9.1729e+00],
[-4.6073e-02, -3.4436e-02, -2.2799e-02, -1.1162e-02, 4.7439e-04,1.2111e-02, 2.3748e-02, 3.5385e-02],
[-1.5541e+00, -1.8505e+00, -2.1469e+00, -2.4433e+00, -2.7397e+00, -3.0361e+00, -3.3325e+00, -3.6289e+00],
[ 6.6593e-01, 1.2362e+00, 1.8066e+00, 2.3769e+00, 2.9472e+00, 3.5175e+00, 4.0878e+00, 4.6581e+00],
[ 2.0414e-01, 6.0421e-01, 1.0043e+00, 1.4044e+00, 1.8044e+00,2.2045e+00, 2.6046e+00, 3.0046e+00]]],
grad_fn=<SqueezeBackward1>)
Conv1d-输入2d
要将1D卷积应用于2d输入信号,我们可以执行以下操作。 首先,我们定义大小为[1、2、5]的输入张量,其中batch_size = 1,input_channels = 2和signal_length = 5。
input_2d = input_2d.unsqueeze(0)
input_2d.shape
###################### OUTPUT ######################
torch.Size([1, 2, 5])
CNN输出in_channels = 2,out_channels = 1,kernel_size = 3,stride = 1。
cnn1d_5 = nn.Conv1d(in_channels=2, out_channels=1, kernel_size=3, stride=1)
print("cnn1d_5: \n")
print(cnn1d_5(input_2d).shape, "\n")
print(cnn1d_5(input_2d))
###################### OUTPUT ######################
cnn1d_5:
torch.Size([1, 1, 3])
tensor([[[-6.6836, -7.6893, -8.6950]]], grad_fn=<SqueezeBackward1>)
CNN输出in_channels = 2,out_channels = 1,kernel_size = 3,stride = 2。
cnn1d_6 = nn.Conv1d(in_channels=2, out_channels=1, kernel_size=3, stride=2)
print("cnn1d_6: \n")
print(cnn1d_6(input_2d).shape, "\n")
print(cnn1d_6(input_2d))
###################### OUTPUT ######################
cnn1d_6:
torch.Size([1, 1, 2])
tensor([[[-3.4744, -3.7142]]], grad_fn=<SqueezeBackward1>)
CNN输出,其中in_channels = 2,out_channels = 1,kernel_size = 2,stride = 1。
cnn1d_7 = nn.Conv1d(in_channels=2, out_channels=1, kernel_size=2, stride=1)
print("cnn1d_7: \n")
print(cnn1d_7(input_2d).shape, "\n")
print(cnn1d_7(input_2d))
###################### OUTPUT ######################
cnn1d_7:
torch.Size([1, 1, 4])
tensor([[[0.5619, 0.6910, 0.8201, 0.9492]]], grad_fn=<SqueezeBackward1>)
CNN输出,其中in_channels = 2,out_channels = 5,kernel_size = 3,stride = 1。
cnn1d_8 = nn.Conv1d(in_channels=2, out_channels=5, kernel_size=3, stride=1)
print("cnn1d_8: \n")
print(cnn1d_8(input_2d).shape, "\n")
print(cnn1d_8(input_2d))
###################### OUTPUT ######################
cnn1d_8:
torch.Size([1, 5, 3])
tensor([[[ 1.5024, 2.4199, 3.3373],
[ 0.2980, -0.0873, -0.4727],
[ 1.5443, 1.7086, 1.8729],
[ 2.6177, 3.2974, 3.9772],
[-2.5145, -2.2906, -2.0668]]], grad_fn=<SqueezeBackward1>)
2D卷积
nn.Conv2d()在输入上应用2D卷积。 nn.Conv2d()希望输入的形状为[batch_size,input_channels,input_height,input_width]。
您可以在PyTorch官方文档中查看完整的参数列表。 必需的参数是—
- in_channels(python:int)— 2d输入中的通道数,例如 图片。
- out_channels(python:int)—卷积产生的通道数。
- kernel_size(python:int或元组)—卷积内核的大小
Conv2d-输入2d
要将2D卷积应用于2d输入信号(例如图像),我们可以执行以下操作。 首先,我们定义大小为[1、3、3、10]的输入张量,其中batch_size = 1,input_channels = 3,input_height = 3,input_width = 10。
input_2d_img = input_2d_img.unsqueeze(0)
input_2d_img.shape
###################### OUTPUT ######################
torch.Size([1, 3, 3, 10])
CNN输出in_channels = 3,out_channels = 1,kernel_size = 3,stride = 1。
cnn2d_1 = nn.Conv2d(in_channels=3, out_channels=1, kernel_size=3, stride=1)
print("cnn2d_1: \n")
print(cnn2d_1(input_2d_img).shape, "\n")
print(cnn2d_1(input_2d_img))
###################### OUTPUT ######################
cnn2d_1:
torch.Size([1, 1, 1, 8])
tensor([[[[-1.0716, -1.5742, -2.0768, -2.5793, -3.0819, -3.5844, -4.0870,-4.5896]]]], grad_fn=<MkldnnConvolutionBackward>)
CNN输出in_channels = 3,out_channels = 1,kernel_size = 3,stride = 2。
cnn2d_2 = nn.Conv2d(in_channels=3, out_channels=1, kernel_size=3, stride=2)
print("cnn2d_2: \n")
print(cnn2d_2(input_2d_img).shape, "\n")
print(cnn2d_2(input_2d_img))
###################### OUTPUT ######################
cnn2d_2:
torch.Size([1, 1, 1, 4])
tensor([[[[-0.7407, -1.2801, -1.8195, -2.3590]]]],
grad_fn=<MkldnnConvolutionBackward>)
CNN输出,其中in_channels = 3,out_channels = 1,kernel_size = 2,stride = 1。
cnn2d_3 = nn.Conv2d(in_channels=3, out_channels=1, kernel_size=2, stride=1)
print("cnn2d_3: \n")
print(cnn2d_3(input_2d_img).shape, "\n")
print(cnn2d_3(input_2d_img))
###################### OUTPUT ######################
cnn2d_3:
torch.Size([1, 1, 2, 9])
tensor([[[[-0.8046, -1.5066, -2.2086, -2.9107, -3.6127, -4.3147, -5.0167, -5.7188, -6.4208],
[-0.8046, -1.5066, -2.2086, -2.9107, -3.6127, -4.3147, -5.0167,-5.7188, -6.4208]]]], grad_fn=<MkldnnConvolutionBackward>)
CNN输出,其中in_channels = 3,out_channels = 5,kernel_size = 3,stride = 1。
cnn2d_4 = nn.Conv2d(in_channels=3, out_channels=5, kernel_size=3, stride=1)
print("cnn2d_4: \n")
print(cnn2d_4(input_2d_img).shape, "\n")
print(cnn2d_4(input_2d_img))
###################### OUTPUT ######################
cnn2d_4:
torch.Size([1, 5, 1, 8])
tensor([[[[-2.0868e+00, -2.7669e+00, -3.4470e+00, -4.1271e+00, -4.8072e+00, -5.4873e+00, -6.1673e+00, -6.8474e+00]],
[[-4.5052e-01, -5.5917e-01, -6.6783e-01, -7.7648e-01, -8.8514e-01, -9.9380e-01, -1.1025e+00, -1.2111e+00]],
[[ 6.6228e-01, 8.3826e-01, 1.0142e+00, 1.1902e+00, 1.3662e+00,1.5422e+00, 1.7181e+00, 1.8941e+00]],
[[-5.4425e-01, -1.2149e+00, -1.8855e+00, -2.5561e+00, -3.2267e+00, -3.8973e+00, -4.5679e+00, -5.2385e+00]],
[[ 2.0564e-01, 1.6357e-01, 1.2150e-01, 7.9434e-02, 3.7365e-02, -4.7036e-03, -4.6773e-02, -8.8842e-02]]]],
grad_fn=<MkldnnConvolutionBackward>)
感谢您的阅读。 欢迎提出建议和建设性批评。 :) 您可以在LinkedIn上找到我。 您可以在此处查看完整的代码。 在此处查看Github存储库,如果喜欢可以加注星标。
(本文翻译自Akshaj Verma的文章《[Pytorch Basics] How to train your Neural Net — Intro to CNN》,参考:https://towardsdatascience.com/pytorch-basics-how-to-train-your-neural-net-intro-to-cnn-26a14c2ea29)
猜你喜欢
- 2024-10-22 彻底搞懂CNN中的卷积和反卷积 cnn卷积计算公式
- 2024-10-22 Python MTCNN(人脸检测)项目附代码讲解(2)-NMS/IOU工具介绍
- 2024-10-22 谷歌大脑用强化学习为移动设备量身定做最好最快的CNN模型
- 2024-10-22 STFGNN:用于交通流预测的时空融合图神经网络
- 2024-10-22 通过 Python 中的 Keras 示例了解 CNN 基础知识
- 2024-10-22 CNN中一些特殊环节的反向传播(面试要点)
- 2024-10-22 为何Keras中的CNN是有问题的,如何修复它们?
- 2024-10-22 用Keras实现一个标准的CNN! keras实现gan
- 2024-10-22 卷积神经网络CNN完全指南终极版(二)
- 2024-10-22 二项式定理问题(1):通项公式 二项式定理问题
你 发表评论:
欢迎- 11-18软考系统分析师知识点十六:系统实现与测试
- 11-18第16篇 软件工程(四)过程管理与测试管理
- 11-18编程|实例(分书问题)了解数据结构、算法(穷举、递归、回溯)
- 11-18算法-减治法
- 11-18笑疯了!巴基斯坦首金!没有技巧全是蛮力!解说:真远啊!笑死!
- 11-18搜索算法之深度优先、广度优先、约束条件、限界函数及相应算法
- 11-18游戏中的优化指的的是什么?
- 11-18算法-分治法
- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)