数学建模社区-数学中国

标题: Python深度学习之初窥神经网络 [打印本页]

作者: 杨利霞    时间: 2020-5-12 11:55
标题: Python深度学习之初窥神经网络

# \0 h# k$ v$ O, i4 [Python深度学习之初窥神经网络% y* ^8 u8 U4 U/ K: P! ?' O
本文为 第2章 开始之前:神经网络背后的数学 (Chapter 2. Before we begin: the mathematical building blocks of neural networks) 的笔记整合。' G# K# I! F. W, }" u

- c5 v6 k8 P, h" F3 I+ e2 V# P% J( g0 {本文目录:- P0 Z, _4 P3 p  D, ?9 M
5 ^0 K9 q- A8 B5 V! B4 X
文章目录
' W, `" N! O- o3 q" P0 h5 U
8 l5 x& S0 |# d3 v5 {, T! A- lDeep Learning with Python, `2 |; |; \6 V; S
初窥神经网络
6 G8 e' d; }0 w1 ]1 c& c7 [0 L" ?导入MNIST数据集& _- Z* Q$ {. ^
网络构建5 ^- {; F; T0 N6 v; d
编译- T% p7 E4 C/ T- x9 D% r
预处理
% r: ]0 U7 @1 H  E8 R* }& v图形处理; H; X. O/ W, o; }. _
标签处理. ~: c3 Z+ R$ E5 h7 A2 `
训练网络  |, _) Z. F7 D0 K
神经网络的数据表示
& Z' Z- U0 E+ k, \: c认识张量. t) F+ J  M4 S; M/ {
标量 (0D Tensors)" r& l. S' n9 K8 o4 ]+ l
向量 (1D Tensors)
0 d9 U$ l7 `2 e矩阵 (2D Tensors)
" l3 ^% ~. X3 z8 x/ R& Y& F高阶张量
3 Z! h' W, M& D+ R1 a张量的三要素
& l' Z0 P; u& z' LNumpy张量操作
, i" R, s& x5 {' U% z' `1 Y张量切片:5 r) E" f8 O( x
数据批量
0 j! G4 c' I; R: `9 v! ^! L0 }; h1 E2 d常见数据张量表示
+ T+ f& x. s% T9 n1 `神经网络的“齿轮”: 张量运算
) l. V6 a) m: `逐元素操作(Element-wise)3 k7 k, B$ B6 H" \8 S# x, R
广播(Broadcasting)/ T% c9 U4 W8 `6 B: Z
张量点积(dot)) }; v7 t6 ^  j$ P7 o  W% n8 W
张量变形(reshaping)
% {$ z5 P9 o3 Z7 Z7 ?( J神经网络的“引擎”: 基于梯度的优化; a, \4 G: ]7 [7 ~% g# p
导数(derivative)+ U3 e: }: t6 E, {8 ^: B: p/ Y& U
梯度(gradient): J7 `# W$ y! s0 o. p
随机梯度下降(Stochastic gradient descent)( {6 K" w# I+ H$ Q$ m1 s
反向传播算法:链式求导9 b* K! y2 j8 |' p2 {; X: [
本文由 CDFMLR 原创,收录于个人主页 https://clownote.github.io。; ~( }4 J9 u, X& B+ @
1 n7 G1 F! T5 @! ~' R* v3 L. o
初窥神经网络7 B1 u2 s$ q) ^& q, b
! {: f  s+ U" }$ S
学编程语言从 “Hello World” 开始,学 Deep learning 从 MINST 开始。
6 G  g- R2 q$ v5 d" l( S
8 D/ K. Y  F+ T9 o7 @MNIST 用来训练手写数字识别, 它包含 28x28 的灰度手写图片,以及每张图片对应的标签(0~9的值)。
0 C* R: b, z" c
2 c4 c/ u9 Z4 i( v* M- M- {9 W8 R导入MNIST数据集
3 |, C- l/ {% q
/ Q* E9 @( _# {& F, I' Q# Loading the MNIST dataset in Keras' j! z* x% ]; P; v: B5 d/ j
from tensorflow.keras.datasets import mnist. H2 @8 E9 F. ?# M9 [$ L
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()( i6 |& A9 B0 E( \/ ^, P
1
2 s+ y& S- r! B% u# m! D2
* D  o. W7 Q2 R6 P$ W3
/ w+ T* L, g2 e, T& z看一下训练集:
; a+ U- _" g) V4 ~* a3 t. v! d0 o1 ], R0 N8 i, y) ?' D
print(train_images.shape)$ b+ U% U' P" i4 Y
print(train_labels.shape)" k( y# e0 w* @, u
train_labels9 C3 I* j% J5 B8 R2 F/ T9 c
1: H5 V" o. _  r. i
2
+ Z2 A1 |# ^' b( ~! g, x3
% T  Z' S: u0 V) D' l% Z# ]输出:# f  J4 S3 ?) m  O) U
& J: [# W( H- Z& S- F  v& E
(60000, 28, 28)
: \9 R& ^) j; l% W! L(60000,)* g& j' r, d) x  |" x3 y3 F

- A, v* U' b# f( `2 q7 N! Yarray([5, 0, 4, ..., 5, 6, 8], dtype=uint8)
1 c7 r+ _% L/ W& }3 t8 z1* D2 p, b# `- K% H0 ]! N
2
: o- r  J# R8 O& ~3 ~' }3
( m4 O; @: M! h3 W45 [) _, J8 x$ Y6 S7 J4 g9 L
这是测试集:2 e) N4 i% U" h  w
, U' c  m* n4 _$ }0 v$ H  Y  {7 w
print(test_images.shape)# g! [0 @% @! \$ Z$ L
print(test_labels.shape)
2 |9 L) a& e! a/ f; O) ^) ^( E0 Etest_labels+ E/ _6 k# e( ?' ?8 P* F, J1 _0 u
1
8 G* w( _1 a  a: o( E25 ^# t  x0 n- @" i" L% \$ r6 S
3
' Q0 O" z& D* c3 ?输出:( g' D1 L) Z1 q/ l5 p) q' E
8 l4 p2 p+ W6 Z( ]5 ?( b3 G
(10000, 28, 28)$ T- u/ y( f9 u  @
(10000,)0 k, g6 }8 Y- C5 S
7 J& a0 D/ ]0 v4 ]! r/ H
array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)
% Y4 i2 }) s: B1 [( |( O1
; l0 M, y+ @0 F5 [1 s28 a5 E' @. v4 Z, O$ D& U" D
37 w* N( [8 x4 D- Z/ C3 t
4' I- L7 W4 r, h9 ~, I3 V1 m
网络构建
  z- R8 {0 e7 K! u8 I2 \5 I
. Z9 }) q  @; s3 s- j) `- i4 O7 ?我们来构建一个用来学习 MNIST 集的神经网络:8 k* z5 G- y3 N) q% [

3 C- h- Y7 O7 j9 g- C8 {from tensorflow.keras import models( f5 r+ C- B6 |. s" {: H* R% n" f
from tensorflow.keras import layers5 w4 d0 m  Y( j" B% [' ]
. b2 v6 x8 i- X* T) j2 D
network = models.Sequential()  V8 i2 U6 n, t* X+ q4 _
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28, )))$ N" S- W% _( u. i- X% @# Q
network.add(layers.Dense(10, activation='softmax'))  G+ ?5 }! j. `+ E: c
1  T% O' \) ?$ N/ P
24 e1 e0 m+ ~3 }2 d2 {  r, a2 F
3
; b& e; m0 ?8 d4( L! w6 p! G2 R3 q7 z! S
5) z- J; B4 q; y0 Y8 C9 R( _" C9 u
6
% q- l1 {$ C9 H2 _: I神经网络是一个个「层」组成的。
8 n& ]+ a1 {2 N3 }7 |2 I一个「层」就像是一个“蒸馏过滤器”,它会“过滤”处理输入的数据,从里面“精炼”出需要的信息,然后传到下一层。- o6 z( t1 f9 h, W

! Y# [7 ], Z9 \这样一系列的「层」组合起来,像流水线一样对数据进行处理。, C$ [8 u7 }: b9 c
层层扬弃,让被处理的数据,或者说“数据的表示”对我们最终希望的结果越来越“有用”。
$ {& g3 v9 M; h) l9 j
+ ?, y; q$ ^- e+ T我们刚才这段代码构建的网络包含两个「Dense 层」,这么叫是因为它们是密集连接(densely connected)或者说是 全连接 的。/ R8 T, o# Y- R0 s; P' _
- \4 H3 _( G  [* {* e* V' ~; O
数据到了最后一层(第二层),是一个 10路 的 softmax 层。; D$ J" i  ~/ l8 A) ?* n7 L
这个层输出的是一个数组,包含 10 个概率值(它们的和为1),这个输出「表示」的信息就对我们预测图片对应的数字相当有用了。
/ P, b- M) J- G+ p6 p. L% q事实上这输出中的每一个概率值就分别代表输入图片属于10个数字(0~9)中的一个的概率!
! I' ^( ~2 D, L" c7 Q: P( ?
* S1 z: u; d; ~( |编译: U; @6 ]- m3 c. [  A+ }
; n0 H1 x# J6 t4 m
接下来,我们要 编译 这个网络,这个步骤需要给3个参数:: X* _2 ]8 J& m" [2 h7 W5 J6 ]
0 p5 a6 F* J6 ]3 b/ T9 |
损失函数:评价你这网络表现的好不好的函数
6 D1 v' L( V) X! ~2 S. a优化器:怎么更新(优化)你这个网络
2 \5 Q" T* B3 X; H, y8 v! l- `- f训练和测试过程中需要监控的指标,比如这个例子里,我们只关心一个指标 —— 预测的精度
, P+ }, I/ ~) S& tnetwork.compile(loss="categorical_crossentropy",5 \4 {) v- _4 s# P  E: x
                optimizer='rmsprop',* o, @* Z+ B6 I  m* r8 K# U. p+ ~
                metrics=['accuracy'])# |; D" p2 R* Y) _4 @( `
1/ F+ Z: \0 z$ ?
2
- z% P4 u/ [! y9 `7 @39 ^$ G* O5 G" l6 x6 b
预处理
/ |" E/ `' e) \2 q* w$ E# w
" W7 W1 a% |6 D! R! f, q' ?8 x3 n图形处理
. I% j' @  g& k! e  c4 [; d- Z! S/ S# C  p& G$ k( U( l
我们还需要处理一下图形数据,把它变成我们的网络认识的样子。
6 y" ^, b6 U3 H& J
- v* U3 T$ J" |MNIST 数据集里的图片是 28x28 的,每个值是属于 [0, 255] 的 uint8。/ A: z# Z, N) w- [, C! h
而我们的神经网络想要的是 28x28 的在 [0, 1] 中的 float32。4 T4 e! g8 c0 w" w' `& {- o5 |

; ?" b1 o3 r: H" t9 S$ i. h% ~train_images = train_images.reshape((60000, 28 * 28))
& L6 z5 y. K' G0 L) ptrain_images = train_images.astype('float32') / 2551 z2 T! B; B8 k$ V  @
. [3 F4 x6 i/ m9 C+ |# `' ~
test_images = test_images.reshape((10000, 28 * 28))
- s( L. e1 L! W* g* P% Ntest_images = test_images.astype('float32') / 2551 r2 \; u' E+ k4 }( O+ _6 O
1
  L2 R9 _3 u, G9 ]: b26 {1 z# T/ f* r7 R7 ~2 Q
3
' g! h* J, C. [4
% L4 w0 L+ U) F( s4 w5
: {, L# l# G5 e$ g' w& _! y) g标签处理
9 `9 H; G; l9 W+ x" ^5 |# A' f* H7 T" j& q2 W, Z
同样,标签也是需要处理一下的。8 d" a6 q" V: z% ]) B

: o6 @9 L, u3 L/ z8 Tfrom tensorflow.keras.utils import to_categorical1 u9 z* \  a, _. R

8 R$ N! k% g: Z; }% g3 Jtrain_labels = to_categorical(train_labels)# x' K, l$ ~3 d: g- {
test_labels = to_categorical(test_labels). N$ L0 K( r% f& X+ k$ s
1
/ l! y0 Y  d# F2 b7 P2+ }, w/ n" J8 t( c9 R3 y  E: Y" z
38 z7 Y. c7 m! f9 M6 w
4
4 [3 c' Y/ m8 m% Y9 V  D6 I6 Z训练网络9 R3 j# l$ _/ P9 \4 E

0 }' v$ f' b  H) p) z& O% wnetwork.fit(train_images, train_labels, epochs=5, batch_size=128)
4 S7 ~  l8 b% X) [: E7 q6 }5 s1" d/ e5 }! p- _. ]: @
输出:
+ b' q/ J* h9 m+ y5 r$ |# S; e
# N6 ]6 d5 \; uTrain on 60000 samples
- a0 [! a1 k/ s9 QEpoch 1/5& b& ~* ^! Q8 Z( G0 P! D  v
60000/60000 [==============================] - 3s 49us/sample - loss: 0.2549 - accuracy: 0.9254" E& r5 a. S# O1 R( l: ]  e
Epoch 2/5
7 x6 O1 {6 d$ n3 D2 G5 i60000/60000 [==============================] - 2s 38us/sample - loss: 0.1025 - accuracy: 0.96937 C0 y8 h3 ^1 Y
Epoch 3/5
2 A0 x1 ~, v$ p9 q60000/60000 [==============================] - 2s 35us/sample - loss: 0.0676 - accuracy: 0.9800
) D; K4 b2 p. M5 o* VEpoch 4/5" C2 L% }9 v2 Z4 v
60000/60000 [==============================] - 2s 37us/sample - loss: 0.0491 - accuracy: 0.98483 W1 P9 O: u6 `
Epoch 5/54 L. D/ z" h$ q2 u7 s4 e0 b0 h
60000/60000 [==============================] - 2s 42us/sample - loss: 0.0369 - accuracy: 0.9888: Z9 n' _3 h4 d9 M- f2 S4 v

: F; _/ i5 d  w1 O<tensorflow.python.keras.callbacks.History at 0x13a7892d0>! Q# A9 v! o0 G' T- l
1
* g3 n3 L: Y' {5 Q6 s26 X6 E4 \8 A$ U7 _3 O$ G
33 ^! i7 t" h4 m: P9 j5 x4 T
4. F' G5 k. L' M5 r- N1 W+ L* I
5
; K; P' P" M/ A3 r6
0 d0 F4 x. T5 {6 C! @7* s; R6 n1 P2 u, e! V
8- W( v  T. F& X4 t: Z7 @  q
9. a- ~8 O+ o  b* D! I: d  i
10
  F; k& |: r3 F( C) j5 P9 P# i/ `11
$ e$ L# S3 h  K$ T128 |# |' S9 T2 R6 `7 C7 d
13
; n: C" J" q7 J; d可以看到,训练很快,一会儿就对训练集有 98%+ 的精度了。1 t( M; U. G5 d1 X! m9 U0 W

1 j" P4 }, @* u3 J再用测试集去试试:- t  @* G7 [8 E* C" h3 k3 A
. D+ }$ M, \" i! p* U' ^2 q( N3 w
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
8 f8 M" L6 n. Vprint('test_acc:', test_acc)& S; Q, k) N0 @* H9 G1 J
10 `& _2 F' T" [$ y6 z) |
20 U2 a1 r! Z2 |) v$ v) B
输出:
) S9 E! ^5 R0 H. N* j* X  ?3 [2 F* O+ A4 t* h+ c/ Z/ N
10000/1 - 0s - loss: 0.0362 - accuracy: 0.9789
9 J  K8 O- \+ G: Q6 }9 ~6 Dtest_acc: 0.9789% i5 s2 h+ w. S3 ~6 D" s; m3 T
1
4 q0 G/ e- z7 c. i: i- P29 I. c* @! `5 T8 [; ~
我们训练好的网络在测试集下的表现并没有之前在训练集中那么好,这是「过拟合」的锅。& _& }& R/ O% g- V5 g* ^* G
7 z( l. f! ?6 m5 {; p! B
神经网络的数据表示
/ r* Y  M. y7 N* [% `% q) A' U/ x
' a* E. U5 P1 y$ |- L# VTensor,张量,任意维的数组(我的意思是编程的那种数组)。矩阵是二维的张量。8 B% x: S. c; C6 y5 t3 w

5 U& \, q9 F* L: V我们常把「张量的维度」说成「轴」。& @% q# D2 K0 p& b) H- m4 n. z
3 c: b& z% Z  E7 g' `" h+ G
认识张量! R7 n9 b, C, i4 G) k& c3 k& }; e
8 f3 W, r$ V% ]! E/ w
标量 (0D Tensors)
% F% Q3 y5 T8 C) ~# I) p4 [$ |" b0 a7 H/ J" s0 ?
Scalars,标量是 0 维的张量(0个轴),包含一个数。
$ `, }/ x& ]4 [6 _0 s+ k5 _3 ?
  w6 q- f6 s$ C- {0 o2 G9 G标量在 numpy 中可以用 float32 或 float64 表示。) W5 U2 }: A/ l; s
) o4 v7 `7 K6 d& y+ d) ^
import numpy as np6 T: i4 v" Z( J& {! q
1 `2 x5 A) A6 [7 I! ?9 X
x = np.array(12)0 B! M: f9 d4 u$ ^% i( X
x, S5 \" p5 m, h6 d
13 n* B1 Q2 @* T; E* E
2/ b0 ~' f) l* g7 x
3' Z* z+ N& P! g7 y
4
: R# P  X) n3 o9 G输出:3 E( F% K" z# x' S% g0 W, D
  f+ ?% \0 b/ {7 k8 q
array(12); s9 ~2 R$ W/ O* L, u. ]
1
) V& t2 D) h. Yx.ndim    # 轴数(维数)
, u) G7 B/ c5 i2 J2 {5 z1# ~* S. x" @" y+ W
输出:
4 E, _) c9 U. G7 f1 F3 m; {2 N% {# C; x; A
1$ C8 a! q; S1 |" e" e5 x
17 K! j7 V) V8 U/ A3 p. E0 S
向量 (1D Tensors)
/ r9 d0 R+ H' V
5 T; W( z+ ]+ J8 FVectors,向量是 1 维张量(有1个轴),包含一列标量(就是搞个array装标量)。
2 q" [% F3 o& a! @' o  T* K. X) \
x = np.array([1, 2, 3, 4, 5])
7 O7 R) l: I: p" N3 [0 Jx2 L7 Z9 _  M& `7 L+ P$ v4 y/ o0 n
1: H  t$ E3 f; W" ~
27 o( R/ H3 H& h% |2 b
输出:
" \3 J( z4 K% t% M! @& _4 Y, p
; @" h% x  ?8 `5 J4 T3 ^) d8 parray([1, 2, 3, 4, 5])  h' Q$ i" B2 y8 k
1  R; ?: }" f8 o
x.ndim% O2 [. C* L. w: ^+ V
1! Z; [1 h, l3 @, M0 l( t7 O7 Y
输出:
8 `. C; h1 a" f" f
* w% C5 ]3 p  R# @# h4 i8 a  ?5 L# x: H. H1
1 Z  C) G: ~" j% s19 W! x1 i, V% D+ j0 c! \
我们把这样有5个元素的向量叫做“5维向量”。
& u& P  p: L) v但注意5D向量可不是5D张量!# W+ y0 L: W9 H( i( H% v/ l  F

* }1 z. M, J( u9 Z5D向量:只有1个轴,在这个轴上有5个维度。8 w( b4 S7 D7 k" L& @
5D张量:有5个轴,在每个轴上可以有任意维度。
. U* f3 J2 z: Q6 _+ {7 B这个就很迷,这“维度”有的时候是指轴数,有的时候是指轴上的元素个数。) U# K- I" D6 U, \4 W7 Z: p% t  t

+ v. C5 J0 G( Q8 V/ N所以,我们最好换种说法,用「阶」来表示轴数,说 5阶张量。5 K9 I( @- d6 S; j) k5 U

! E, W, F9 _" p1 c矩阵 (2D Tensors)
+ M! r5 ?5 W5 h# p. `- u7 R. k$ z/ J5 O! I' I& {& b
Matrices,矩阵是 2 阶张量(2个轴,就是我们说的「行」和「列」),包含一列向量(就是搞个array装向量)。8 H" E% w' Q; ~* k

# s8 ?* H8 G: q! Q" u( Bx = np.array([[5, 78, 2, 34, 0],, n; h$ N& n2 ^' {+ d
              [6, 79, 3, 35, 1],
7 ]/ i1 S- x$ I' d& P              [7, 80, 4, 36, 2]])
5 L1 H  T6 I% ~. I" K& s. dx
# r8 T2 [0 T$ _1 V9 k5 E# w3 Q# [1
! q/ K1 J6 h; P2
, }* h5 t) R6 L3
& {; r1 U% d% U7 o4 y/ r1 ^44 Q4 X1 [- p7 [! u* p, m/ k+ W
输出:( X8 e+ u, G) b+ i1 S, W. q# Q
3 n. b+ R3 z' O. x7 I& g
array([[ 5, 78,  2, 34,  0],
$ X0 k# }" P0 m       [ 6, 79,  3, 35,  1],# m. E2 ^& K3 }; W8 p9 W' r
       [ 7, 80,  4, 36,  2]])
. Y8 F# P' y1 x, V. Q; j1
' g3 z: y: a7 K2
" I, Q( O# u, o- o3
* K$ q5 e; w4 ^* N+ z5 T7 cx.ndim
. B. J+ i* [2 u  Q1/ q. l% R' w) B% H' i4 N9 f7 b
输出:1 C0 f$ M/ }. @$ a, B
2 t# K3 e9 w8 E4 I9 W1 l
2
( k8 Z: r* {. c% W. j( r! n13 c; ~8 d0 {4 {5 n
高阶张量) x  g1 N$ Z3 W0 Z
% r! ?/ x6 p8 H6 N+ v; k
你搞个装矩阵的 array 就得到了3阶张量。
3 F+ o% D/ _* E' t3 F. E& i
3 {& x1 i1 C% j4 M( X: A0 O( h再搞个装3阶张量的 array 就得到了4阶张量,依次类推,就有高阶张量了。
; H& W9 T; _$ R. c$ h- i  p# s7 d  [7 x1 u. F$ u8 ]
x = np.array([[[5, 78, 2, 34, 0],
  C2 `9 b) |* H* ^               [6, 79, 3, 35, 1],
3 z2 E2 T# C4 Q' f/ T               [7, 80, 4, 36, 2]],4 R( @3 J; o0 `, ~+ \0 e
              [[5, 78, 2, 34, 0],9 I+ V- Z$ N) T" m# x$ a2 ]
               [6, 79, 3, 35, 1],6 ]! W/ \& t7 [9 o
               [7, 80, 4, 36, 2]],; F3 m: D+ g$ R6 f
              [[5, 78, 2, 34, 0],: {" b$ P# T  c8 _" l3 K
               [6, 79, 3, 35, 1],
3 ~2 I, S7 c4 C, r2 O$ s               [7, 80, 4, 36, 2]]])0 {5 }" |$ ]" R* L
x.ndim7 S! u8 `8 f; r9 m
1: X7 O) R0 }+ R& P. g
27 I. a: r2 W: h# {1 |" G
3
8 V! O2 X- M; n$ J8 d42 n7 x6 {$ q, V( F
5
2 r4 f& N" {" e; c) b3 l6
) p$ }8 G  `1 Q+ e4 F7
2 P2 [: x  C4 P% C. k; F  u8. K9 ^5 _9 x* Y9 W
9* u4 d) a" ?6 {, k
10
% e, A. d/ U$ w输出:: `" c4 T* ]% A' K7 U6 y

" _; h, L2 k; x) i+ D7 q  k- ]35 j2 m2 k9 y8 R- M% Q9 b9 i9 R. i1 O
1
/ }) s5 X0 x: j: c+ \/ H$ o深度学习里,我们一般就用0~4阶的张量。' \7 Q0 l" J" r& k3 z8 ^& N

  s* U# z  v' F, {! x张量的三要素. S  f3 p5 P" r2 V. r
2 X' m$ l( o; j7 r4 l
阶数(轴的个数):3,5,…- A' Z8 l' K( y9 I7 \
形状(各轴维数):(2, 1, 3),(6, 5, 5, 3, 6),…, }7 c5 @; {% u9 ?3 K
数据类型:float32,uint8,…1 {& W4 A8 @! D8 _! c" j  i3 M0 ~5 t( a
我们来看看 MNIST 里的张量数据:' o6 m# Z$ s6 _) y. I/ n# s7 k* A

& O7 m8 z0 U0 T: f( O- Qfrom tensorflow.keras.datasets import mnist
% v2 d% z# s) v0 b& h(train_images, train_labels), (test_images, test_labels) = mnist.load_data()& _& O& y# f( S( b

' y8 X/ N4 k; Q$ L4 @, I5 G5 S3 M/ \. qprint(train_images.ndim)
. |# ?2 }  k2 n- `; K% ^& Wprint(train_images.shape)% }- U' g2 b+ b4 t
print(train_images.dtype)
5 n+ g  l" a$ I1
: _' a& @0 [% Z" G4 a& r8 y29 h/ Y& \0 g0 v2 [/ h# c7 {
3
0 p3 x. @$ X$ N4
7 ~( V. o! z) ?- c% S$ v- B5& u' U4 P2 m6 D* ]8 @
6
' d$ m% W5 o% u- _& V' P! _输出:
; g6 s8 P3 R4 F7 j1 n" t6 y
6 }0 H" q+ B* q2 n" @3 q4 x3
0 n) A  [+ }6 Z$ P0 M(60000, 28, 28)
: Q3 u" Q5 H. yuint8% ~2 L  V* t8 d" C4 y6 N
1" O1 U2 F: x' O5 w& T& }( V0 V
2
7 r2 n. {0 @3 n/ c( v" g, \/ ]" F3
4 e6 L5 D$ {# Y& ^5 j所以 train_images 是个8位无符号整数的3阶张量。  x9 V; J8 H) g
& l7 a& n) x: G) B! {! Y
打印个里面的图片看看:9 U, S1 u, L7 [, l: F2 y! a
5 Y/ m5 X# P; i" L8 x* |$ g2 Q
digit = train_images[0]( R. [5 b" k1 u% m+ k
: k0 l; L* ~% i- P2 v5 X5 p9 |
import matplotlib.pyplot as plt
; X0 h& N9 t+ t4 o$ t8 c' p4 e
5 D" x6 Y* c6 _; B4 i1 k/ h+ d: F8 S8 ^print("image:")
3 }4 ^; D- y# ]4 z7 q( i9 o; H+ _plt.imshow(digit, cmap=plt.cm.binary)) j  ~9 t* G$ L& u
plt.show()
9 n! [: D7 G& U5 |+ ?print("label: ", train_labels[0])
/ R# P% W1 H& B0 J' |; S% v15 K2 ~4 {& L9 i8 Q
22 S9 t8 W% e8 ~
3! [+ d1 g" g, H2 M4 x7 S
4% T$ w" u% ^0 H8 ^$ m- v2 L
5" h4 S2 ]* W/ A9 v" o
61 c) l8 n; S. B% t+ U  K3 D
7
, q3 x" I' \  D7 l9 V& Q! D$ Y8. Y4 e( Z) n% r( C% z) V
输出:
2 \% Y4 G' D- Q" i2 [" M" E: U  D. z
1.jpg ( M: J8 x' Q* s: L& e
# ~7 }( Z  K: p
label:  5' H+ s% K' D. H2 R) T1 E
1+ }  B2 E5 c, i1 R/ |  w$ ?( P
Numpy张量操作
0 R% T$ x- u8 @1 }0 _0 [* g* z# X( W, ]$ B. d8 e/ S% }+ l; {: d
张量切片:; r# N8 L5 t* _9 m, n- g# p

: W; ~; a+ k5 K7 hmy_slice = train_images[10:100]# C4 w0 K; O6 j6 U
print(my_slice.shape)% S5 ?' }6 N3 f4 C# G- x& J
1  u* A0 s7 u; _9 D
2. G. J& m" [. e% Y/ W1 S
输出:" U- x8 R& _2 p0 o" _
2.jpg
5 l9 H/ P! C" |3 l0 G$ _(90, 28, 28)- D$ |0 {& q2 ^% M2 @7 i$ ]
1
! i+ S' {9 a& {, C6 z- c等价于:- `' s* Q" [2 W' S- n5 Q

  C# }  |& V1 U! b" ^1 Lmy_slice = train_images[10:100, :, :]0 s, a0 d& X% T8 r4 B2 p
print(my_slice.shape)2 A, X% X0 H0 v$ S) k. h
1
+ F  U0 h  p9 v* g0 |2$ X& a! Y/ f# G* p0 u
输出:# e6 A. y9 w8 R3 Y
3.jpg $ a- m. |# A5 W. G* H- j
(90, 28, 28)
  u/ C2 c5 G9 }1 |  M1) }; [. B; d* m# Z* }: a
也等价于  ~2 P( Z5 p& H3 m! B/ H7 y# Z* D

& V, b  ~) x" w7 H! K% Hmy_slice = train_images[10:100, 0:28, 0:28]* ^9 f4 s% D# ]: R3 K! W
print(my_slice.shape)3 k' R9 B$ H9 n& P
1
5 w1 X" ~4 |% d2- Q, s$ P7 Y0 r* o8 l
输出:
1 [7 \8 d0 N" m( l4 o* {& X. o5 J. ?
(90, 28, 28)
* ]6 O& q% i) v1 D7 ^: Z* L! G18 L3 o9 c" @, ~( C( ?
选出 右下角 14x14 的:
. k$ ^' d9 j3 v* v( O, \9 m" |7 w5 ~: E/ u4 m
my_slice = train_images[:, 14:, 14:]
; }. I2 _; B" g% f0 O8 F" ]$ M$ mplt.imshow(my_slice[0], cmap=plt.cm.binary)3 v* f( Z5 Z+ l' @& f: p; a
plt.show()
$ k3 l1 M  m( c1  W) o" P1 t5 u2 z# d
25 H7 H$ e$ A+ a% E
3
' o3 @3 C3 T) L8 a输出:
  ?7 K/ T' F2 ]! @/ I' p" j/ t
; }# H$ ^/ x5 c; N: q% s
7 b% c" ~2 W; P7 @- F! m
1 m+ T8 m6 S; {8 t. D选出 中心处 14x14 的:
& u, c) w  u$ I
# u; [1 {+ i2 ~3 A$ H6 hmy_slice = train_images[:, 7:-7, 7:-7]0 M- k, D4 f  b6 x1 d& B- r( G
plt.imshow(my_slice[0], cmap=plt.cm.binary)
) K4 U! _) t; v( H2 e3 ?$ X0 f# oplt.show(). P$ o4 ~; w/ R0 l; e& M% U
1
# P7 s$ ?9 {1 J. A2) D" _7 V3 x- M. Q  V8 F" d4 F
3: ]9 H5 c, w6 Z6 J/ I. X
输出:3 h) N+ l$ Y6 F" g: c  U
! F% z( G) t) H3 {& G
( ?3 j& f- a: F/ @/ s
% G- T+ Z4 |2 r& ]8 H
数据批量1 C' n" W, q8 r
* K0 C, p( t7 G. _/ _
深度学习的数据里,一般第一个轴(index=0)叫做「样本轴」(或者说「样本维度」)。1 v  P9 c: _' k# b6 F" k
$ t! O" p. o( ~6 u  m9 Z9 R/ j9 Y
深度学习里,我们一般不会一次性处理整个数据集,我们一批一批地处理。1 ~( ~; Q: o. v0 ^
1 A# x- j. q. I/ a. r- j
在 MNIST 中,我们的一个批量是 128 个数据:: i, W  ]* d* P6 M7 [# Z

9 J( d/ I9 R5 x# 第一批
& k5 b4 Q/ x3 a( t. r3 Qbatch = train_images[:128]
/ x% R( ]! ?% @  D0 s' S# 第二批
; m# R, [8 }3 }, [8 _batch = train_images[128:256]
; G6 Q: h$ _( U, z- l# 第n批, c* L# E/ N& m9 f4 b2 v8 J9 ]) x
n = 12
  @- z2 V: p2 bbatch = train_images[128 * n : 128 * (n+1)]
' B% E) F8 y+ j/ v0 I1: @5 f: A2 m0 k! `
2
2 l4 [" A" O' ~3
4 A0 i9 x$ z$ |) N, W! B% E. T4
9 I4 {% H* |2 i/ ]) q5# W( s+ o) R; G0 R; F6 ?7 o% ~
6( i" M6 e8 m/ a1 c3 m
7
( D  S7 i  b6 e+ O) @所以,在使用 batch 的时候,我们也把第一个轴叫做「批量轴」。7 p2 K, P: J7 }0 M# \3 b+ d: L

4 i# Q' H2 G3 r) w常见数据张量表示
  {" j' G, T2 {  l% T; g& A
. P; ?* ?! c0 b3 R数据) e9 C1 d& y$ C* O

作者: 2863358207    时间: 2020-5-12 12:11
好好好好好好好好好啊发表回复
- `. U9 y7 j. x9 A+ I9 P! R




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5