数学建模社区-数学中国
标题:
Python深度学习之初窥神经网络
[打印本页]
作者:
杨利霞
时间:
2020-5-12 11:55
标题:
Python深度学习之初窥神经网络
' ^) K6 \# z9 i7 v3 x4 B9 l
Python深度学习之初窥神经网络
% [0 W% p2 F" V1 D! k
本文为 第2章 开始之前:神经网络背后的数学 (Chapter 2. Before we begin: the mathematical building blocks of neural networks) 的笔记整合。
' P9 u4 V. Z4 b, A+ l
! m( s, ^/ h/ |! D8 N. p6 B
本文目录:
: k6 n4 d. E7 F& O# q- b
: G- v& Y$ {8 W; x- h0 [/ S/ M
文章目录
" o0 x0 T( e4 g6 \: q
9 D) W# m$ b: u$ p4 m8 L
Deep Learning with Python
8 k- U) O ~4 v
初窥神经网络
3 y+ N: n& }' _5 D+ k
导入MNIST数据集
+ P- F7 n0 ]# e+ Q0 [
网络构建
6 ?3 V, u% n( I# f" ^
编译
2 I" S9 R! {2 x1 P+ N0 N# }
预处理
6 @5 `7 S. v4 [& E
图形处理
W1 q. M6 Y! Z5 m
标签处理
" G. _7 ~- a ?$ @2 X" ~
训练网络
* A. f; [, A7 D! `- P# B' Q
神经网络的数据表示
7 U0 L2 q( S& P/ x: {6 |$ [
认识张量
( o) M9 w* G# J. C4 R) l1 U
标量 (0D Tensors)
: j9 V" P) c; ^& l
向量 (1D Tensors)
/ L; j0 I; E6 T
矩阵 (2D Tensors)
1 Y& C3 t9 m/ M. ?; a
高阶张量
" z5 w+ L/ v5 T$ N
张量的三要素
( ?- ]* t0 H& r* L8 s, M T' g7 m
Numpy张量操作
& S( C9 \" K `+ \. }5 S- ]
张量切片:
! b5 l' H0 Q4 J# c/ Q; J. N
数据批量
( E+ d" F3 F. O/ S% P
常见数据张量表示
( G9 V$ H# b% a9 E1 P
神经网络的“齿轮”: 张量运算
5 }4 Y6 ^- i; n' B, G4 e1 r2 s8 w
逐元素操作(Element-wise)
. b1 a6 p5 B, r! F
广播(Broadcasting)
1 L, T* q# x, E# S6 ^# y
张量点积(dot)
' \$ T2 G$ H: k0 ] Z
张量变形(reshaping)
+ ^* a' J! ]) s$ ]" \
神经网络的“引擎”: 基于梯度的优化
) M* U0 X* @& @3 @' T2 k) u& C5 M
导数(derivative)
$ V( S; n4 g7 ^2 a8 b. p
梯度(gradient)
p+ [0 V" b0 l1 C5 X) q
随机梯度下降(Stochastic gradient descent)
1 b0 ~' m* j) ] ~8 W
反向传播算法:链式求导
9 C0 Y( Q, s' R. @8 U1 F1 J
本文由 CDFMLR 原创,收录于个人主页 https://clownote.github.io。
) A a5 f" `" W! [" }: V7 D, R" w1 F$ ], J
8 Q; b4 w- X/ L0 `# n
初窥神经网络
+ K2 }. z3 b. L0 F
& G6 W l1 T; A. N7 ^- J+ O
学编程语言从 “Hello World” 开始,学 Deep learning 从 MINST 开始。
7 `0 U5 ?. `7 R; Y7 S
- o5 @. Y' t. s( c/ W |2 A) x
MNIST 用来训练手写数字识别, 它包含 28x28 的灰度手写图片,以及每张图片对应的标签(0~9的值)。
/ A7 b* {) D" s2 \+ @! D( d0 b
' y9 U8 d6 x- G5 S, `" }0 R
导入MNIST数据集
% b6 s+ T- W2 K' f, f6 [
z y+ I4 a+ E1 D
# Loading the MNIST dataset in Keras
& _0 E4 H5 |6 j' i: i6 A
from tensorflow.keras.datasets import mnist
; z/ Q' |! C3 c- L& Z
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
2 E, C, S4 A8 F& w& k6 ?
1
$ `5 E M1 n) n4 V
2
6 |* u O8 O) W) o( o
3
% i; J7 U6 J, c
看一下训练集:
( A" l9 D+ G5 F2 J7 P" g6 U6 E
" T4 Q% X3 C3 r- Y% [
print(train_images.shape)
3 _" j. D: i8 Y0 Z8 F# q: Y+ n
print(train_labels.shape)
+ m8 }8 n8 `: m! p3 B( Q5 v
train_labels
4 Y5 S; z; ?5 c
1
; x% X7 u9 r! b
2
. U# j9 b9 ^" J0 x j
3
5 K, x5 }* K" x( O* R% y
输出:
* z) n# J# N. l7 ?+ W
( Z* N( ^1 Y3 }1 z5 c/ y1 B5 Z
(60000, 28, 28)
, G; v0 Z3 c3 V+ Z: D* \
(60000,)
% W/ B- ?1 K) A& D6 G
6 z s0 \9 @% y) {: G% s- V8 R
array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)
( r. a- b7 B* ^- s! `0 ]! @! T
1
5 n8 [/ d# U9 q% W2 Q) k. N
2
4 B; P) N" i9 k! l. ^! p/ X
3
. G3 |. c0 a# x' [
4
' _9 R: E z; S& `
这是测试集:
9 y. U0 I6 A, M+ D. h) g% O
( h, y7 ]. w/ T5 I4 D
print(test_images.shape)
0 H3 }, f4 J* j* w" `. u- J% j6 Y
print(test_labels.shape)
( m) d$ p, l) `
test_labels
* F& Y! \7 G& I6 ~$ u! m
1
0 q6 b o" k# D! c1 Z3 r
2
% `6 C. i3 _1 X8 _
3
! z0 Z1 X, |* R% |1 y P
输出:
# `! m, T) D$ M9 p; \2 B7 T
* P# g, W# N( s. S; c6 u2 ]
(10000, 28, 28)
% ?& s/ F; j" x/ A- g
(10000,)
1 w. X& M( L0 a: C. T& A
# ]- e# ~; @- G3 R9 q# v# g# t
array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)
. t" }; q1 p& X6 q7 N3 [; f- L
1
" \0 m5 C ~1 [/ X! [
2
9 O! Y9 v9 B' ]7 \ v1 K
3
' M7 C7 F6 ~: t$ {7 E! M5 H: w0 ^
4
0 h8 t$ ?9 q- a) U7 J
网络构建
8 E2 e% Q6 k* q: {2 [& N \
% E0 U C4 E" }7 g& c8 v
我们来构建一个用来学习 MNIST 集的神经网络:
) m% X' i6 }9 v0 j9 a3 `
3 Q* H" G/ q3 [2 |2 B& I) [3 l( X
from tensorflow.keras import models
3 s7 X; a: D# R% Y
from tensorflow.keras import layers
3 r1 X1 K9 K. h# O$ u# J2 f
& @6 j& V+ Z$ d; M1 J
network = models.Sequential()
1 Y4 a; ]% S* x- `
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28, )))
0 l3 p0 y# |2 E! m" p
network.add(layers.Dense(10, activation='softmax'))
- ?0 [0 b v8 s8 M- [
1
8 D3 u; ?: C. C8 P3 [6 W
2
3 ~- _8 Q9 a0 k L: S
3
: p; b4 R8 q0 V. h/ C, u
4
Z' F) D/ I* v6 o6 Q
5
2 B) z- l7 a: {% B1 u z0 B
6
6 j$ \: a2 k k# Q; C; c; [
神经网络是一个个「层」组成的。
; w( l3 E6 c9 M, _# Z! e
一个「层」就像是一个“蒸馏过滤器”,它会“过滤”处理输入的数据,从里面“精炼”出需要的信息,然后传到下一层。
# b r/ l5 V) w4 p
* }' y7 n' F$ n) K
这样一系列的「层」组合起来,像流水线一样对数据进行处理。
# G& N) a1 B5 d3 a1 y* Y, ]
层层扬弃,让被处理的数据,或者说“数据的表示”对我们最终希望的结果越来越“有用”。
$ u8 }. S: O1 n) b& e% U# C! ~
2 l) W9 U" O3 A9 }; Y# Q5 E3 j$ j
我们刚才这段代码构建的网络包含两个「Dense 层」,这么叫是因为它们是密集连接(densely connected)或者说是 全连接 的。
0 {7 o& T5 r- n. x. P
8 z W; a }# W/ Y: U$ N& e
数据到了最后一层(第二层),是一个 10路 的 softmax 层。
4 j" c3 T5 c! i+ `2 |$ d% e6 z
这个层输出的是一个数组,包含 10 个概率值(它们的和为1),这个输出「表示」的信息就对我们预测图片对应的数字相当有用了。
; {6 H! e8 M8 q" l
事实上这输出中的每一个概率值就分别代表输入图片属于10个数字(0~9)中的一个的概率!
* L& s7 Y: h& W2 a) U
. u. d" V. c5 @ r% c, w* ?
编译
% h1 s5 F Q3 j
* @; C: e( J+ v! Z- i8 O0 @
接下来,我们要 编译 这个网络,这个步骤需要给3个参数:
1 Q; H7 f& i2 B: O2 o$ u
7 b7 [# r- _# {9 Z$ m1 g% s) j; i
损失函数:评价你这网络表现的好不好的函数
2 ~- C/ c' W: u; a- T1 e: b
优化器:怎么更新(优化)你这个网络
: h1 o- N& r9 b6 [/ c0 f% p H1 j
训练和测试过程中需要监控的指标,比如这个例子里,我们只关心一个指标 —— 预测的精度
- p, `7 U J6 s
network.compile(loss="categorical_crossentropy",
# O) I& X' d. V/ N: ^
optimizer='rmsprop',
- _! k+ y) @% K _8 E: [; o
metrics=['accuracy'])
. l4 S6 l0 s. a& V, i* T" I8 C' A
1
4 e+ C; y, Z* g! p& r6 P
2
2 x; n" A( ~& Y3 Z+ T @
3
, J7 w% b# `1 _5 i- J; { D
预处理
2 g$ @. U+ Y6 Z
8 B9 z1 B+ G' }% U4 @0 p/ }
图形处理
, e/ j- x" ]' P! J$ \" {, F
: a9 f; m: T/ [& r6 I+ c6 N5 f
我们还需要处理一下图形数据,把它变成我们的网络认识的样子。
3 O9 A/ {3 Y! w6 M
. P* H; n1 H* S0 c1 r6 p9 o! g8 c
MNIST 数据集里的图片是 28x28 的,每个值是属于 [0, 255] 的 uint8。
+ a0 I) j B, x* a
而我们的神经网络想要的是 28x28 的在 [0, 1] 中的 float32。
* d5 g% n% }6 J7 w0 v
% }) | k5 u0 F" X7 |) Z
train_images = train_images.reshape((60000, 28 * 28))
7 @, r7 }& b5 H; c, J4 R7 f& |
train_images = train_images.astype('float32') / 255
3 N3 o1 F0 b- J* T. v
+ W5 [, Z, `2 i0 H7 s4 h9 D
test_images = test_images.reshape((10000, 28 * 28))
' \& @ A' A( K
test_images = test_images.astype('float32') / 255
, [, S' _ J8 n. T! l/ G
1
% C4 [- O( v P3 f
2
1 I# {* ?$ L* H. O
3
9 ]8 z" y2 r, ^# m8 d
4
7 T) r3 g! ?0 M4 d
5
6 n0 ~9 S* ? t! P' u
标签处理
7 T# u9 f& n: l6 s- r# x$ ?
4 R1 [5 K2 j0 i H. @2 @0 ]/ a/ i" v
同样,标签也是需要处理一下的。
: q, e8 B3 v4 J1 a$ M9 w
$ F6 f7 s o; a& M: m& K
from tensorflow.keras.utils import to_categorical
: d: [" ^4 X# ^, m: |% k P# M
' M6 c, \" l: F3 e/ m- d; q
train_labels = to_categorical(train_labels)
8 Z3 l- L5 K' [7 _! o
test_labels = to_categorical(test_labels)
6 d& k% U& t$ w
1
4 W! `* Y& _0 _( u
2
2 [) P; p i8 i. v+ y$ _6 j. S
3
( ?1 b G- u% K. S; J& G" @
4
+ [( o4 ]3 L& d2 N( z" `& x
训练网络
3 N+ K, B4 l$ U& `: _" H
) A! Q, Q+ ?/ D# c1 b4 {3 ^; P( \
network.fit(train_images, train_labels, epochs=5, batch_size=128)
: g5 H" D R. ~
1
1 ]- f; y, s1 j
输出:
5 o. ]8 y' d7 g9 q/ v6 k
. K" D g' U5 d: A: R, }
Train on 60000 samples
7 O: J% A" S8 s9 T2 D$ _+ o, G
Epoch 1/5
! B' J& k+ F( L* ]
60000/60000 [==============================] - 3s 49us/sample - loss: 0.2549 - accuracy: 0.9254
( o- m5 }, H2 z: ?
Epoch 2/5
2 Q$ }& K3 H7 h5 l* H
60000/60000 [==============================] - 2s 38us/sample - loss: 0.1025 - accuracy: 0.9693
- n7 c0 x: J# E
Epoch 3/5
7 x0 c! A, ?* U/ K" `
60000/60000 [==============================] - 2s 35us/sample - loss: 0.0676 - accuracy: 0.9800
/ x: M8 U1 O( R$ _, M! f! d. k
Epoch 4/5
8 G# C* `/ I N0 G* m+ t; X- Z
60000/60000 [==============================] - 2s 37us/sample - loss: 0.0491 - accuracy: 0.9848
p" ]3 ~: Y( \- _
Epoch 5/5
) R+ g; \8 k& E/ K1 i' Y* y
60000/60000 [==============================] - 2s 42us/sample - loss: 0.0369 - accuracy: 0.9888
+ D. j# `; g9 V+ E
% B5 S9 b& a. r! T$ q: m
<tensorflow.python.keras.callbacks.History at 0x13a7892d0>
2 U8 I9 l2 z; J
1
$ l, O+ z9 O M$ I
2
: G0 d) I0 \/ Y+ f. k
3
9 r4 ?" w; D: l U6 k4 X
4
: D# ]3 ~) }3 H4 \: j# o, }, l
5
/ T; U2 ]9 a; T/ {, O0 p( d
6
$ `" Y9 C- k, a
7
* K4 ?% y+ G( _$ O+ Y, N
8
2 G' ^3 K. {6 c* N4 k B" D" Z
9
9 G! G" F6 Y& Q; B
10
, y( z4 g9 c5 N8 d( O/ p
11
+ |4 U: E2 ~/ G4 Y* l
12
) ]- Y, R- a! L4 q% F
13
9 X# }3 J1 d3 m% w% u! \9 h' M4 `
可以看到,训练很快,一会儿就对训练集有 98%+ 的精度了。
+ V6 n+ a! Q9 k. d4 h3 N* E
) C+ C% s1 {/ ]! _
再用测试集去试试:
; `; A3 a( c' P5 B) `
; I: o/ J, Y3 a8 ^" K! ?
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
, \: a" j7 Y$ y x$ I
print('test_acc:', test_acc)
8 e( `! B, H$ C1 j
1
1 W3 ]1 d0 |9 b( B
2
. w, |2 g4 k7 J' A" u5 J7 H8 i
输出:
% o5 H$ e" _! U W! g" E
, y/ f# G5 S: y. V( f/ T5 Z
10000/1 - 0s - loss: 0.0362 - accuracy: 0.9789
( B% o* z& d& B, k1 s3 w. e! J
test_acc: 0.9789
/ _' A' r9 L9 _/ |; {7 N% ~
1
& q) E, h6 f8 |7 t0 A+ ^$ y
2
2 w+ A8 L: F( A6 D
我们训练好的网络在测试集下的表现并没有之前在训练集中那么好,这是「过拟合」的锅。
3 Q2 |, k- i& S/ v( x+ ~: e
- b; p) p( s% M* [
神经网络的数据表示
7 p" W' Y3 `% J, j& w; D w
8 w0 i3 u8 \) c
Tensor,张量,任意维的数组(我的意思是编程的那种数组)。矩阵是二维的张量。
, I' p( i$ ~" c' O3 U$ _
, j# e& E, l- w" `" d% y9 ]* j
我们常把「张量的维度」说成「轴」。
# o6 y, |6 \. A' D9 Y
8 f- y* B2 W& W
认识张量
& R6 p/ p9 x4 x& j5 N
' E' B5 A4 `% \, m, C
标量 (0D Tensors)
$ }& Y$ M. F1 T3 t( E* V
, J0 z' _, K9 s7 i
Scalars,标量是 0 维的张量(0个轴),包含一个数。
* E) `5 g; }8 B7 q1 [+ p/ J" R
- f: }8 a8 _5 t0 J, ~* @
标量在 numpy 中可以用 float32 或 float64 表示。
% e) _' x8 ]6 v6 t) _5 R
% F ^4 F- [, R t$ j
import numpy as np
1 F9 Q/ Y ?5 V* E$ d3 S+ C% s
2 p" j5 k( O- _" e
x = np.array(12)
: P* V, {$ h$ R) k! S4 U. Y
x
0 e) g s5 {$ c' C" p) C
1
7 j3 ]) U8 f/ Y% u9 e
2
X3 @3 K( U/ z8 j7 S M+ [
3
- A% @9 y. L6 O4 e' d
4
O% p& F$ a. f. Q1 m8 y8 B. N
输出:
% g! C; C8 e7 Q
6 t$ R& r5 d4 h. t$ g
array(12)
- b. Z& m6 p0 v
1
' w5 a. m1 ~8 I6 l5 q
x.ndim # 轴数(维数)
1 y$ M& R. O4 D* A% C9 l* Q
1
) C) D; s; U# Y# B0 r+ z# K7 g: H$ c
输出:
- Q8 g) O* U6 T+ ^; q; L4 L$ ~; f
9 |0 o6 V+ N! I1 m: z
1
" t& @9 a9 ^% u3 ?' ~4 U; \! L
1
2 i! }8 e+ F5 X. C& @8 r$ O( o
向量 (1D Tensors)
: [! `8 D! \* p( W* ]6 X8 m9 I* B
) ~. `% o3 W/ ^1 d* g
Vectors,向量是 1 维张量(有1个轴),包含一列标量(就是搞个array装标量)。
" E" h2 s. y* o Q3 a
$ |3 W k8 { y
x = np.array([1, 2, 3, 4, 5])
1 g: v/ d+ i) ~2 S; l+ Q
x
3 {7 \; R$ s0 {9 K7 h
1
! V9 a/ v, y4 F
2
) C! T5 C& `# _# G" e/ j' J% |+ G
输出:
% o' c! {& [2 c8 _
- \8 s! I1 d7 r+ d
array([1, 2, 3, 4, 5])
) j' B# L* L$ @6 ? I) E3 @
1
- a# a- W& i9 d9 n( _- [
x.ndim
" D. l! _0 r6 K% y* @" M' e L) |
1
% i/ ?2 d. A: [$ c6 ~2 u! c* s1 z" b
输出:
, B! i( q; _8 x1 q9 }: |9 m' k
% R: Z' {- D2 e% z* \# H
1
' q' G; T9 E2 u8 L3 f j
1
: I* o0 h, w/ D: N' Q Q
我们把这样有5个元素的向量叫做“5维向量”。
0 W% P y/ V" t( r" c* i$ R
但注意5D向量可不是5D张量!
; G$ T3 t( b/ i. l& Z1 ~
, g' @( s8 f% e+ U
5D向量:只有1个轴,在这个轴上有5个维度。
; T$ `3 T0 c- O- f9 s/ J% ~
5D张量:有5个轴,在每个轴上可以有任意维度。
5 K4 ]! I+ E8 @
这个就很迷,这“维度”有的时候是指轴数,有的时候是指轴上的元素个数。
3 d8 O, t) m7 A- V# F3 y/ ^" W
3 z& |! h* q& T) ^5 E
所以,我们最好换种说法,用「阶」来表示轴数,说 5阶张量。
Z+ N6 |) G. w5 B
, {8 V3 N) ^9 Q
矩阵 (2D Tensors)
X9 p/ I$ ^" q: n4 |) b) D
. p3 g% ^$ I% v& B
Matrices,矩阵是 2 阶张量(2个轴,就是我们说的「行」和「列」),包含一列向量(就是搞个array装向量)。
/ I+ `4 }. S8 d7 N* Y* x3 L
$ |! T$ Y! }& E
x = np.array([[5, 78, 2, 34, 0],
9 Y/ B% {- B0 T0 E4 p$ i
[6, 79, 3, 35, 1],
; J( |# p+ v% l& f0 j( I0 A0 u
[7, 80, 4, 36, 2]])
3 W: k% c' U# H3 a; I# l9 c& b5 P
x
9 o; `- Y' i9 D0 N/ `% \
1
) S% }! ^- {4 K! l; V, k; l' v
2
0 l' `5 x8 t: N) g3 Q
3
: R/ P8 Q( `8 Z, D# P
4
* b+ X- ^" @: p1 n/ K
输出:
) Y7 H; R$ u y6 w* s
& `. [" P: s1 B0 z* e$ h
array([[ 5, 78, 2, 34, 0],
0 g! B# s0 ^- f
[ 6, 79, 3, 35, 1],
$ v, C! K9 U+ {* Y
[ 7, 80, 4, 36, 2]])
W" L1 F, C( q0 d4 w5 ?( {
1
+ \+ M1 C8 }; L- P
2
% F0 g$ |5 M, s8 ?5 S, ~4 s, B
3
" P$ S* X: [/ M2 j* H- ?7 G+ R
x.ndim
2 Q( [# q* i+ @" o/ d' l; r! f
1
1 } T( z! O3 Z- U* \& u6 f2 [
输出:
/ u, L: n# x/ Z* G# j
Y9 _( M: q* C3 _& b/ W
2
4 N& k# V9 X! \1 i
1
- `, R% w$ ~# I) I
高阶张量
2 d$ v* C2 i5 T a5 e
" V- x! ~$ x1 g
你搞个装矩阵的 array 就得到了3阶张量。
2 D) h$ q2 Y" G6 P$ a, _# X
- }& N; }* h, D6 x3 n
再搞个装3阶张量的 array 就得到了4阶张量,依次类推,就有高阶张量了。
4 Y* g2 l6 d K$ M9 i7 t
' i$ G+ P% \7 T8 ?" b* G
x = np.array([[[5, 78, 2, 34, 0],
G$ o: I9 r2 ~( B! E4 I6 _3 K
[6, 79, 3, 35, 1],
/ |# n8 C7 O# X: |4 Z+ l* _: j$ W {
[7, 80, 4, 36, 2]],
' o* G0 T, Y& l* {: m5 b, m' ^* ~
[[5, 78, 2, 34, 0],
- Z+ t$ i8 ?5 p% Y' L
[6, 79, 3, 35, 1],
3 ?# h: d4 b5 x2 V# K p1 A6 C
[7, 80, 4, 36, 2]],
5 w, L$ ^* A. {+ u, Z
[[5, 78, 2, 34, 0],
9 }6 Q) g7 ^& g6 Z# E2 V
[6, 79, 3, 35, 1],
6 ?% _% ^# f' ], H+ b' K4 F& E
[7, 80, 4, 36, 2]]])
. o8 T' U- Z3 a. o# y- x4 A; ?# H
x.ndim
1 q7 c; O/ T' ], K
1
8 K- |- I* {/ y1 \1 A
2
; q u X0 u! E# ?% L
3
* @9 B! G) C4 y
4
6 L+ I+ X, S- l5 G% c: P# ]- u1 T+ g
5
/ W% V7 `3 y$ X: f- @7 X& R4 C
6
! L/ M1 w( { d4 v) c' n2 h
7
& y, w. R# J) k/ s% }
8
1 z6 w% @& N* }" V& u
9
' a& [. |) T k: W/ o: M, c) l& [
10
! o9 l5 L0 h( ^' T! y
输出:
% A+ I6 M3 m' g/ _) E6 }
2 f: u, D' T! ?7 L- L5 {
3
9 Z" K% g9 L; }- \& R
1
, U6 h8 c- r8 e
深度学习里,我们一般就用0~4阶的张量。
0 d' X% K8 L+ o5 d
- |( b5 r3 H2 X8 a
张量的三要素
J& \; |& L$ W! l" u; t0 i
* g* a0 \, R. T6 U9 S0 M1 M. _, L
阶数(轴的个数):3,5,…
5 \8 ]" |8 K1 U. d1 G9 r
形状(各轴维数):(2, 1, 3),(6, 5, 5, 3, 6),…
2 i. I) r! q8 F
数据类型:float32,uint8,…
5 n7 G; t7 M& q
我们来看看 MNIST 里的张量数据:
6 o1 y& W& [9 U W
) L; L) i7 W# X
from tensorflow.keras.datasets import mnist
7 S( [) v- U3 _5 Y. V$ d1 h4 @0 @, G
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
0 b2 \% L Z. a0 E+ t4 s8 \
! h9 h: W p# x( h
print(train_images.ndim)
( F% O/ i" y. U$ R* b: z
print(train_images.shape)
- h3 V; n3 }: I1 D
print(train_images.dtype)
5 v9 i; L9 p8 @
1
9 y2 D% v3 H) g2 @6 r
2
( [0 `$ D4 X7 x) `
3
0 @' Q& |! q6 Y! L7 Y
4
! H& o/ H$ u" [5 S) U
5
9 h; }" N* \- ?
6
% R; d' l4 a2 H z, W# O0 k/ M
输出:
+ p7 m0 o+ U* |# |5 h7 @9 ^
9 \$ O1 l0 b. V4 N
3
* I: Z- E3 l |& L9 p/ V: D
(60000, 28, 28)
& J2 H2 Z3 D$ |" N) C! t' j
uint8
7 r. f z- r. }" p
1
- C6 \2 c# v' Y6 L4 o5 M4 |3 ?# u
2
9 y0 j8 [: r6 [) D/ u/ H
3
8 s4 E6 e$ o; }" Q
所以 train_images 是个8位无符号整数的3阶张量。
4 y! z( ] C. L, [
B$ l M6 O; Q! w$ O3 d+ N# E" o6 ^2 S/ [# [
打印个里面的图片看看:
9 w x; _! w( Y6 @
- W$ ?- Z* y- I" Q2 M
digit = train_images[0]
1 ^0 h2 d! ^- h$ `. Y
5 }6 o1 A+ @: U% w' @
import matplotlib.pyplot as plt
G0 k) J8 c! W' b
; ]. X9 e8 ?7 d* q& G' ^
print("image:")
& U. M% o& ]: p6 E* F
plt.imshow(digit, cmap=plt.cm.binary)
! \1 P4 P- k* B2 h1 K8 K
plt.show()
}2 q# b3 o$ k D
print("label: ", train_labels[0])
+ C# B+ e( h; h6 p% G4 @+ z; \3 T
1
3 I8 i8 |: j" q
2
" ?% e3 d j2 S# }
3
. V& f+ z& q% N, u3 A: x
4
. @1 J( a3 o' l" \: ?
5
6 ]3 k7 b0 \# Z0 ?/ x( Z
6
$ l( r2 S; d1 }0 J/ _
7
' a Y6 ` s9 G) S X; r
8
/ g6 E1 ]0 S8 U; f& U
输出:
. J* g( u# I- t$ b, h1 A: j, i
* i: ]6 [0 ^0 p
2020-5-12 11:55 上传
下载附件
(14.63 KB)
3 }2 F. g, P7 B8 h2 V5 \
* x6 z X6 _3 K) r& w
label: 5
# e- ~6 C% P8 D! ]7 z4 ^ D! z2 q
1
1 ]+ X4 F8 `9 _9 I+ y( y ?
Numpy张量操作
3 k. }5 a( D5 s) [. d( i. [: x* \
! O, p! l# T/ ], W
张量切片:
$ G/ K; e% A5 \. f. ]3 }: K
- w( v; t. L. N! l9 K
my_slice = train_images[10:100]
* ~# O7 x l" f' ^0 o$ N1 D
print(my_slice.shape)
/ `) p/ F! m) t# T$ P8 G9 F
1
4 O, V' ]$ Y6 @4 s$ H' ?2 U
2
B9 W! R6 S+ v& G8 |+ @
输出:
; g M& u0 M9 {5 m4 K) _
2020-5-12 11:55 上传
下载附件
(12.59 KB)
, C1 M! E$ U* U& ^
(90, 28, 28)
0 ?) d3 p/ J3 z, {
1
; G P/ Z6 G8 }
等价于:
/ }! I8 Q, J2 }3 t
* ^7 v" E7 P' {8 T
my_slice = train_images[10:100, :, :]
( G* B" S- j% @
print(my_slice.shape)
6 Y& P# |, _; J+ f4 I
1
, p* g; {9 D! a8 N1 y4 D. {
2
- z. _: ?& X* j+ }: Q
输出:
' K% Q n/ E4 y0 r) b( d2 m1 b- c4 k7 i
2020-5-12 11:55 上传
下载附件
(16.13 KB)
. I: e7 s6 U/ F M
(90, 28, 28)
/ s! Y5 |. J1 l7 A
1
H3 \1 _5 @; F
也等价于
, B2 K5 `, E8 K
# g8 m+ Z0 P9 Q1 E' I0 U
my_slice = train_images[10:100, 0:28, 0:28]
! R7 ]9 c3 K) H7 Q
print(my_slice.shape)
! o& {7 t! d. O! y: N4 q) M6 _. x
1
3 C+ a; G* v7 w, R- e$ V1 S
2
8 y! E# y: B! u6 k% d5 R: W
输出:
" r- v5 V( J! n% V
' v( o+ b% ^7 D! _1 A
(90, 28, 28)
; D6 G1 G2 M' K+ ^) j
1
) Q# K6 j' m0 S& k* c0 V+ D
选出 右下角 14x14 的:
; r9 [. n! |- B8 I4 W' f! G
g' e+ f! }' k0 w# D0 F) U* K& {2 \% m
my_slice = train_images[:, 14:, 14:]
: v2 q, D1 B) p
plt.imshow(my_slice[0], cmap=plt.cm.binary)
' [9 E% i# O# x' w2 E, |
plt.show()
3 H' V$ ]! y) K# l' ?% R3 P- {. }" \
1
! b2 u- L9 R) i4 t, l, m, _& X! a) |
2
8 k' E, c1 `/ V' [; V
3
2 k1 N" W! O: ~
输出:
2 U5 t: V' b* W( s/ _/ y
6 U' d+ w! m. Z# z+ s$ k6 q
# V' P; l1 {: N2 @
3 i2 y! k& D+ B6 L* M% m5 s5 s8 q
选出 中心处 14x14 的:
) w8 K; ^- V* \& f2 }" r$ o6 {- V
) ~9 K! \7 E- L/ V7 i- I2 m
my_slice = train_images[:, 7:-7, 7:-7]
p0 p# C% ~7 C1 [! r
plt.imshow(my_slice[0], cmap=plt.cm.binary)
' [9 }/ ?2 m# m# @. ]# l
plt.show()
" w+ N, c2 k& F% z2 b
1
! C8 m8 J! C' {' b8 l. s( | E
2
" p0 l$ c+ a* Q2 ?6 q, n. R' K; |8 x
3
$ G6 B6 j6 w h; i9 U" t. y& F
输出:
! k, A- D1 v0 i
# R4 P; w: u4 \5 I& i7 i
A, e& a4 m. r k1 ]- U
* ?2 F7 ]% V4 |" s$ x( ?
数据批量
8 V5 n7 X# {/ r- x f- m1 H3 C
$ h3 i$ q' W- F% E, K
深度学习的数据里,一般第一个轴(index=0)叫做「样本轴」(或者说「样本维度」)。
( `( p% N0 G" Y6 R8 g& t) P/ y
. j* ]# ^7 K' m" ]6 M/ ~ j/ ]* g
深度学习里,我们一般不会一次性处理整个数据集,我们一批一批地处理。
9 x7 H4 b( X. w2 C1 t
2 | J& S; `4 `! N/ O o/ B. C
在 MNIST 中,我们的一个批量是 128 个数据:
# Y, u" y$ C8 U; p
4 c: f1 l ], o, Z% r
# 第一批
0 l" r2 D+ Y' i
batch = train_images[:128]
1 E( p; T4 d) d
# 第二批
4 P( E: y4 K+ C% P
batch = train_images[128:256]
0 [( V7 v$ C# T+ b6 c
# 第n批
/ S5 b; b! t5 f# z, q! Y
n = 12
5 v% A; C8 o% W7 _/ N2 ^3 u2 u* C
batch = train_images[128 * n : 128 * (n+1)]
( p( k- l A9 f7 Y
1
; S5 |7 x* s$ S0 n0 D. O
2
- ?" Z; T& s) N- ?6 r' W
3
3 L% S% w: |1 Z
4
/ M/ y7 b! R- r9 M
5
, j% b4 S$ O3 Q n' y) _6 @
6
' f% ~, C8 L! R0 A* x. O3 K
7
7 {* o$ Z; D; g3 P. G
所以,在使用 batch 的时候,我们也把第一个轴叫做「批量轴」。
4 S. o9 i# D7 c9 u' R( r# J
) ]4 F+ R+ a. s2 n C) Q7 V
常见数据张量表示
5 N* N0 u7 `, F9 n9 d7 x
- f r( J- {6 b5 P: L1 S' [
数据
' w5 B/ `( @3 x' F
作者:
2863358207
时间:
2020-5-12 12:11
好好好好好好好好好啊发表回复
* r) U1 b' ~+ w5 T2 l
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5