深度学习总结(3)

数据批量的概念

通常来说,深度学习中所有数据张量的第一个轴(也就是轴0,因为索引从0开始)都是样本轴[samples axis,有时也叫样本维度(samples dimension)​]​。深度学习模型不会一次性处理整个数据集,而是将数据拆分成小批量。下面是MNIST数据集的一个批量,批量大小为128。

batch = train_images[:128]

对于这种批量张量,第一个轴(轴0)叫作批量轴(batch axis)或批量维度(batch dimension)​。在使用Keras和其他深度学习库时,你会经常遇到“批量轴”这个术语。

现实世界中的数据张量实例

向量数据:形状为(samples, features)的2阶张量,每个样本都是一个数值(​“特征”​)向量。时间序列数据或序列数据:形状为(samples, timesteps, features)的3阶张量,每个样本都是特征向量组成的序列(序列长度为timesteps)​。图像数据:形状为(samples, height, width, channels)的4阶张量,每个样本都是一个二维像素网格,每个像素则由一个“通道”​(channel)向量表示。视频数据:形状为(samples, frames, height, width, channels)的5阶张量,每个样本都是由图像组成的序列(序列长度为frames)​。

向量数据

这是最常见的一类数据。对于这种数据集,每个数据点都被编码为一个向量,因此一个数据批量就被编码为一个2阶张量(由向量组成的数组)​,其中第1个轴是样本轴,第2个轴是特征轴(features axis)​。

时间序列数据或序列数据

当时间(或序列顺序)对数据很重要时,应该将数据存储在带有时间轴的3阶张量中。每个样本可被编码为一个向量序列(2阶张量)​,因此一个数据批量就被编码为一个3阶张量。

图像数据

图像通常具有3个维度:高度、宽度和颜色深度。虽然灰度图像只有一个颜色通道,因此可以保存在2阶张量中,但按照惯例,图像张量都是3阶张量。
图像张量的形状有两种约定:通道在后(channels-last)的约定(这是TensorFlow的标准)和通道在前(channels-first)的约定(使用这种约定的人越来越少)​。

视频数据

视频数据是现实世界中为数不多的需要用到5阶张量的数据类型。视频可以看作帧的序列,每一帧都是一张彩色图像。由于每一帧都可以保存在一个形状为(height, width,color_depth)的3阶张量中,因此一个视频(帧的序列)可以保存在一个形状为(frames, height, width, color_depth)的4阶张量中,由多个视频组成的批量则可以保存在一个形状为(samples, frames, height, width, color_depth)的5阶张量中。

神经网络的“齿轮”​:张量运算

所有计算机程序最终都可以简化为对二进制输入的一些二进制运算(AND、OR、NOR等)​,与此类似,深度神经网络学到的所有变换也都可以简化为对数值数据张量的一些张量运算(tensor operation)或张量函数(tensor function)​,如张量加法、张量乘法等。下面是一个Keras层的实例。

keras.layers.Dense(512, activation="relu")

这个层理解为一个函数,其输入是一个矩阵,返回的是另一个矩阵,即输入张量的新表示。这个函数具体如下(其中W是一个矩阵,b是一个向量,二者都是该层的属性)​。

output = relu(dot(input, W) + b)

这里有3个张量运算。输入张量和张量W之间的点积运算(dot)​。由此得到的矩阵与向量b之间的加法运算(+)​。relu运算。relu(x)就是max(x, 0),relu代表“修正线性单元”​(rectified linear unit)​。

逐元素运算

relu运算和加法都是逐元素(element-wise)运算,即该运算分别应用于张量的每个元素。也就是说,这些运算非常适合大规模并行实现(向量化实现)​。如果你想对逐元素运算编写一个简单的Python实现,那么可以使用for循环。下列代码是对逐元素relu运算的简单实现。

def naive_relu(x):#x是一个2阶NumPy张量assert len(x.shape) == 2#避免覆盖输入张量x = x.copy()for i in range(x.shape[0]):for j in range(x.shape[1]):x[i, j] = max(x[i, j], 0)return x

对于加法,可采用同样的实现方法。

def naive_add(x, y):#x和y是2阶NumPy张量assert len(x.shape) == 2assert x.shape == y.shape#避免覆盖输入张量x = x.copy()for i in range(x.shape[0]):for j in range(x.shape[1]):x[i, j] += y[i, j]return x

利用同样的方法,可以实现逐元素的乘法、减法等。在实践中处理NumPy数组时,这些运算都是优化好的NumPy内置函数。这些函数将大量运算交给基础线性代数程序集(Basic Linear Algebra Subprograms,BLAS)实现。BLAS是低层次(low-level)​、高度并行、高效的张量操作程序,通常用Fortran或C语言来实现。因此,在NumPy中可以直接进行下列逐元素运算,速度非常快

import numpy as np
#逐元素加法
#z = x + y
# 逐元素relu
#z = np.maximum(z, 0.)

我们来看一下两种方法运行时间的差别。

import timex = np.random.random((20, 100))
y = np.random.random((20, 100))
t0 = time.time()
for _ in range(1000):z = x + yz = np.maximum(z, 0.)
print("Took: {0:.2f} s".format(time.time() - t0))

只需要0.00秒。与之相对,前面手动编写的简单实现耗时长达0.77秒。

t0 = time.time()
for _ in range(1000):z = naive_add(x, y)z = naive_relu(z)
print("Took: {0:.2f} s".format(time.time() - t0))

同样,在GPU上运行TensorFlow代码,逐元素运算都是通过完全向量化的CUDA来完成的,可以最大限度地利用高度并行的GPU芯片架构。

广播

naive_add的简单实现仅支持两个形状相同的2阶张量相加,但在Dense层中,我们将一个2阶张量与一个向量相加。如果将两个形状不同的张量相加,会发生什么?在没有歧义且可行的情况下,较小的张量会被广播(broadcast)​,以匹配较大张量的形状。广播包含以下两步。(1)向较小张量添加轴[叫作广播轴(broadcast axis)​]​,使其ndim与较大张量相同。(2)将较小张量沿着新轴重复,使其形状与较大张量相同。我们来看一个具体的例子。假设X的形状是(32, 10),y的形状是(10,)。

import numpy as np
#X是一个形状为(32, 10)的随机矩阵
X = np.random.random((32, 10))  
#y是一个形状为(10,)的随机向量
y = np.random.random((10,))  

首先,我们向y添加第1个轴(空的)​,这样y的形状变为(1, 10)。

#现在y的形状变为(1, 10)
y = np.expand_dims(y, axis=0) 

然后,我们将y沿着这个新轴重复32次,这样得到的张量Y的形状为(32, 10),并且Y[i,:] == y for i in range(0, 32)

#将y沿着轴0重复32次后得到Y,其形状为(32, 10)
Y = np.concatenate([y] * 32, axis=0) 

现在,我们可以将X和Y相加,因为它们的形状相同。在实际的实现过程中并不会创建新的2阶张量,因为那样做非常低效。重复操作完全是虚拟的,它只出现在算法中,而没有出现在内存中。但想象将向量沿着新轴重复10次,是一种很有用的思维模型。下面是一种简单实现。

def naive_add_matrix_and_vector(x, y):#x是一个2阶NumPy张量assert len(x.shape) == 2 # y是一个NumPy向量assert len(y.shape) == 1 assert x.shape[1] == y.shape[0]#避免覆盖输入张量x = x.copy() for i in range(x.shape[0]):for j in range(x.shape[1]):x[i, j] += y[j]return x

如果一个张量的形状是(a, b, …, n, n+1, …, m),另一个张量的形状是(n, n+1, …, m),那么通常可以利用广播对这两个张量做逐元素运算。广播会自动应用于从a到n-1的轴。下面这个例子利用广播对两个形状不同的张量做逐元素maximum运算。

import numpy as np
#x是一个形状为(64, 3, 32, 10)的随机张量
x = np.random.random((64, 3, 32, 10)) 
#y是一个形状为(32, 10)的随机张量
y = np.random.random((32, 10)) 
#输出z的形状为(64, 3, 32, 10),与x相同
z = np.maximum(x, y) 

本文代码汇总:

def naive_add(x, y):#x和y是2阶NumPy张量assert len(x.shape) == 2assert x.shape == y.shape#避免覆盖输入张量x = x.copy()for i in range(x.shape[0]):for j in range(x.shape[1]):x[i, j] += y[i, j]return ximport numpy as np
#逐元素加法
#z = x + y
# 逐元素relu
#z = np.maximum(z, 0.)import timex = np.random.random((20, 100))
y = np.random.random((20, 100))
t0 = time.time()
for _ in range(1000):z = x + yz = np.maximum(z, 0.)
print("Took: {0:.2f} s".format(time.time() - t0))t0 = time.time()
for _ in range(1000):z = naive_add(x, y)z = naive_relu(z)
print("Took: {0:.2f} s".format(time.time() - t0))import numpy as np
#X是一个形状为(32, 10)的随机矩阵
X = np.random.random((32, 10))
#y是一个形状为(10,)的随机向量
y = np.random.random((10,))#现在y的形状变为(1, 10)
y = np.expand_dims(y, axis=0)#将y沿着轴0重复32次后得到Y,其形状为(32, 10)
Y = np.concatenate([y] * 32, axis=0)def naive_add_matrix_and_vector(x, y):#x是一个2阶NumPy张量assert len(x.shape) == 2# y是一个NumPy向量assert len(y.shape) == 1assert x.shape[1] == y.shape[0]#避免覆盖输入张量x = x.copy()for i in range(x.shape[0]):for j in range(x.shape[1]):x[i, j] += y[j]return ximport numpy as np
#x是一个形状为(64, 3, 32, 10)的随机张量
x = np.random.random((64, 3, 32, 10))
#y是一个形状为(32, 10)的随机张量
y = np.random.random((32, 10))
#输出z的形状为(64, 3, 32, 10),与x相同
z = np.maximum(x, y)

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

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

相关文章

微软庆祝它成立整整50周年

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

【操作系统(Linux)】——通过案例学习父子进程的线程异步性

本篇旨在通过几个案例来学习父子进程的线程异步性 一、父进程与子进程 我们将要做的&#xff1a; 创建父子进程&#xff0c;观察父子进程执行的顺序&#xff0c;了解进程执行的异步行为 源代码&#xff1a; #include <stdio.h> #include <sys/types.h> #include…

系统性能核心指标:QPS、TPS、RT、并发量详解

系统性能核心指标&#xff1a;QPS、TPS、RT、并发量详解 1. 引言 在分布式系统、高并发架构设计中&#xff0c;QPS、TPS、RT、并发量 等指标是衡量系统性能的关键。本文深入解析这些术语的定义、计算方法、关联性及优化策略&#xff0c;帮助开发者更好地进行系统性能评估与调…

PortswiggerLab:Exploiting a mass assignment vulnerability

实验目标 To solve the lab, find and exploit a mass assignment vulnerability to buy a Lightweight l33t Leather Jacket. You can log in to your own account using the following credentials: wiener:peter. 官方WP In Burps browser, log in to the application using…

卡尔曼滤波器的工作原理

原文: https://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/ 1 概述 你可以对某个动态系统有不确定信息的任何地方使用卡尔曼滤波器&#xff0c;并且对系统下一步的状态做出有根据的猜测。即使出现混乱的现实状态&#xff0c;卡尔曼滤波器都会给出一个合理的结果。…

PDFtk

如果下载的pdf文件有秘钥的话&#xff0c;使用下面linux命令去掉秘钥&#xff1a; pdftk 纳税记录.pdf input_pw 261021 output 纳税记录_output.pdf将多个单页pdf合并为一个pdf的linux命令: pdftk 自然人电子税务局1.pdf 自然人电子税务局2.pdf 自然人电子税务局3.pdf 自然人…

Openlayers:海量图形渲染之WebGL渲染

最近由于在工作中涉及到了海量图形渲染的问题&#xff0c;因此我开始研究相关的解决方案。我在网络上寻找相关的解决方案时发现许多的文章都提到利用Openlayers中的WebGLPointsLayer类&#xff0c;可以实现渲染海量的点&#xff0c;之后我又了解到利用WebGLVectorLayer类可以渲…

替换jeecg图标

替换jeecg图标 ant-design-vue-jeecg/src/components/tools/Logo.vue <!-- <img v-else src"~/assets/logo.svg" alt"logo">-->

Codeforces Round 970 (Div. 3)题解

题目地址 https://codeforces.com/contest/2008 锐评 本次D3的前四题还是比较简单的&#xff0c;没啥难度区分&#xff0c;基本上差不多&#xff0c;属于手速题。E的码量比F大一些&#xff0c;实现略显复杂一些。G的数学思维较明显&#xff0c;如果很久没有训练这个知识点&a…

操作系统:线程间同步之事件集

事件集是线程间同步的机制之一&#xff0c;一个事件集可以包含多个事件&#xff0c;利用事件集可以完成一对多、多对多的线程间同步。 目录 一、事件集举例说明 二、事件集工作机制 三、RT-Thread为实例说明 四、事件集的应用场合 一、事件集举例说明 以坐公交车为例&…

基于springboot钻孔数据管理系统的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本钻孔数据管理系统采用B/S架构&#xff0c;数据库是MySQL&#xff0c;网站的搭建与开发采用了先进的Java语言、Hadoop、数据可视化技术进行编写&#xff0c;使用了Spring Boot框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。用户主要功能包括&…

全双工分轨语音数据集:让AI实现无缝对话

清晨&#xff0c;智能音箱根据指令-播放音乐&#xff1b;驾驶途中&#xff0c;车载助手同步处理导航与来电&#xff1b;智能会议工具无缝切换多语种对话……语音交互技术正快速融入生活。然而&#xff0c;用户对于对话体验追求更自然、更流畅&#xff0c;实时理解&#xff0c;动…

Python 网络请求利器:requests 包详解与实战

诸神缄默不语-个人技术博文与视频目录 文章目录 一、前言二、安装方式三、基本使用1. 发起 GET 请求2. 发起 POST 请求 四、requests请求调用常用参数1. URL2. 数据data3. 请求头 headers4. 参数 params5. 超时时间 timeout6. 文件上传 file&#xff1a;上传纯文本文件流7. jso…

linux入门四:Linux 编译器

一、C 语言编译器 GCC&#xff1a;开启编程之旅 1.1 GCC 安装&#xff1a;一站式工具链 GCC&#xff08;GNU Compiler Collection&#xff09;是 Linux 下最常用的 C/C 编译器&#xff0c;支持多种编程语言。安装命令&#xff08;适用于 Debian/Ubuntu 系统&#xff09;&…

建筑兔零基础自学记录69|爬虫Requests-2

Requests库初步尝试 #导入requests库 import requests #requests.get读取百度网页 rrequests.get(http://www.baidu.com) #输出读取网页状态 print(r.status_code) #输出网页源代码 print(r.text) HTTP 状态码是三位数字&#xff0c;用于表示 HTTP 请求的结果。常见的状态码有…

Web测试流程及注意点

在Web工程过程中&#xff0c;基于Web系统的测试、确认和验收是一项重要而富有挑战性的工作。基于Web的系统测试与传统的软件测试不同&#xff0c;它不但需要检查和验证是否按照设计的要求运行&#xff0c;而且还要测试系统在不同用户的浏览器端的显示是否合适。 重要的是&…

基于MATLAB/simulink的信号调制仿真--AM调制

实验内容&#xff1a; 假设y(t)(20.5*2cos&#xff08;2*pi*1000*t&#xff09;)*5cos&#xff08;2*pi*2*1e4*t&#xff09;调幅系统&#xff0c;请将一个频率为1000HZ的余弦波信号&#xff0c;通过进行AM调制&#xff0c;载波信号频率为20kHZ的余弦波&#xff0c;调制度ma0.…

通信协议详解(十):PSI5 —— 汽车安全传感器的“抗干扰狙击手”

一、PSI5是什么&#xff1f; 一句话秒懂 PSI5就像传感器界的“防弹信使”&#xff1a;在汽车安全系统&#xff08;如气囊&#xff09;中&#xff0c;用两根线同时完成供电数据传输&#xff0c;即便车祸时线路受损&#xff0c;仍能确保关键信号准确送达&#xff01; 基础概念…

数据结构与算法-图论-复习1(单源最短路,全源最短路,最小生成树)

1. 单源最短路 单一边权 BFS 原理&#xff1a;由于边权为单一值&#xff0c;可使用广度优先搜索&#xff08;BFS&#xff09;来求解最短路。BFS 会逐层扩展节点&#xff0c;由于边权相同&#xff0c;第一次到达某个节点时的路径长度就是最短路径长度。 用法&#xff1a;适用…

【WRF理论第十七期】单向/双向嵌套机制(含namelist.input详细介绍)

WRF运行的单向/双向嵌套机制 准备工作&#xff1a;WRF运行的基本流程namelist.input的详细设置&time_control 设置&domain 嵌套结构&bdy_control 配置部分 namelist 其他注意事项Registry.EM 运行 ARW 嵌套双向嵌套&#xff08;two-way nesting&#xff09;单向嵌套…