第2章-神经网络的数学基础——python深度学习
第2章 神经网络的数学基础
2.1 初识神经网络
关于类和标签的说明

from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# 代码清单 2-1 加载keras中的minst数据集
from keras.datasets import mnist
from keras.utils import to_categorical(train_images, train_labels), (test_images, test_labels) = mnist.load_data()print('train_images.shape:', train_images.shape)
print('len(train_labels)', len(train_labels))print('train_labels', train_labels)print('test_images.shape:', test_images.shape)
print(' len(test_labels):', len(test_labels))
print('test_labels:', test_labels)
运行结果:
train_images.shape: (60000, 28, 28)
len(train_labels) 60000
train_labels [5 0 4 ... 5 6 8]
test_images.shape: (10000, 28, 28)len(test_labels): 10000
test_labels: [7 2 1 ... 4 5 6]
# 代码清单 2-2 网络架构
from keras import models
from keras import layersnetwork = models.Sequential()
# Dense 也就是全连接的神经网络
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))
# 2.3 编译步骤
# 编译的三个参数:损失函数、优化器、监控的指标(精度)
network.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
# 2-4 准备图像数据
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255
# 2-5准备标签
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)network.fit(train_images, train_labels, epochs=5, batch_size=128)test_loss, test_acc = network.evaluate(test_images, test_labels)
print('test_acc:', test_acc)
469/469 [==============================] - 1s 2ms/step - loss: 0.2649 - accuracy: 0.9234
Epoch 2/5
469/469 [==============================] - 1s 2ms/step - loss: 0.1077 - accuracy: 0.9678
Epoch 3/5
469/469 [==============================] - 1s 2ms/step - loss: 0.0712 - accuracy: 0.9790
Epoch 4/5
469/469 [==============================] - 1s 2ms/step - loss: 0.0508 - accuracy: 0.9847
Epoch 5/5
469/469 [==============================] - 1s 2ms/step - loss: 0.0380 - accuracy: 0.9885
313/313 [==============================] - 0s 923us/step - loss: 0.0592 - accuracy: 0.9812
test_acc: 0.9811999797821045
2.2 神经网络的数据表示
前面例子使用的数据存储在多维 Numpy 数组中,也叫张量(tensor)。一般来说,当前所有机器学习系统都使用张量作为基本数据结构。张量对这个领域非常重要,重要到 Google 的TensorFlow 都以它来命名。
张量这一概念的核心在于,它是一个数据容器。它包含的数据几乎总是数值数据,因此它是数字的容器。你可能对矩阵很熟悉,它是二维张量。张量是矩阵向任意维度的推广[注意,张量的维度(dimension)通常叫作轴(axis)]。
2.2.1 标量(0D 张量)
仅包含一个数字的张量叫作标量(scalar,也叫标量张量、零维张量、0D 张量)。在 Numpy中,一个 float32 或 float64 的数字就是一个标量张量(或标量数组)。你可以用 ndim 属性来查看一个 Numpy 张量的轴的个数。标量张量有 0 个轴(ndim == 0)。张量轴的个数也叫作阶(rank)。下面是一个 Numpy 标量。
>>> import numpy as np
>>> x = np.array(12)
>>> x
array(12)
>>> x.ndim
0
2.2.2 向量(1D 张量)
数字组成的数组叫作向量(vector)或一维张量(1D 张量)。一维张量只有一个轴。下面是
一个 Numpy 向量。
>>> x = np.array([12, 3, 6, 14, 7])
>>> x
array([12, 3, 6, 14, 7])
>>> x.ndim
1
这个向量有 5 个元素,所以被称为 5D 向量。
不要把 5D 向量和 5D 张量弄混!
5D 向量只有一个轴,沿着轴有 5 个维度,而 5D 张量有 5 个轴(沿着每个轴可能有任意个维度)。
维度(dimensionality)可以表示沿着某个轴上的元素个数(比如 5D 向量),也可以表示张量中轴的个数(比如 5D 张量),这有时会令人感到混乱。
对于后一种情况,技术上更准确的说法是 5 阶张量(张量的阶数即轴的个数),但 5D 张量这种模糊的写法更常见。
2.2.3 矩阵(2D 张量)
向量组成的数组叫作矩阵(matrix)或二维张量(2D 张量)。
矩阵有 2 个轴(通常叫作行和列)。你可以将矩阵直观地理解为数字组成的矩形网格。
>>> x = np.array([[5, 78, 2, 34, 0],[6, 79, 3, 35, 1],[7, 80, 4, 36, 2]])
>>> x.ndim
2
第一个轴上的元素叫作行(row),第二个轴上的元素叫作列(column)。
在上面的例子中,[5, 78, 2, 34, 0] 是 x 的第一行,[5, 6, 7] 是第一列。
2.2.4 3D 张量与更高维张量
将多个矩阵组合成一个新的数组,可以得到一个 3D 张量,你可以将其直观地理解为数字组成的立方体。下面是一个 Numpy 的 3D 张量。
>>> x = np.array([[[5, 78, 2, 34, 0],[6, 79, 3, 35, 1],[7, 80, 4, 36, 2]],[[5, 78, 2, 34, 0],[6, 79, 3, 35, 1],[7, 80, 4, 36, 2]],[[5, 78, 2, 34, 0],[6, 79, 3, 35, 1],[7, 80, 4, 36, 2]]])
>>> x.ndim
3
将多个 3D 张量组合成一个数组,可以创建一个 4D 张量,以此类推。深度学习处理的一般是 0D 到 4D 的张量,但处理视频数据时可能会遇到 5D 张量。
2.2.5 关键属性
张量是由以下三个关键属性来定义的。
轴的个数(阶)。例如,3D 张量有 3 个轴,矩阵有 2 个轴。这在 Numpy 等 Python 库中也叫张量的 ndim。
形状。这是一个整数元组,表示张量沿每个轴的维度大小(元素个数)。例如,前面矩阵示例的形状为 (3, 5),3D 张量示例的形状为 (3, 3, 5)。向量的形状只包含一个元素,比如 (5,),而标量的形状为空,即 ()。
数据类型(在 Python 库中通常叫作 dtype)。这是张量中所包含数据的类型,例如,张量的类型可以是 float32、uint8、float64 等。
在极少数情况下,你可能会遇到字符(char)张量。注意,Numpy(以及大多数其他库)中不存在字符串张量,因为张量存储在预先分配的连续内存段中,而字符串的长度是可变的,无法用这种方式存储。
为了具体说明,我们回头看一下 MNIST 例子中处理的数据。首先加载 MNIST 数据集。
from keras.datasets import mnist(train_images, train_labels), (test_images, test_labels) = mnist.load_data()print('train_images.ndim:',train_images.ndim)
print('train_images.shape:',train_images.shape)
print('train_images.dtype:',train_images.dtype)
train_images.ndim: 3
train_images.shape: (60000, 28, 28)
train_images.dtype: uint8
所以,这里 train_images 是一个由 8 位整数组成的 3D 张量。更确切地说,它是 60 000个矩阵组成的数组,每个矩阵由 28×28 个整数组成。每个这样的矩阵都是一张灰度图像,元素取值范围为 0~255。
#2-8 显示第 4 个数字
digit = train_images[4]
import matplotlib.pyplot as plt
plt.imshow(digit, cmap=plt.cm.binary)
plt.show()
train_images[4]就是train数据库中的第5张图片(从0开始计数)
2.2.6 在 Numpy 中操作张量
my_slice = train_images[10:100]
print('my_slice.shape',my_slice.shape)
运行结果:
my_slice.shape (90, 28, 28)
my_slice = train_images[10:100, :, :]
print('my_slice.shape2:',my_slice.shape)my_slice = train_images[10:100, 0:28, 0:28]
print('my_slice.shape3:',my_slice.shape)
my_slice.shape2: (90, 28, 28)
my_slice.shape3: (90, 28, 28)
my_slice = train_images[:, 14:, 14:]
print('my_slice.shape4:',my_slice.shape)my_slice = train_images[:, 7:-7, 7:-7]
print('my_slice.shape5:',my_slice.shape)
my_slice.shape4: (60000, 14, 14)
my_slice.shape5: (60000, 14, 14)
2.2.7 数据批量的概念
2.2.8 现实世界中的数据张量
2.2.9 向量数据
2.2.10 时间序列数据或序列数据

2.2.11 图像数据

2.2.12 视频数据
2.3 神经网络的“齿轮”:张量运算
与此类似,深度神经网络学到的所有变换也都可以简化为数值数据张量上的一些张量运算(tensor
2.3.1 逐元素运算
def naive_relu(x):# x 是一个 Numpy 的 2D 张量assert len(x.shape) == 2# 避免覆盖输入张量x = x.copy()# x 是一个 Numpy 的 2D 张量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):assert len(x.shape) == 2assert x.shape == y.shapex = 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 内置函数,这些函数将大量
import numpy as np
z = x + y
z = np.maximum(z, 0.)
2.3.2 广播
def naive_add_matrix_and_vector(x, y):# x 是一个 Numpy 的 2D 张量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 x
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)
2.3.3 张量点积
import numpy as np
z = np.dot(x, y)
def naive_vector_dot(x, y):# x 和 y 都是 Numpy 向量assert len(x.shape) == 1assert len(y.shape) == 1assert x.shape[0] == y.shape[0]z = 0.for i in range(x.shape[0]):z += x[i] * y[i]return z
def naive_matrix_vector_dot(x, y):# x 是一个 Numpy 矩阵assert len(x.shape) == 2# y 是一个 Numpy 向量assert len(y.shape) == 1# x 的第 1 维和 y 的第 0 维大小必须相同assert x.shape[1] == y.shape[0]# 这个运算返回一个全是 0 的向量,# 其形状与 x.shape[0] 相同z = np.zeros(x.shape[0])for i in range(x.shape[0]):for j in range(x.shape[1]):z[i] += x[i, j] * y[j]return z
def naive_matrix_vector_dot(x, y):z = np.zeros(x.shape[0])for i in range(x.shape[0]):z[i] = naive_vector_dot(x[i, :], y)return z
注意,如果两个张量中有一个的 ndim 大于 1,那么 dot 运算就不再是对称的,也就是说,dot(x, y) 不等于 dot(y, x)。
def naive_matrix_dot(x, y):# x 和 y 都 是Numpy矩阵,二维张量assert len(x.shape) == 2assert len(y.shape) == 2# x 的第 1 维和 y 的第 0 维大小必须相同assert x.shape[1] == y.shape[0]# 这个运算返回特定形状的零矩阵z = np.zeros((x.shape[0], y.shape[1]))# 遍历 x 的所有行……for i in range(x.shape[0]):# 然后遍历 y 的所有列for j in range(y.shape[1]):row_x = x[i, :]column_y = y[:, j]z[i, j] = naive_vector_dot(row_x, column_y)return z

2.3.4 张量变形
train_images = train_images.reshape((60000, 28 * 28))
import numpy as npx = np.array([[0., 1.],[2., 3.],[4., 5.]])
print('x=', x)
print(x.shape)x = x.reshape((6, 1))
print('x=', x)x = x.reshape((2, 3))
print('x=', x)
x= [[0. 1.][2. 3.][4. 5.]]
(3, 2)
x= [[0.][1.][2.][3.][4.][5.]]
x= [[0. 1. 2.][3. 4. 5.]]
x = np.zeros((3, 4))
x = np.transpose(x)
print(x.shape)
(4, 3)
2.3.5 张量运算的几何解释


2.3.6 深度学习的几何解释

2.4 神经网络的“引擎”:基于梯度的优化
output = relu(dot(W, input) + b)
最终得到的网络在训练数据上的损失非常小,即预测值 y_pred 和预期目标 y 之间的距离非常小。网络“学会”将输入映射到正确的目标。乍一看可能像魔法一样,但如果你将其简化为基本步骤,那么会变得非常简单。
2.4.1 什么是导数

2.4.2 张量运算的导数:梯度
2.4.3 随机梯度下降
相反,你可以使用 2.4 节开头总结的四步算法:基于当前在随机数据批量上的损失,一点一点地对参数进行调节。由于处理的是一个可微函数,你可以计算出它的梯度,从而有效地实现第四步。沿着梯度的反方向更新权重,损失每次都会变小一点。



2.4.4 链式求导:反向传播算法
2.5 回顾第一个例子
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255
network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))
network.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
network.fit(train_images, train_labels, epochs=5, batch_size=128)
本章小结
相关文章:

第2章-神经网络的数学基础——python深度学习
第2章 神经网络的数学基础 2.1 初识神经网络 我们来看一个具体的神经网络示例,使用 Python 的 Keras 库 来学习手写数字分类。 我们这里要解决的问题是, 将手写数字的灰度图像(28 像素28 像素)划分到 10 个类别 中(0…...

【Docker】Docker学习⑧ - Docker仓库之分布式Harbor
【Docker】Docker学习⑧ - Docker仓库之分布式Harbor 一、Docker简介二、Docker安装及基础命令介绍三、Docker镜像管理四、Docker镜像与制作五、Docker数据管理六、网络部分七、Docker仓库之单机Dokcer Registry八、 Docker仓库之分布式Harbor1 Harbor功能官方介绍2 安装Harbor…...

一行命令在 wsl-ubuntu 中使用 Docker 启动 Windows
在 wsl-ubuntu 中使用 Docker 启动 Windows 0. 背景1. 验证我的系统是否支持 KVM?2. 使用 Docker 启动 Windows3. 访问 Docker 启动的 Windows4. Docker Hub 地址5. Github 地址 0. 背景 我们可以在 Windows 系统使用安装 wsl-ubuntu,今天玩玩在 wsl-ub…...

Datawhale 组队学习之大模型理论基础 Task7 分布式训练
第8章 分布式训练 8.1 为什么分布式训练越来越流行 近年来,模型规模越来越大,对硬件(算力、内存)的发展提出要求。因为内存墙的存在,单一设持续提高芯片的集成越来越困难,难以跟上模型扩大的需求。 为了…...

05-使用结构体构建相关数据
上一篇: 04-了解所有权 结构体(struct)是一种自定义数据类型,可以将多个相关值打包命名,组成一个有意义的组。如果你熟悉面向对象的语言,那么结构体就像是对象的数据属性。在本章中,我们将对元组…...

【Android】Android中的系统镜像由什么组成?
文章目录 总览Boot Loader 的加锁与解锁Boot 镜像内核RAM diskARM 中的设备树 (Device Tree) /System 和/Data 分区镜像参考 总览 各种Android设备都只能刷专门为相应型号的设备定制的镜像。 厂商会提供一套系统镜像把它作为“出厂默认”的 Android 系统刷在设备上。 一个完…...

仿真机器人-深度学习CV和激光雷达感知(项目2)day7【ROS关键组件】
文章目录 前言Launch 文件了解 XML 文件Launch 文件作用Launch 文件常用标签实例--作业1的 Launch 文件TF Tree介绍发布坐标变换--海龟例程获取坐标变换--海龟自动跟随例程rqt_工作箱前言 💫你好,我是辰chen,本文旨在准备考研复试或就业 💫本文内容是我为复试准备的第二个…...

解锁一些SQL注入的姿势
昨天课堂上布置了要去看一些sql注入的案例,以下是我的心得: 1.新方法 打了sqli的前十关,我发现一般都是联合查询,但是有没有不是联合查询的方法呢…...

Qt 拖拽事件示例
一、引子 拖拽这个动作,在桌面应用程序中是非常实用和具有很友好的交互体验的。我们常见的譬如有,将文件拖拽到某个窗口打开,或者拖拽文件到指定位置上传;在绘图软件中,选中某个模板、并拖拽到画布上,画布上变回绘制该模板的图像… 诸如此类,数不胜数。 那么,在Qt中我…...

Linux:命名管道及其实现原理
文章目录 命名管道指令级命名管道代码级命名管道 本篇要引入的内容是命名管道 命名管道 前面的总结中已经搞定了匿名管道,但是匿名管道有一个很严重的问题,它只允许具有血缘关系的进程进行通信,那如果是两个不相关的进程进行通信࿰…...

实习记录——第五天
今天我的心情不是很美丽,昨天晚上没怎么睡好,因为我一直在想离不离开实验室?该怎么说的事情?但是又觉得这个项目还没有完全结束,冒昧提这个事情是不是不好?最终也没得出一个结论,晚上睡得也不踏…...

Kotlin 教程(环境搭建)
Kotlin IntelliJ IDEA环境搭建 IntelliJ IDEA 免费的社区版下载地址:Download IntelliJ IDEA – The Leading Java and Kotlin IDE 下载安装后,我们就可以使用该工具来创建项目,创建过程需要选择 SDK, Kotlin 与 JDK 1.6 一起使…...

04.领域驱动设计:了解聚合和聚合根,怎样设计聚合-学习总结
目录 1、概述 2、聚合 3、聚合根 4、怎么设计聚合 4.1 聚合的构建过程主要步骤 第 1 步:采用事件风暴。 第 2 步:选出聚合根。 第 3 步:找出与聚合根关联的所有紧密依赖的实体和值对象。 第 4 步:画出对象的引用和依赖模型…...

cmake-find_package链接第三方库
文章目录 基本调用形式和模块模式使用方式 之前我们是使用了绝对路径来链接OpenCV第三方库,但是现在很多库一般会自己写一些cmake文件提供给用户,用户可以直接使用其中的内置变量即可。使用的命令就是find_package。 基本调用形式和模块模式 find_packa…...

obsidian阅读pdf和文献——与zotero连用
参考: 【基于Obsidian的pdf阅读、标注,构建笔记思维导图,实现笔记标签化、碎片化,便于检索和跳转】 工作流:如何在Obsidian中阅读PDF - Eleven的文章 - 知乎 https://zhuanlan.zhihu.com/p/409627700 操作步骤 基于O…...

走方格(动态规划)
解题思路: 找边界,即行为1,列为1。 拆分问题,拆分成一次走一步,只能向右或者向下走。 解题代码: public static void main(String[] args) {int [][]arrnew int[31][31];Scanner scnew Scanner(Sys…...

基于DataKit迁移MySQL到openGauss
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...

API网关-Apinto压缩包方式自动化安装配置教程
文章目录 前言一、Apinto安装教程1. 复制脚本2. 增加执行权限3. 执行脚本4. Apinto命令4.1 启动Apinto4.2 停止Apinto4.3 重启Apinto4.4 查看Apinto版本信息4.5 加入Apinto集群4.6 离开Apinto集群4.7 查看Apinto节点信息 5. 卸载Apinto 二、Apserver(Apinto Dashboard V3)安装教…...

内网穿透natapp使用教程(Linux)
我的使用场景:在家访问学校服务器,由于不在一个局域网,所以需要使用内网穿透,我使用的是natapp。需要在有局域网的时候做好以下步骤。 (natapp官网:https://natapp.cn/) 1. 下载客户端 &#x…...

php函数 二
一 字符串包含 1.1 str_starts_with(string $haystack, string $needle) php8版本中新函数。 检查字符串是否以指定子串开头,区分大小写。返回布尔值。 $haystack待判断的字符串,$needle需要查询的内容。 function test1() {$str "Qwe asd zx…...

IDC机房交换机核心技术与应用指南
IDC机房交换机核心技术与应用指南 在这个快速发展的数字时代,数据中心作为信息技术的心脏,不仅承载着海量数据的处理、存储和传输,更是支撑着全球企业运营和互联网服务的关键基础设施。在众多构成数据中心的组件中,IDC机房交换…...

Compose | UI组件(五) | Button 按钮组件
文章目录 前言Button 是什么?Button的创建Button显示水平方向的UI IconButton是什么?IconButton是创建 FloatingActionButton是什么?FloatingActionButton创建 ExtendedFloatingActionButton是什么? 总结 前言 随着移动端的技术不…...

【leetcode刷刷】235. 二叉搜索树的最近公共祖先 、701.二叉搜索树中的插入操作 、450.删除二叉搜索树中的节点
235. 二叉搜索树的最近公共祖先 class Solution:def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:# 递归if not root: return if root.val p.val: return pif root.val q.val: return qleft Noneright Noneif root.val > p.…...

YoloV8改进策略:BackBone改进|DCNv4最新实践|高效涨点|多种改进教程|完整论文翻译
摘要 涨点效果:在我自己的数据集上,mAP50 由0.986涨到了0.993,mAP50-95由0.737涨到0.77,涨点明显! DCNv4是可变形卷积的第四版,速度和v3相比有了大幅度的提升,但是环境搭建有一定的难度,对新手不太友好。如果在使用过程遇到编译的问题,请严格按照我写的环境配置。 …...

高中数学常识
一、大小关系 |x| > |sinx| 理由: 很明显,在圆内,弧长x>垂线sinx 3x、2x 、 1 2 \frac{1}{2} 21x 理由: log 1 2 _\frac{1}{2} 21x、log 2 _2 2x、 log 3 _3 3x 二、(xy)? 的求法 利用二项式定理 三、平…...

docker之部署青龙面板
青龙面板是一个用于管理和监控 Linux 服务器的工具,具有定时运行脚本任务的功能。在实际情况下也可以用于一些定期自动签到等任务脚本的运行。 本次记录下简单的安装与使用,请提前安装好docker,参考之前的文章。 一、安装部署 1、拉取镜像 # …...

Type-C平板接口协议芯片介绍,实现单C口充放电功能
在现代平板电脑中,Type-C接口已经成为了一个非常常见的接口类型。相比于传统的USB接口,Type-C接口具有更小的体积、更快的传输速度和更方便的插拔体验。但是,在使用Type-C接口的平板电脑上,如何实现单C口充电、放电和USB2.0数据传…...

系统架构演变
1.1系统架构的演变 2008年以后,国内互联网行业飞速发展,我们对软件系统的需求已经不再是过去”能用就行”这种很low的档次了,像抢红包、双十一这样的活动不断逼迫我们去突破软件系统的性能上限,传统的IT企业”能用就行”的开发思…...

Oracle PL/SQL Programming 第2章:Creating and Running PL/SQL Code 读书笔记
总的目录和进度,请参见开始读 Oracle PL/SQL Programming 第6版 暂不考虑系统设计或单元测试之类的任务,所有 PL/SQL 程序员必须熟悉的基本操作任务包括: 浏览数据库创建和编辑 PL/SQL 源代码编译 PL/SQL 源代码,并更正编译器注…...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Swiper容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Swiper容器组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Swiper容器组件 滑块视图容器,提供子组件滑动轮播显示的能力。…...