CNN最大的特點(diǎn)在于卷積的權(quán)值共享結(jié)構(gòu),可以大幅減少神經(jīng)網(wǎng)絡(luò)的參數(shù)量,防止過(guò)擬合的同時(shí)又降低了神經(jīng)網(wǎng)絡(luò)模型的復(fù)雜度。在CNN中,第一個(gè)卷積層會(huì)直接接受圖像像素級(jí)的輸入,每一個(gè)卷積操作只處理一小塊圖像,進(jìn)行卷積變化后再傳到后面的網(wǎng)絡(luò),每一層卷積都會(huì)提取數(shù)據(jù)中最有效的特征。這種方法可以提取到圖像中最基礎(chǔ)的特征,比如不同方向的邊或者拐角,而后再進(jìn)行組合和抽象形成更高階的特征。
一般的卷積神經(jīng)網(wǎng)絡(luò)由多個(gè)卷積層構(gòu)成,每個(gè)卷積層中通常會(huì)進(jìn)行如下幾個(gè)操作:
- 圖像通過(guò)多個(gè)不同的卷積核的濾波,并加偏置(bias),特取出局部特征,每個(gè)卷積核會(huì)映射出一個(gè)新的2D圖像。
- 將前面卷積核的濾波輸出結(jié)果,進(jìn)行非線性的激活函數(shù)處理。目前最常見的是使用ReLU函數(shù),而以前Sigmoid函數(shù)用得比較多。
- 對(duì)激活函數(shù)的結(jié)果再進(jìn)行池化操作(即降采樣,比如將2*2的圖片將為1*1的圖片),目前一般是使用最大池化,保留最顯著的特征,并提升模型的畸變?nèi)萑棠芰Α?/li>
總結(jié)一下,CNN的要點(diǎn)是局部連接(local Connection)、權(quán)值共享(Weight Sharing)和池化層(Pooling)中的降采樣(Down-Sampling)。
本文將使用Tensorflow實(shí)現(xiàn)一個(gè)簡(jiǎn)單的卷積神經(jīng)網(wǎng)絡(luò),使用的數(shù)據(jù)集是MNIST,網(wǎng)絡(luò)結(jié)構(gòu):兩個(gè)卷積層加一個(gè)全連接層。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
from tensorflow.examples.tutorials.mnist import input_data import tensorflow as tf # 載入MNIST數(shù)據(jù)集,并創(chuàng)建默認(rèn)的Interactive Session。 mnist = input_data.read_data_sets( "MNIST_data/" , one_hot = True ) sess = tf.InteractiveSession() # 創(chuàng)建權(quán)重和偏置,以便重復(fù)使用。我們需要給權(quán)重制造一些隨機(jī)的噪聲來(lái)打破完全對(duì)稱,比如截?cái)嗟恼龖B(tài)分布噪聲,標(biāo)準(zhǔn)差設(shè)為0.1 def weight_variable(shape): initial = tf.truncated_normal(shape, stddev = 0.1 ) return tf.Variable(initial) def bias_variable(shape): initial = tf.constant( 0.1 , shape = shape) return tf.Variable(initial) # 創(chuàng)建卷積層、池化層,以便重復(fù)使用 def conv2d(x, W): return tf.nn.conv2d(x, W, strides = [ 1 , 1 , 1 , 1 ], padding = 'SAME' ) def max_pool(x): return tf.nn.max_pool(x, ksize = [ 1 , 2 , 2 , 1 ], strides = [ 1 , 2 , 2 , 1 ], padding = 'SAME' ) # 定義輸入的placeholder x = tf.placeholder(tf.float32, [ None , 784 ]) y_ = tf.placeholder(tf.float32, [ None , 10 ]) x_image = tf.reshape(x, [ - 1 , 28 , 28 , 1 ]) # 定義第一個(gè)卷積層 W_conv1 = weight_variable([ 5 , 5 , 1 , 32 ]) b_conv1 = bias_variable([ 32 ]) h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) h_pool1 = max_pool(h_conv1) # 定義第二個(gè)卷積層 W_conv2 = weight_variable([ 5 , 5 , 32 , 64 ]) b_conv2 = bias_variable([ 64 ]) h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) h_pool2 = max_pool(h_conv2) # 定義全連接層。由于第二個(gè)卷積層輸出的tensor是7*7*64,我們使用tf.reshape函數(shù)對(duì)其進(jìn)行變形 W_fc1 = weight_variable([ 7 * 7 * 64 , 1024 ]) b_fc1 = bias_variable([ 1024 ]) h_pool2_flat = tf.reshape(h_pool2, [ - 1 , 7 * 7 * 64 ]) h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) # 為了減輕過(guò)擬合,下面使用一個(gè)Dropout層。通過(guò)一個(gè)placeholder傳入keep_prob比率來(lái)控制的。在訓(xùn)練時(shí),我們隨機(jī)丟棄一部分節(jié)點(diǎn) # 的數(shù)據(jù)來(lái)減輕過(guò)擬合,預(yù)測(cè)時(shí)則保留全部數(shù)據(jù)來(lái)追求最好的預(yù)測(cè)性能。 keep_prob = tf.placeholder(dtype = tf.float32) h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 最后我們將Dropout層的輸出連接一個(gè)Softmax層,得到最后的概率輸出 W_fc2 = weight_variable([ 1024 , 10 ]) b_fc2 = bias_variable([ 10 ]) y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) # 定義損失函數(shù)為cross entropy和優(yōu)化器 cross_entropy = tf.reduce_mean( - tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices = [ 1 ])) train_step = tf.train.AdamOptimizer( 1e - 4 ).minimize(cross_entropy) # 定義評(píng)測(cè)準(zhǔn)確率的操作 correct_prediction = tf.equal(tf.argmax(y_conv, 1 ), tf.argmax(y_, 1 )) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 下面開始訓(xùn)練 tf.global_variables_initializer().run() for i in range ( 20000 ): batch = mnist.train.next_batch( 50 ) if i % 100 = = 0 : train_accuracy = accuracy. eval (feed_dict = {x: batch[ 0 ], y_: batch[ 1 ], keep_prob: 1.0 }) print ( "Step %d, training accuracy %g" % (i, train_accuracy)) train_step.run(feed_dict = {x: batch[ 0 ], y_: batch[ 1 ], keep_prob: 0.5 }) print ( "test accuracy %g" % accuracy. eval (feed_dict = {x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0 })) # 載入MNIST數(shù)據(jù)集,并創(chuàng)建默認(rèn)的Interactive Session。 mnist = input_data.read_data_sets( "MNIST_data/" , one_hot = True ) sess = tf.InteractiveSession() # 創(chuàng)建權(quán)重和偏置,以便重復(fù)使用。我們需要給權(quán)重制造一些隨機(jī)的噪聲來(lái)打破完全對(duì)稱,比如截?cái)嗟恼龖B(tài)分布噪聲,標(biāo)準(zhǔn)差設(shè)為0.1 def weight_variable(shape): initial = tf.truncated_normal(shape, stddev = 0.1 ) return tf.Variable(initial) def bias_variable(shape): initial = tf.constant( 0.1 , shape = shape) return tf.Variable(initial) # 創(chuàng)建卷積層、池化層,以便重復(fù)使用 def conv2d(x, W): return tf.nn.conv2d(x, W, strides = [ 1 , 1 , 1 , 1 ], padding = 'SAME' ) def max_pool(x): return tf.nn.max_pool(x, ksize = [ 1 , 2 , 2 , 1 ], strides = [ 1 , 2 , 2 , 1 ], padding = 'SAME' ) # 定義輸入的placeholder x = tf.placeholder(tf.float32, [ None , 784 ]) y_ = tf.placeholder(tf.float32, [ None , 10 ]) x_image = tf.reshape(x, [ - 1 , 28 , 28 , 1 ]) # 定義第一個(gè)卷積層 W_conv1 = weight_variable([ 5 , 5 , 1 , 32 ]) b_conv1 = bias_variable([ 32 ]) h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) h_pool1 = max_pool(h_conv1) # 定義第二個(gè)卷積層 W_conv2 = weight_variable([ 5 , 5 , 32 , 64 ]) b_conv2 = bias_variable([ 64 ]) h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) h_pool2 = max_pool(h_conv2) # 定義全連接層。由于第二個(gè)卷積層輸出的tensor是7*7*64,我們使用tf.reshape函數(shù)對(duì)其進(jìn)行變形 W_fc1 = weight_variable([ 7 * 7 * 64 , 1024 ]) b_fc1 = bias_variable([ 1024 ]) h_pool2_flat = tf.reshape(h_pool2, [ - 1 , 7 * 7 * 64 ]) h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) # 為了減輕過(guò)擬合,下面使用一個(gè)Dropout層。通過(guò)一個(gè)placeholder傳入keep_prob比率來(lái)控制的。在訓(xùn)練時(shí),我們隨機(jī)丟棄一部分節(jié)點(diǎn) # 的數(shù)據(jù)來(lái)減輕過(guò)擬合,預(yù)測(cè)時(shí)則保留全部數(shù)據(jù)來(lái)追求最好的預(yù)測(cè)性能。 keep_prob = tf.placeholder(dtype = tf.float32) h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 最后我們將Dropout層的輸出連接一個(gè)Softmax層,得到最后的概率輸出 W_fc2 = weight_variable([ 1024 , 10 ]) b_fc2 = bias_variable([ 10 ]) y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) # 定義損失函數(shù)為cross entropy和優(yōu)化器 cross_entropy = tf.reduce_mean( - tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices = [ 1 ])) train_step = tf.train.AdamOptimizer( 1e - 4 ).minimize(cross_entropy) # 定義評(píng)測(cè)準(zhǔn)確率的操作 correct_prediction = tf.equal(tf.argmax(y_conv, 1 ), tf.argmax(y_, 1 )) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 下面開始訓(xùn)練 tf.global_variables_initializer().run() for i in range ( 20000 ): batch = mnist.train.next_batch( 50 ) if i % 100 = = 0 : train_accuracy = accuracy. eval (feed_dict = {x: batch[ 0 ], y_: batch[ 1 ], keep_prob: 1.0 }) print ( "Step %d, training accuracy %g" % (i, train_accuracy)) train_step.run(feed_dict = {x: batch[ 0 ], y_: batch[ 1 ], keep_prob: 0.5 }) print ( "test accuracy %g" % accuracy. eval (feed_dict = {x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0 })) |
運(yùn)行結(jié)果:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/xjy104165/article/details/78559129