在线时间 1630 小时 最后登录 2024-1-29 注册时间 2017-5-16 听众数 82 收听数 1 能力 120 分 体力 565365 点 威望 12 点 阅读权限 255 积分 174832 相册 1 日志 0 记录 0 帖子 5313 主题 5273 精华 3 分享 0 好友 163
TA的每日心情 开心 2021-8-11 17:59
签到天数: 17 天
[LV.4]偶尔看看III
网络挑战赛参赛者
网络挑战赛参赛者
自我介绍 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
群组 : 2018美赛大象算法课程
群组 : 2018美赛护航培训课程
群组 : 2019年 数学中国站长建
群组 : 2019年数据分析师课程
群组 : 2018年大象老师国赛优
0 G2 o) C4 k3 z& g. ?
Python深度学习之初窥神经网络 # a$ Z7 h p5 C! v! Y p4 [
本文为 第2章 开始之前:神经网络背后的数学 (Chapter 2. Before we begin: the mathematical building blocks of neural networks) 的笔记整合。
8 {/ s" ~$ S' Z; E# z# I! ~, w" ~
* W9 b& t4 Q7 t c5 m5 @' X4 a9 m 本文目录:
" e7 ?" V5 ~/ R5 F1 u7 ~/ Q8 D
' ~2 Q' K1 w; [: ` 文章目录' L. @% O; c" l" `3 u; }& E
+ b+ H/ K" [! L7 {) E7 o+ t4 V
Deep Learning with Python; i& @/ u7 D7 R" Y
初窥神经网络
+ p6 G0 g. j" X6 R8 E( Q. u# H 导入MNIST数据集
1 d; w' U" S" I 网络构建
6 N k) P; m+ l 编译5 G2 ^9 z6 W- `8 y" M1 d0 Y% S
预处理
9 N6 V+ m6 M/ k, F2 p5 ~% B 图形处理
6 P5 t7 C# u$ f C 标签处理
/ A0 p% L1 t# V 训练网络
8 m& r3 c3 L% }- z, H: K 神经网络的数据表示" }- x( M1 F/ `9 {
认识张量5 [/ L: S% A# ?. }* k
标量 (0D Tensors)
4 e; Z' n, C! N8 T z) n 向量 (1D Tensors)
$ V5 L! o* h" E5 \) j 矩阵 (2D Tensors), A& E& n* s) @2 T5 p4 c( f* w1 `
高阶张量/ M k; v( G) r. H
张量的三要素
$ p# w( s* u: _6 e# c q1 [" h1 G9 { i Numpy张量操作7 |$ Y; d% D2 {2 x
张量切片:
& E8 J0 m" z& n) g 数据批量" c8 q' ^+ ?- O6 _' U: b
常见数据张量表示
2 G' V# p" v- T) h/ [5 v 神经网络的“齿轮”: 张量运算
; z0 \! `0 Y5 v( h* w3 ] 逐元素操作(Element-wise): L; f, V, P6 \1 y. O+ H
广播(Broadcasting)
8 U4 N# [: D" I( P: y; A 张量点积(dot)
3 X; t- ^2 q$ ^: |1 B5 O7 u4 T 张量变形(reshaping)
) I, ^# X: d7 K5 _- D/ j) A 神经网络的“引擎”: 基于梯度的优化
" t7 m/ d, j, ] 导数(derivative)
# f7 U' Q5 ]! ^* W/ I 梯度(gradient)
. a0 X5 \% f% x* l( q 随机梯度下降(Stochastic gradient descent)
; |2 {8 G9 `" l3 J3 b1 Y/ E1 g 反向传播算法:链式求导) }5 z ~3 ^4 v3 U$ n
本文由 CDFMLR 原创,收录于个人主页 https://clownote.github.io。
- \& f/ P3 C) p7 L% o' ?/ Q+ j
( F& f3 X" R, R 初窥神经网络
. Q3 E) [9 E7 L/ H8 z
t3 v5 a4 ^6 u V8 N1 P 学编程语言从 “Hello World” 开始,学 Deep learning 从 MINST 开始。
M h& S$ E5 V7 N3 u& @ ' a: l& M) g& I
MNIST 用来训练手写数字识别, 它包含 28x28 的灰度手写图片,以及每张图片对应的标签(0~9的值)。- O" `6 p# b' l6 P5 K4 w: u
2 a% F- Z! G# f7 {) } 导入MNIST数据集
. B/ A# {) J4 k9 B8 O5 t" Y; n9 x ' |6 z$ A' U% s) s" E$ i3 A N
# Loading the MNIST dataset in Keras
, `" v& m% B M. a/ J from tensorflow.keras.datasets import mnist3 `" E- T; ~ u8 I) J) f( Y
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
: ~; Z. Z$ t- @9 A( e2 r; @1 S" s 17 b7 `* F2 z3 n! |
2& N# j% p2 s# x6 X& Z# `6 H% w( b3 C d
3# t# e, K4 Q0 r
看一下训练集:' B& P" K y) h+ R( {0 E: U6 g1 x" w
/ i/ J; q+ J) Z
print(train_images.shape)/ _9 j1 k4 i9 [9 i% \3 j, {8 x
print(train_labels.shape)! v* \1 h( c9 d
train_labels
0 w4 D9 [8 H1 F; K& L 1. k/ F: B5 \ e& Q8 F4 n1 p
2
2 j1 @5 g5 ]' l2 x% b9 g) C0 ~ 3
1 S2 C' G8 X! K; y 输出:: d q$ m5 ^- f B2 |( R
: i% d# g! P* {8 L6 l% p* z. o
(60000, 28, 28)% n f8 h% j4 b+ v
(60000,)- G9 u% L5 J. p; l1 U$ ?
- b8 }* h0 X' s* n7 L& r' x. a1 T array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)! ^, [; [: x, y( b$ X' P
1
$ a: l$ `6 e9 _5 }, C5 v 2
) |4 [6 }8 G: s6 p. \9 D" J 3( x& ~5 [ n; N& o
4
( ~) t M& U6 L1 S1 m 这是测试集:
9 c$ C9 R. D# S9 B* b I& X8 C
6 O# t0 I; g, m, X9 K; f- v$ ^ print(test_images.shape); `" O+ {' D+ }* o' t2 I
print(test_labels.shape)2 p0 z* s0 w$ J) M
test_labels
5 J- s9 J3 b" x8 v 1% ?8 L8 j8 y1 ^ B7 f1 Y* a
2
6 k4 z( ?: E; q; y! w+ ^1 A 3, s2 M! n0 ]. C; p$ O- g8 J
输出:
% L- t6 T1 J) R+ i ) F0 k; h0 B2 v: E1 V# M: N
(10000, 28, 28) L6 e0 }& S( f6 W, @" Q8 v5 q" h
(10000,)
9 S" ?5 v4 ~2 `- @ ' B. @: c6 @7 d( Z V, J
array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)
5 D( A7 r4 Q* [* m' |, _" ]$ P 1
3 R' B1 @( }0 ~# P& a! G, } 29 @ `6 z7 {5 K5 m# @/ d
3( E% j9 A( ~% B& s
44 r" k' X$ m e
网络构建 k6 o9 Q: Q/ A: Q
* n2 y# }9 A; G" |9 C8 J( y& t 我们来构建一个用来学习 MNIST 集的神经网络:3 Y4 h: ?; v0 S' h0 m; P, `3 }% J
6 n5 u2 I, Y" Y5 c0 ~ from tensorflow.keras import models
/ r1 U8 \6 g0 _0 v* c from tensorflow.keras import layers
6 E0 O3 R# r$ l$ S: r+ R8 l & ?4 D' i; K4 i! @! `
network = models.Sequential()
, C# A2 K. R% t: F3 a# | network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28, )))
1 w }+ l' P" E6 R1 q: w0 b network.add(layers.Dense(10, activation='softmax'))
7 |) p5 a) z1 A# m 10 v% r) u) e& K, S
2% @) m8 r& |) d# @1 T, w
3
+ K8 @1 l; ? }, r* g O 4
/ F$ N1 E4 h& B4 |9 p% e& n 53 W: q8 ?: Q: e2 e, ~4 l9 O1 N
6
! T- J: a' J ~" r. _0 | 神经网络是一个个「层」组成的。" i/ q) J- u, x. s# W; G
一个「层」就像是一个“蒸馏过滤器”,它会“过滤”处理输入的数据,从里面“精炼”出需要的信息,然后传到下一层。
, h" T: ]$ R7 @! t4 Z5 | # P8 I4 s; G/ F$ V0 z/ e
这样一系列的「层」组合起来,像流水线一样对数据进行处理。" P0 f/ g1 V/ t% o8 T( z7 p I
层层扬弃,让被处理的数据,或者说“数据的表示”对我们最终希望的结果越来越“有用”。
9 S4 C$ s+ R# @+ k
1 g5 S" q5 `8 r1 {0 @ 我们刚才这段代码构建的网络包含两个「Dense 层」,这么叫是因为它们是密集连接(densely connected)或者说是 全连接 的。
5 q" y4 Q1 Y8 `- }* o
9 N- U" O7 l" y. J! B- I' _ 数据到了最后一层(第二层),是一个 10路 的 softmax 层。
9 ^" L) ~2 T N4 h8 M# v 这个层输出的是一个数组,包含 10 个概率值(它们的和为1),这个输出「表示」的信息就对我们预测图片对应的数字相当有用了。7 |, K0 y7 U) M; ^6 f A' P5 y2 f
事实上这输出中的每一个概率值就分别代表输入图片属于10个数字(0~9)中的一个的概率!
5 v& V8 c4 }# g* ]7 T# l
& Q, l" S5 |1 X3 V% S; H 编译
1 Q3 W4 ^2 N+ r1 ]+ G
9 J. Z6 [. [/ \+ y& J/ R# N+ r6 ? 接下来,我们要 编译 这个网络,这个步骤需要给3个参数:' i0 D/ @% z% D) J$ l
0 i" s. i+ d: Z, x- X$ g* n( ?1 ^
损失函数:评价你这网络表现的好不好的函数7 ?- F8 v' Q/ F: e. P
优化器:怎么更新(优化)你这个网络
! o" d1 {6 j0 l1 ?: q 训练和测试过程中需要监控的指标,比如这个例子里,我们只关心一个指标 —— 预测的精度
2 k- E4 ~5 y7 e" o: V network.compile(loss="categorical_crossentropy", | [! F% p P+ i1 f( K+ y7 C8 i
optimizer='rmsprop',; v% \# L% f8 p) F
metrics=['accuracy'])
: L s; D5 U9 y2 ^ F$ w& c! V 1' q; s$ W/ o2 q6 ]8 C
2
/ X' ]9 t% M# w# P" ~ 3
9 R5 m9 f. s' }! K5 E. @7 { 预处理
2 j9 `+ K+ D" C) \
% `# \! l4 x& h8 Q7 `1 z% P# K 图形处理. }' B7 S- w. l1 y
8 @- L8 h* r: N
我们还需要处理一下图形数据,把它变成我们的网络认识的样子。
* J% i+ p- T3 }+ T6 j1 U, ?) h 1 i5 K) p" ^1 ~8 t* L
MNIST 数据集里的图片是 28x28 的,每个值是属于 [0, 255] 的 uint8。
, z4 q3 a5 @( x9 m, j 而我们的神经网络想要的是 28x28 的在 [0, 1] 中的 float32。/ f; K$ N6 w( X8 ^8 l$ I, t2 Q
+ P/ J9 @* B J# O/ @+ q d
train_images = train_images.reshape((60000, 28 * 28))8 G7 V8 Y- v n# H( O% `9 \& j
train_images = train_images.astype('float32') / 255
8 x8 y: k; E1 d% g' R
3 I! k0 X3 T' p/ L5 U; H test_images = test_images.reshape((10000, 28 * 28))- e& N+ k d' m2 Q3 ~7 ~2 i
test_images = test_images.astype('float32') / 255
3 b1 |1 y. W+ z" U3 o6 P 1* V+ V: @! \3 _8 m5 B
28 S6 n' w) q$ m0 y! k
3: H) z& H0 D- X/ c- e2 i
4 U" Q9 `! m- y+ l, l! H, H! r- u
5
4 R- O7 _$ L* n0 ?/ m 标签处理- x( t! d# |! p: y' z Y
. |- x- P3 G, v) v
同样,标签也是需要处理一下的。& v2 e {% \/ Y: }% I. h
- J g: } |, ~2 G, L from tensorflow.keras.utils import to_categorical
% V2 N9 j& m* M
; H; o. |; V8 r: @: ~. W$ K, { train_labels = to_categorical(train_labels)& t$ {1 T1 N( Y- B& z6 g4 {
test_labels = to_categorical(test_labels)
* y( O/ }1 p6 X# x. g6 o" O 1
% [+ K5 y) I* t# G F 2
6 }5 A( G% u) r' e 3/ O4 K0 z% H3 x+ u8 X4 ^
4- A1 v7 F- T( d+ E& X
训练网络8 _, o! @# d" k, |+ H" k; \& Q
( t* P" S0 S8 ^6 g. f4 Q6 h7 S
network.fit(train_images, train_labels, epochs=5, batch_size=128)1 k/ U. ]* H1 g, v" [
1: p2 b. `1 b" S7 B( N, l ?
输出:( K- z! G* @; t Q( j- S m4 T
, O7 Z* K( e. x% A7 s6 M1 X
Train on 60000 samples: `( j2 r- N* | |
Epoch 1/5; o( l7 ~" U7 N, d3 _3 J& N
60000/60000 [==============================] - 3s 49us/sample - loss: 0.2549 - accuracy: 0.9254
+ J* R# M8 v# y! |/ g2 ] Epoch 2/5) v* a- S5 M8 P, s: t- P& ?6 y
60000/60000 [==============================] - 2s 38us/sample - loss: 0.1025 - accuracy: 0.9693
6 K/ M4 d0 u! I. W Epoch 3/5+ R0 p8 Y' H) I
60000/60000 [==============================] - 2s 35us/sample - loss: 0.0676 - accuracy: 0.9800
; H! J. _- q' z Epoch 4/5
2 }7 E$ {5 f! y% Y. u9 _8 R 60000/60000 [==============================] - 2s 37us/sample - loss: 0.0491 - accuracy: 0.9848! e5 B1 l2 P. R5 @, o$ Z
Epoch 5/5
" N% t9 v9 p* ^+ A 60000/60000 [==============================] - 2s 42us/sample - loss: 0.0369 - accuracy: 0.9888/ }0 g6 d0 c9 E ~5 y2 {
U4 c4 K2 d6 y8 [- h- k3 N) _
<tensorflow.python.keras.callbacks.History at 0x13a7892d0>. W4 i; X8 l( O2 x5 w
1
5 s3 G' W E* k% M" e 2
: q8 ]2 S6 j3 P# ?/ c- _ 35 W! q2 n6 v7 Z7 ^5 l, q
4 w8 ?/ l4 g8 b( h' n7 T1 `
5
: e1 n: [0 z$ G3 J9 U% d6 w8 ~( l# h8 D 6
7 F6 E2 E! E2 ~3 U5 n- V 7
5 a5 u/ A" H2 P- L# j 8
) }# S. L5 b- V% {2 T9 K$ ] 9
6 [5 A$ X3 A! t2 V# g9 e 10
7 r; J5 I1 h2 k$ N9 ^ 119 u' k+ B& a( P" J- _3 @6 ^
12
9 c7 p5 [5 n+ U; J 13/ m( I E6 }9 g1 s
可以看到,训练很快,一会儿就对训练集有 98%+ 的精度了。" r0 I# a+ Z& d9 \% S0 p
" S9 L1 s+ a6 G% S9 v! @% I 再用测试集去试试:( f# ]5 E2 _" m0 m) `
: z( r9 I: u, I9 t& J8 r1 p2 a test_loss, test_acc = network.evaluate(test_images, test_labels, verbose=2) # verbose=2 to avoid a looooong progress bar that fills the screen with '='. https://github.com/tensorflow/tensorflow/issues/32286
5 C1 W5 u) I A$ e+ C$ b print('test_acc:', test_acc)7 i3 H7 J9 V6 ], g2 X
1
" f% x, @' w8 K: X% Q2 F7 b 2
" g {( E% U- a 输出:7 D, [. Q* v9 q
/ [# c- V( v+ A8 ` 10000/1 - 0s - loss: 0.0362 - accuracy: 0.97895 E/ i" e) N j( J& s2 R
test_acc: 0.9789
) w9 m- h, Q c 17 Z G% k5 |5 f+ c+ J
2
& r, j3 j, M) a5 k' P 我们训练好的网络在测试集下的表现并没有之前在训练集中那么好,这是「过拟合」的锅。
% v# w9 }: D' v0 n 5 C3 Z& |5 q0 d5 K4 Z, [5 y
神经网络的数据表示" s7 T" x* N- f2 L# x- b Z
9 ]/ E: @8 {& M9 O. q Tensor,张量,任意维的数组(我的意思是编程的那种数组)。矩阵是二维的张量。
3 M* C+ l9 p3 L& K/ r / q7 N3 ]+ |# R) S+ W, ?1 X
我们常把「张量的维度」说成「轴」。: d2 Q( J3 e( w" S6 n# Q {! H" v
) U: c" x& \6 H) P9 G- |; p
认识张量
0 ]0 n; \- l1 D0 S* E ; ^/ r, O+ X0 l2 N3 |+ V2 c
标量 (0D Tensors)
+ U _& j5 e* ?7 _: G 9 {. m' [- M. P2 i |
Scalars,标量是 0 维的张量(0个轴),包含一个数。
k; Y) T" `0 G9 f1 y
1 j9 Z6 i7 f, g3 \$ X: x- M+ h 标量在 numpy 中可以用 float32 或 float64 表示。
) X/ @. y8 `3 ~" e4 W f. V# m " P+ m( f7 W. e3 ^
import numpy as np0 H7 ~! |* S! N9 d* r: N5 u* {4 E# \
7 Y, D" I. s1 B" r$ {! i
x = np.array(12)5 g9 M6 Y. b' C9 w; R
x/ A3 W* D, w2 W# m( Q) H) b$ z
1. ~; q" _% j1 K3 k
23 X' _4 Q7 ^4 H' L
30 @5 e2 b; T% \8 R# u- S' F8 p, E/ E+ Z
4
+ p4 H# o+ _& g* k& \ 输出:
6 E: k8 I' j1 b5 D" E6 T# A% N9 b ( K9 P; [& [+ h/ J3 k; a* f
array(12)
- J% g( P( o. i# v 1
( b+ H6 Y) r% ?5 j! {/ F5 x x.ndim # 轴数(维数)+ k/ U3 S+ q2 T. S- B4 P
1! H2 _ F Z0 _/ `# v
输出:
- _% L& k/ k' M 2 f4 p, ? a1 R! \2 P
1: W2 J% q/ ?' I P; j5 _ @
12 g3 R/ n+ y3 N4 R+ ~
向量 (1D Tensors) H! N8 J% @1 a0 g
5 V2 R H( \: j/ `( |+ J
Vectors,向量是 1 维张量(有1个轴),包含一列标量(就是搞个array装标量)。
* f7 k/ K; \- @, _2 v' Q - Y. Q, @% \! L3 T7 E8 H" N
x = np.array([1, 2, 3, 4, 5])* e& X& k; |, a6 T- [! ]/ L. @: |" b0 v
x4 \# T" O0 y/ Y: Z1 n5 a$ [5 Y
1! C4 g# P8 y' e/ e. }& ^- {
2
; C8 v1 V1 y2 M4 s9 U: Q 输出:6 r7 C* L+ C1 G, C$ K3 Q
7 D/ I! L6 H$ Z+ s' P- B
array([1, 2, 3, 4, 5]); W7 h; B9 R9 \0 W8 g
1& D9 v6 u% a; d+ W) J F- t
x.ndim
- c2 o6 d4 V2 ^5 Y4 k$ M 1- Q b# n. d6 I) L+ f! c
输出:
: C7 o7 f4 k9 y4 o! o5 P8 ~/ R
* Q3 j7 Q2 X M/ P: P; ? 1
) B T" v" a) l5 o 1
' F4 D8 I. U9 O 我们把这样有5个元素的向量叫做“5维向量”。
o1 X, {3 U9 S* E7 ^) { 但注意5D向量可不是5D张量!( d4 q ~# @ }( g
# Y, x9 c, P/ y1 f 5D向量:只有1个轴,在这个轴上有5个维度。- [* d+ L5 U' J3 A) s7 z
5D张量:有5个轴,在每个轴上可以有任意维度。
# t {+ A4 s) d 这个就很迷,这“维度”有的时候是指轴数,有的时候是指轴上的元素个数。- A8 T" y V' e6 v+ F
+ L X9 K/ I5 C. N3 N 所以,我们最好换种说法,用「阶」来表示轴数,说 5阶张量。
7 i- ?5 b$ `8 T( k9 I, C 2 w2 I. B2 g# \. V: i& P8 F
矩阵 (2D Tensors): x, z k0 D# b4 X5 W0 A% V1 ]
4 U8 |( t) E% j: [1 I Matrices,矩阵是 2 阶张量(2个轴,就是我们说的「行」和「列」),包含一列向量(就是搞个array装向量)。# c! ]$ E# v( Z, G" }( T
. H" _, A6 M- P, \7 u+ v6 E: y x = np.array([[5, 78, 2, 34, 0],
. Q( C4 U6 b3 p [6, 79, 3, 35, 1],$ _1 A& f! I6 P* O' s7 d
[7, 80, 4, 36, 2]])5 a0 V. R" g3 D6 z/ D9 `
x
- X/ Z6 b& }6 z7 E 1# ?3 } x+ R1 A+ V3 [' L
2, y5 v' J, Q3 z: T6 m. j
3
2 U1 v( g# j. O2 [, d, Z; e+ E 4
3 Y) k) }8 A" n: D& c 输出:
) h e, K, i2 u' D" F- p9 o 2 w h0 `0 `. U; Z5 ~+ M. ]
array([[ 5, 78, 2, 34, 0],3 o2 A+ Z7 S) l: v/ r9 n
[ 6, 79, 3, 35, 1],7 l( `3 U* H4 f1 ~: y
[ 7, 80, 4, 36, 2]])
9 v' ], y8 T+ r- ~% D 1
8 l0 n! H, W& u8 _2 w9 h 2
7 d. P+ @4 E6 {3 J) L 3% N$ T) V5 n0 |. f
x.ndim
+ Z2 ]5 c$ z% l! z* d 1, R3 G# i$ j4 R% c T
输出:
5 q9 ?7 Z4 s! z: q! k $ `6 M7 K* h1 e, t- Z9 i0 A
29 N* c2 x b# v! a' |
1+ T9 d; R/ n `$ S$ z- Z0 `6 @
高阶张量
: G% m' ]9 }& v4 T; m2 Q 8 T/ G+ q$ q: t+ b+ b/ @; E0 P) `
你搞个装矩阵的 array 就得到了3阶张量。0 H, f* T) V4 y5 m* f
! Q Z1 `; W* k4 x! i& u
再搞个装3阶张量的 array 就得到了4阶张量,依次类推,就有高阶张量了。
. ?1 O, Q. u* Q' Q. O; Q* L 2 y7 u8 h8 X u% c T
x = np.array([[[5, 78, 2, 34, 0],5 w( B8 H+ q# x
[6, 79, 3, 35, 1],7 {2 [- F6 [# k. X1 O( u! x& U; a
[7, 80, 4, 36, 2]],( B9 O! J6 D+ w7 ?; W
[[5, 78, 2, 34, 0],
8 ~4 \' U& y6 T [6, 79, 3, 35, 1],
9 z2 ~/ U) j1 M# e2 f: f [7, 80, 4, 36, 2]],# o: P" D, J `: l& e! m
[[5, 78, 2, 34, 0],7 U% [ W* v: y8 U2 H% B
[6, 79, 3, 35, 1],
( ]8 {- N1 A6 Q, } [7, 80, 4, 36, 2]]])7 k+ I: R3 k9 t$ c
x.ndim
1 s$ h# q; V( }1 o) [' Y 1# ?$ q; G( Q y; _( ^4 _4 Y" v$ S
2
& g1 n1 \* u5 u' [/ {6 j( |0 T 3/ I9 p' C1 T) P$ J- c6 d1 f+ t
4
+ j- ]2 e1 ?1 \# O2 X 55 G' ]5 f+ L Z/ p$ n" A3 ]
6: O4 B; ~, s h4 @$ h/ ?
79 x K, N( A' }" I/ I. }6 ?
8! i: m) C b& d: \ Z
95 A8 @: N# h- ?9 b3 X+ T; f
10
+ F$ Z1 n- r! u, r+ y- E, _( ` 输出:
% ? s7 g! o' D7 Q5 c; Y8 `5 ?
) R% z7 W; D" {. G# w! D 3+ t o# E2 N$ t8 t' W6 R
1
0 Y3 O( U* a* }8 |: Z( K 深度学习里,我们一般就用0~4阶的张量。* ~0 y) i" p+ V/ ?7 p
6 ~* e3 I& N. f2 y7 E: V* _
张量的三要素
7 r5 r6 r9 y4 C5 g2 g) }9 C& D! n. W
* ^- O# b, ^, f% k 阶数(轴的个数):3,5,…: H) R( @3 q. H- ^ v# s9 N/ {* m
形状(各轴维数):(2, 1, 3),(6, 5, 5, 3, 6),…
( H5 Y6 m: D7 J5 ^9 j, q4 x3 _! @ 数据类型:float32,uint8,…6 E9 t. L# L/ }' e
我们来看看 MNIST 里的张量数据:
& x3 f# F+ U+ g2 t& b* S4 z
Y4 T9 u4 `+ |2 F& f) E from tensorflow.keras.datasets import mnist; ^1 [3 |1 U* p( n; ~, l1 `
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()1 w, v. W. {. N* E1 m
# }' X& C) x+ c+ W5 n: B: v print(train_images.ndim)( w/ g' E, S/ l# o. B# ~/ ` n
print(train_images.shape)4 L F* r3 H5 w, D5 q7 q' Q0 g
print(train_images.dtype); \" N% q; ], y$ @
10 e5 W$ ^' A+ N
2
9 q, [0 f& e3 ?) g8 u9 L 3
( n+ K r+ J* Y 4
! P& s1 u4 ^' \ 5
6 e2 W8 d5 `9 O/ F. k 6. L7 [) `/ D. [% ]' f$ i8 w2 Q
输出:8 X6 g) f. m3 x1 @6 x+ ^
1 r0 |' [2 u K! b
3
( X8 x4 O6 Q! `# J8 \ (60000, 28, 28)9 V, @& J- Y3 |# d/ W4 x
uint8
- r5 i- {3 ?7 p: U. s# d 1+ ~- q! e/ S! @& x3 L" e
26 J) M3 p& \; y+ h( f
36 s4 |1 z+ Q; S5 S
所以 train_images 是个8位无符号整数的3阶张量。" n& S, `* v. _9 D9 N1 I- C
, b$ b- u' M p4 l- v 打印个里面的图片看看:
! @$ t0 l4 a9 T2 T3 ]- s: Y; ~8 X
. I% g; O8 T. v) c- S v5 ^ digit = train_images[0]
+ D# m3 U( z) V& @ % R `, q/ ~3 y4 _7 [
import matplotlib.pyplot as plt
: X1 ^. [3 O9 e0 D. R! Y , ?5 e5 Y. f7 T3 R
print("image:")
: Z: W5 }/ N; J6 ]! s* x plt.imshow(digit, cmap=plt.cm.binary)4 v# H: o; P- V1 P. j8 a
plt.show()
. l0 y i) M& [- l6 K9 p print("label: ", train_labels[0])
# t. d4 i1 e& _: E 16 A) p3 c( c* Q k9 g
2
/ N( K6 H, r+ `0 v( { 3
* n: p7 ^! p9 K! v4 \$ | 40 ]7 k6 \* b( ]8 O( b
5
4 s7 {$ F9 P8 V) K0 F/ n+ D# \ 6
2 H) ~+ y1 E/ I) y7 J, q 7
% A; ]1 j4 r/ y/ t- R1 s- C- P- T 8' p! M* j2 s& |4 d* ~
输出:% [# z+ d2 W* {3 }/ J4 p& K
& c/ H5 A, R( _* l F f
8 b* U- d- Y. x! }: |- \* L# [
1 K) P: x+ ^7 x7 U label: 5
; _9 p& I; h$ r8 { G* L& f1 t% Z 1 U: k0 x+ S& E! D- B
Numpy张量操作7 a: u; k3 a6 c+ B2 {+ h: l* Y
6 `8 E) Y2 Z/ j) g6 T5 [( q
张量切片:* R- ]; y% z, y5 F
& G* e) i4 Q0 G. i
my_slice = train_images[10:100]
! `1 e4 W+ A; `: Q5 Y print(my_slice.shape)* c0 H6 @& G0 j E+ V- x
1
9 g7 Q# b5 G- |. G; l6 A, `6 F 2
& L% U6 Q! X0 k" w. B4 Z9 M9 O 输出:
- d; O* @, g" Q* X; F
8 S2 }* [1 x7 z: s3 i% T! t (90, 28, 28)
5 ~: E+ j/ d- ^8 i9 j) a 1( Q9 |+ ?* \* P+ w/ X. n* K
等价于:
- z3 s% Y1 v! Z # g" P2 l3 S3 x3 m1 X
my_slice = train_images[10:100, :, :]
: m# K1 a' N: H( C& I9 r) Q print(my_slice.shape)8 |$ k: ~# H( a$ v4 Y
1- \ X( L9 }, i% O
29 s3 m" e2 l3 x; O/ S- Q
输出:7 {9 ?- a. w+ z, N+ P3 u
, A: U4 s( V! q# S& I (90, 28, 28)( j/ f8 d) ~; o& q
1
1 |. _: M' b2 h" o7 ~! K0 h! R 也等价于% w. e# g( l. D: m7 W+ V
1 D) K, ?+ S( A' L- V' f my_slice = train_images[10:100, 0:28, 0:28]! T5 S2 x, [) M) u
print(my_slice.shape)) q+ w) ^( D. E7 a! I/ f& ~& R
1. J2 G7 E/ F& C0 Z9 `, s- H' ]% K
2) ~- h& P7 j1 R$ `
输出:
9 i, V1 M W( ]# T7 Z
. j; w3 e7 w) J3 o( e5 j (90, 28, 28)
. e3 `8 f! _* G, v }( M2 y 1
, V( [! b, H r- h: |. P6 H4 o f Y 选出 右下角 14x14 的:8 f3 J* ~' x3 M; e# ^1 F
: N6 N( T" G! U) ]" W C* A my_slice = train_images[:, 14:, 14:]
' j ~4 d4 I7 ?* J- T plt.imshow(my_slice[0], cmap=plt.cm.binary)4 O- y8 n0 e$ Q; l% Q
plt.show()
5 Q% }2 L8 X0 x4 v# M5 ] 1
$ _ W/ d2 ^ ^/ F+ P5 T 2, Q, a, q# x' Z3 G
3
! [+ a1 [2 u/ f( ~" f/ m* P; s0 e 输出:# V1 \6 c. L& G8 T! Z2 U
0 j: K3 U8 }# h* T
3 A) w" A0 X- o1 h( p! t; I, x # i! |! l7 d* ]7 n* L
选出 中心处 14x14 的:
; k! o1 M! i7 T: D. M# ?% y
, A( p5 [7 s+ k. h- g2 ^" t my_slice = train_images[:, 7:-7, 7:-7]" K V' _/ B5 g5 L+ d
plt.imshow(my_slice[0], cmap=plt.cm.binary)
+ [$ W, \5 l9 t& U plt.show()
, l) x. E2 ?' ^9 {2 a 1
5 l! m+ K7 p2 x X; K2 t* n, }6 y8 m Z 2
) Y2 T- e4 V8 Q+ q 3
* r/ Q4 b# ^9 A4 O 输出:
8 Y4 h% X% n, k" j . g& }8 @- Q8 P' b6 t+ W: I0 c
/ p! n( V' B8 ~# l; \- A- R$ p
8 K) V( X2 ~! z8 `7 [3 @ 数据批量
) v& t9 ~5 r/ a) {( q 9 d( c, a* w) j3 X
深度学习的数据里,一般第一个轴(index=0)叫做「样本轴」(或者说「样本维度」)。
2 |/ k+ n0 k, u' ]- ~, |5 i 9 d- A! X8 L- M& \9 d2 w9 [' Z4 w
深度学习里,我们一般不会一次性处理整个数据集,我们一批一批地处理。
4 R% Q2 u6 L+ {" j; ~ " t" y, w( [3 o
在 MNIST 中,我们的一个批量是 128 个数据:
6 S" P4 e7 o. [( z4 z7 Q / s) Q/ L9 \. i& D+ N( }" v
# 第一批: E; k. m! M1 v; \- \9 `
batch = train_images[:128]
1 L+ L, D+ _- C # 第二批7 o2 v3 m' ~5 Q4 w, }
batch = train_images[128:256], x$ h7 C* M6 I, _/ m
# 第n批
8 J: }% x: p+ y$ }1 r+ a/ W n = 12
, G% U( G% ~) G* V+ |+ b batch = train_images[128 * n : 128 * (n+1)]2 D9 M6 t2 R- A
12 V% i2 i9 g5 i; y7 g
2 D: [1 q& s/ Z+ s
39 n6 Y0 X% A7 p) c, c9 i
4: f9 i2 i- a* @9 ~
5
& c0 W. ?. }4 u4 O. ` 6! _% z' |7 o) A* A1 q/ n
70 U3 }* e# m- s
所以,在使用 batch 的时候,我们也把第一个轴叫做「批量轴」。7 {# K$ ?* D. J" q# z" o
4 g) z4 H6 s" \& M
常见数据张量表示! n7 E3 Y: Z( ? s4 L8 F
- T5 t0 E3 | T/ m* S+ _ 数据% y* I* s+ t( ^) x% y# K: r
zan