# 六、卷積神經網絡
卷積神經網絡是當前使用的許多最高級模型的一部分。 它們被用于許多領域,但是主要的應用領域是圖像分類和特征檢測領域。
我們將在本章中介紹的主題如下:
* 了解卷積函數和卷積網絡如何工作以及構建它們的主要操作類型
* 將卷積運算應用于圖像數據并學習一些應用于圖像的預處理技術,以提高方法的準確率
* 使用 CNN 的簡單設置對 MNIST 數據集的數字進行分類
* 使用應用于彩色圖像的 CNN 模型對 CIFAR 數據集的真實圖像進行分類
# 卷積神經網絡的起源
新認知加速器是福島教授在 1980 年發表的論文中介紹的卷積網絡的前身,并且是一種能容忍位移和變形的自組織神經網絡。
這個想法在 1986 年再次出現在原始反向傳播論文的書本中,并在 1988 年被用于語音識別中的時間信號。
最初的設計后來在 1998 年通過 LeCun 的論文將基于梯度的學習應用于文檔識別中進行了審查和改進,該論文提出了 LeNet-5 網絡,該網絡能夠對手寫數字進行分類。 與其他現有模型相比,該模型顯示出更高的表現,尤其是在 SVM 的幾種變體上,SVM 是出版年份中表現最高的操作之一。
然后在 2003 年對該論文進行了概括,論文為圖像解釋的層次神經網絡。 但是,總的來說,我們將使用 LeCun 的 LeNet 論文架構的近似表示。
## 卷積入門
為了理解在這些類型的操作中應用于信息的操作,我們將從研究卷積函數的起源開始,然后我們將解釋如何將此概念應用于信息。
為了開始跟蹤操作的歷史發展,我們將開始研究連續域中的卷積。
### 連續卷積
此操作的最初使用來自 18 世紀,并且可以在原始應用上下文中表示為將兩個按時出現的特征混合在一起的操作。
從數學上講,它可以定義如下:

當我們嘗試將此操作概念化為算法時,可以在以下步驟中解釋前面的方程式:
1. 翻轉信號:這是變量的`(-τ)`部分。
2. 移動它:這是由`g(τ)`的`t`求和因子給出的。
3. 乘以:這是`f`和`g`的乘積。
4. 積分結果曲線:這是較不直觀的部分,因為每個瞬時值都是積分的結果。

### 離散卷積
卷積可以轉換為離散域,并以離散項描述離散函數:

## 卷積核
在離散域中應用卷積的概念時,經常會使用內核。
內核可以定義為`nxm`維矩陣,通常是在所有維上長的幾個元素,通常是`m = n`。
卷積運算包括將對應的像素與內核相乘,一次一個像素,然后將這些值相加,以便將該值分配給中央像素。
然后將應用相同的操作,將卷積矩陣向左移動,直到訪問了所有可能的像素。
在以下示例中,我們有一個包含許多像素的圖像和一個大小為`3x3`的內核,這在圖像處理中特別常見:

## 卷積運算的解釋
回顧了連續場和離散場的卷積運算的主要特征之后,現在讓我們看一下該運算在機器學習中的用途。
卷積核突出或隱藏模式。 根據受過訓練的(或在示例中,手動設置)參數,我們可以開始發現參數,例如不同尺寸的方向和邊緣。 我們也可能通過諸如模糊內核之類的方法覆蓋一些不必要的細節或離群值。
正如 LeCun 在他的基礎論文中所述:
> 卷積網絡可以看作是合成自己的特征提取器。
卷積神經網絡的這一特性是相對于以前的數據處理技術的主要優勢。 我們可以非常靈活地確定已確定數據集的主要組成部分,并通過這些基本構件的組合來表示其他樣本。
## 在 TensorFlow 中應用卷積
TensorFlow 提供了多種卷積方法。 規范形式通過`conv2d`操作應用。 讓我們看一下此操作的用法:
```py
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu, data_format, name=None)
```
我們使用的參數如下:
* `input`:這是將對其應用操作的原始張量。 它具有四個維度的確定格式,默認維度順序如下所示。
* `[batch, in_height, in_width, in_channels]`:批量是允許您擁有圖像集合的維度。 順序稱為`NHWC`。 另一個選項是`NCWH`。
例如,單個`100x100` 像素彩色圖像將具有以下形狀:
```py
[1,100,100,3]
```
* `filter`:這是代表`kernel`或`filter`的張量。 它有一個非常通用的方法:
```py
[filter_height, filter_width, in_channels, out_channels]
```
* `strides`:這是四個`int`張量數據類型的列表,這些數據類型指示每個維度的滑動窗口。
* `Padding`:可以是`SAME`或`VALID`。 `SAME`將嘗試保留初始張量尺寸,但`VALID`將允許其增長,以防計算輸出大小和填充。
* `use_cudnn_on_gpu`:這指示是否使用`CUDA GPU CNN`庫來加速計算。
* `data_format`:這指定數據的組織順序(`NHWC`或`NCWH`)。
### 其他卷積運算
TensorFlow 提供了多種應用卷積的方法,如下所示:
* `tf.nn.conv2d_transpose`:這適用于`conv2d`的轉置(梯度),并用于反卷積網絡中
* `tf.nn.conv1d`:給定 3D 輸入和`filter`張量,這將執行 1D 卷積
* `tf.nn.conv3d`:給定 5D 輸入和`filter`張量,這將執行 3D 卷積
### 示例代碼 -- 將卷積應用于灰度圖像
在此示例代碼中,我們將讀取 GIF 格式的灰度圖像,該圖像將生成一個三通道張量,但每個像素具有相同的 RGB 值。 然后,我們將張量轉換為真實的灰度矩陣,應用`kernel`,并在 JPEG 格式的輸出圖像中檢索結果。
### 注意
請注意,您可以調整`kernel`變量中的參數以觀察圖像變化的影響。
以下是示例代碼:
```py
import tensorflow as tf
#Generate the filename queue, and read the gif files contents
filename_queue = tf.train.string_input_producer(tf.train.match_filenames_once("data/test.gif"))
reader = tf.WholeFileReader()
key, value = reader.read(filename_queue)
image=tf.image.decode_gif(value)
#Define the kernel parameters
kernel=tf.constant(
[
[[[-1.]],[[-1.]],[[-1.]]],
[[[-1.]],[[8.]],[[-1.]]],
[[[-1.]],[[-1.]],[[-1.]]]
]
)
#Define the train coordinator
coord = tf.train.Coordinator()
with tf.Session() as sess:
tf.initialize_all_variables().run()
threads = tf.train.start_queue_runners(coord=coord)
#Get first image
image_tensor = tf.image.rgb_to_grayscale(sess.run([image])[0])
#apply convolution, preserving the image size
imagen_convoluted_tensor=tf.nn.conv2d(tf.cast(image_tensor, tf.float32),kernel,[1,1,1,1],"SAME")
#Prepare to save the convolution option
file=open ("blur2.jpg", "wb+")
#Cast to uint8 (0..255), previous scalation, because the convolution could alter the scale of the final image
out=tf.image.encode_jpeg(tf.reshape(tf.cast(imagen_convoluted_tensor/tf.reduce_max(imagen_convoluted_tensor)*255.,tf.uint8), tf.shape(imagen_convoluted_tensor.eval()[0]).eval()))
file.close()
coord.request_stop()
coord.join(threads)
```
### 示例核的結果
在下圖中,您可以觀察到參數的變化如何影響圖像的結果。 第一張圖片是原始圖片。
濾鏡類型為從左到右,從上到下模糊,底部 Sobel(從上到下搜索邊的一種濾鏡),浮雕(突出顯示拐角邊)和輪廓(概述圖像的外部邊界)。

## 二次采樣操作 -- 池化
在 TensorFlow 中通過稱為池化的操作執行二次采樣操作。 這個想法是應用一個(大小不一的)內核并提取內核覆蓋的元素之一,其中`max_pool`和`avg_pool`是最著名的一些元素,它們僅獲得最大和平均值。 應用內核的元素。
在下圖中,您可以看到將`2x2`內核應用于單通道`16x16`矩陣的操作。 它只是保持其覆蓋的內部區域的最大值。

可以進行的合并操作的類型也有所不同。 例如,在 LeCun 的論文中,應用于原始像素的運算必須將它們乘以一個可訓練的參數,并添加一個額外的可訓練`bias`。
### 下采樣層的屬性
二次采樣層的主要目的與卷積層的目的大致相同。 減少信息的數量和復雜性,同時保留最重要的信息元素。 它們構建了基礎信息的緊湊表示。
### 不變性
下采樣層還允許將信息的重要部分從數據的詳細表示轉換為更簡單的表示。 通過在圖像上滑動濾鏡,我們將檢測到的特征轉換為更重要的圖像部分,最終達到 1 像素的圖像,該特征由該像素值表示。 相反,此屬性也可能導致模型丟失特征檢測的局部性。
### 下采樣層實現的表現
下采樣層的實現要快得多,因為未使用的數據元素的消除標準非常簡單。 通常,它只需要進行幾個比較。
### 在 TensorFlow 中應用池化操作
首先,我們將分析最常用的`pool`操作`max_pool`。 它具有以下簽名:
```py
tf.nn.max_pool(value, ksize, strides, padding, data_format, name)
```
此方法類似于`conv2d`,參數如下:
* `value`:這是`float32`元素和形狀(批量長度,高度,寬度,通道)的 4D 張量。
* `ksize`:這是一個整數列表,代表每個維度上的窗口大小
* `strides`:這是在每個尺寸上移動窗口的步驟
* `data_format`:設置數據尺寸
* `ordering`:`NHWC`或`NCHW`
* `padding`:`VALID`或`SAME`
### 其他池化操作
* `tf.nn.avg_pool`:這將返回每個窗口的平均值的縮減張量
* `tf.nn.max_pool_with_argmax`:這將返回`max_pool`張量和具有`max_value`的平展索引的張量
* `tf.nn.avg_pool3d`:此操作使用類似立方的窗口執行`avg_pool`操作; 輸入有額外的深度
* `tf.nn.max_pool3d`:執行與(`...`)相同的操作,但應用`max`操作
### 示例代碼
在以下示例代碼中,我們將采用原始格式:
```py
import tensorflow as tf
#Generate the filename queue, and read the gif files contents
filename_queue = tf.train.string_input_producer(tf.train.match_filenames_once("data/test.gif"))
reader = tf.WholeFileReader()
key, value = reader.read(filename_queue)
image=tf.image.decode_gif(value)
#Define the coordinator
coord = tf.train.Coordinator()
def normalize_and_encode (img_tensor):
image_dimensions = tf.shape(img_tensor.eval()[0]).eval()
return tf.image.encode_jpeg(tf.reshape(tf.cast(img_tensor, tf.uint8), image_dimensions))
with tf.Session() as sess:
maxfile=open ("maxpool.jpg", "wb+")
avgfile=open ("avgpool.jpg", "wb+")
tf.initialize_all_variables().run()
threads = tf.train.start_queue_runners(coord=coord)
image_tensor = tf.image.rgb_to_grayscale(sess.run([image])[0])
maxed_tensor=tf.nn.avg_pool(tf.cast(image_tensor, tf.float32),[1,2,2,1],[1,2,2,1],"SAME")
averaged_tensor=tf.nn.avg_pool(tf.cast(image_tensor, tf.float32),[1,2,2,1],[1,2,2,1],"SAME")
maxfile.write(normalize_and_encode(maxed_tensor).eval())
avgfile.write(normalize_and_encode(averaged_tensor).eval())
coord.request_stop()
maxfile.close()
avgfile.close()
coord.join(threads)
```
在下圖中,我們首先看到原始圖像和縮小尺寸的圖像,然后是`max_pool`,然后是`avg_pool`。 如您所見,這兩個圖像看起來是相等的,但是如果我們繪制它們之間的圖像差異,我們會發現,如果取最大值而不是均值(始終小于或等于均值),則會有細微的差異。

## 提高效率 - 丟棄操作
在大型神經網絡訓練過程中觀察到的主要優點之一是過擬合,即為訓練數據生成非常好的近似值,但為單點之間的區域發出噪聲。
在過擬合的情況下,該模型專門針對訓練數據集進行了調整,因此對于一般化將無用。 因此,盡管它在訓練集上表現良好,但是由于缺乏通用性,因此它在測試數據集和后續測試中的表現很差。
因此,引入了丟棄操作。 此操作將某些隨機選擇的權重的值減小為零,從而使后續層為零。
這種方法的主要優點是,它避免了一層中的所有神經元同步優化其權重。 隨機分組進行的這種適應避免了所有神經元都收斂到相同的目標,從而使適應的權重解相關。
在丟棄應用中發現的第二個屬性是隱藏單元的激活變得稀疏,這也是理想的特性。
在下圖中,我們表示了原始的完全連接的多層神經網絡以及具有鏈接的丟棄的關聯網絡:

### 在 TensorFlow 中應用丟棄操作
為了應用`dropout`操作,TensorFlows 實現了`tf.nn.dropout`方法,其工作方式如下:
```py
tf.nn.dropout (x, keep_prob, noise_shape, seed, name)
```
參數如下:
* `x`:這是原始張量
* `keep_prob`:這是保留神經元的概率以及乘以其余節點的因子
* `noise_shape`:這是一個四元素列表,用于確定尺寸是否將獨立應用歸零
#### 示例代碼
在此樣本中,我們將對樣本向量應用丟棄操作。 丟棄還可以將丟棄傳輸到所有與架構相關的單元。
在下面的示例中,您可以看到將丟棄應用于`x`變量的結果,其歸零概率為 0.5,并且在未發生這種情況的情況下,值加倍(乘以`1 / 1.5`,丟棄概率):

顯然,大約一半的輸入已被清零(選擇此示例是為了顯示概率不會總是給出預期的四個零)。
可能使您感到驚訝的一個因素是應用于非放置元素的比例因子。 這項技術用于維護相同的網絡,并在訓練時將`keep_prob`設為 1,將其恢復到原始架構。
## 卷積層的構建方法
為了構建卷積神經網絡層,存在一些通用的實踐和方法,可以在構建深度神經網絡的方式中將其視為準規范。
為了促進卷積層的構建,我們將看一些簡單的實用函數。
### 卷積層
這是卷積層的一個示例,它連接一個卷積,添加一個`bias`參數總和,最后返回我們為整個層選擇的激活函數(在這種情況下,`relu`操作很常見)。
```py
def conv_layer(x_in, weights, bias, strides=1):
x = tf.nn.conv2d(x, weights, strides=[1, strides, strides, 1], padding='SAME')
x = tf.nn.bias_add(x_in, bias)
return tf.nn.relu(x)
```
### 下采樣層
通常可以通過維持層的初始參數,通過`max_pool`操作來表示下采樣層:
```py
def maxpool2d(x, k=2):
return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
padding='SAME')
```
# 示例 1 -- MNIST 數字分類
在本節中,我們將首次使用最知名的模式識別數據集中的一個。 它最初是為了訓練神經網絡來對支票上的手寫數字進行字符識別而開發的。
原始數據集有 60,000 個不同的數字用于訓練和 10,000 個用于測試,并且在使用時是原始使用的數據集的子集。
在下圖中,我們顯示了 LeNet-5 架構,這是有關該問題發布的第一個著名的卷積架構。
在這里,您可以看到層的尺寸和最后的結果表示:

## 數據集說明和加載
MNIST 是易于理解和閱讀但難以掌握的數據集。 當前,有很多好的算法可以解決這個問題。 在我們的案例中,我們將尋求建立一個足夠好的模型,以使其與 10% 的隨機結果相去甚遠。
為了訪問 MNIST 數據集,我們將使用為 TensorFlow 的 MNIST 教程開發的一些實用工具類。
這兩條線是我們擁有完整的 MNIST 數據集所需的全部工作。
在下圖中,我們可以看到數據集對象的數據結構的近似值:

通過此代碼,我們將打開并探索 MNIST 數據集:

要打印字符(在 Jupyter 筆記本中),我們將重塑表示圖像的線性方式,形成`28x28`的方矩陣,分配灰度色圖,并使用以下行繪制所得的數據結構:
```py
plt.imshow(mnist.train.images[0].reshape((28, 28), order='C'), cmap='Greys', interpolation='nearest')
```
下圖顯示了此行應用于不同數據集元素的結果:

## 數據集預處理
在此示例中,我們將不進行任何預處理; 我們只會提到,僅通過使用線性變換的現有樣本(例如平移,旋轉和傾斜的樣本)擴展數據集示例,就可以實現更好的分類評分。
## 模型架構
在這里,我們將研究為該特定架構選擇的不同層。
它開始生成帶有名稱的權重字典:
```py
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
'out': tf.Variable(tf.random_normal([1024, n_classes]))
```
對于每個權重,還將添加一個`bias`以說明常數。
然后我們定義連接的層,一層又一層地集成:
```py
conv_layer_1 = conv2d(x_in, weights['wc1'], biases['bc1'])
conv_layer_1 = subsampling(conv_layer_1, k=2)
conv_layer_2 = conv2d(conv_layer_1, weights['wc2'], biases['bc2'])
conv_layer_2 = subsampling(conv_layer_2, k=2)
fully_connected_layer = tf.reshape(conv_layer_2, [-1, weights['wd1'].get_shape().as_list()[0]])
fully_connected_layer = tf.add(tf.matmul(fully_connected_layer, weights['wd1']), biases['bd1'])
fully_connected_layer = tf.nn.relu(fully_connected_layer)
fully_connected_layer = tf.nn.dropout(fully_connected_layer, dropout)
prediction_output = tf.add(tf.matmul(fully_connected_layer, weights['out']), biases['out'])
```
## 損失函數說明
損失函數將是交叉熵誤差函數的平均值,該函數通常是用于分類的 softmax 函數。
```py
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
```
## 損失函數優化器
對于此示例,我們將使用改進的`AdamOptimizer`,其學習率可配置,我們將其定義為 0.001。
```py
optimizer = tf.train.AdamOptimizer
(learning_rate=learning_rate).minimize(cost)
```
## 準確率測試
準確率測試計算標簽和結果之間比較的平均值,以獲得`0`和`1`之間的值。
```py
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
```
## 結果說明
此示例的結果簡潔明了,并且假設我們僅訓練 10,000 個樣本,則準確率不是一流的,但與十分之一的隨機采樣結果明顯分開:
```py
Optimization Finished!
Testing Accuracy: 0.382812
```
## 完整源代碼
以下是源代碼:
```py
import tensorflow as tf
%matplotlib inline
import matplotlib.pyplot as plt
# Import MINST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)
# Parameters
learning_rate = 0.001
training_iters = 2000
batch_size = 128
display_step = 10
# Network Parameters
n_input = 784 # MNIST data input (img shape: 28*28)
n_classes = 10 # MNIST total classes (0-9 digits)
dropout = 0.75 # Dropout, probability to keep units
# tf Graph input
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])
keep_prob = tf.placeholder(tf.float32) #dropout (keep probability)
#plt.imshow(X_train[1202].reshape((20, 20), order='F'), cmap='Greys', interpolation='nearest')
# Create some wrappers for simplicity
def conv2d(x, W, b, strides=1):
# Conv2D wrapper, with bias and relu activation
x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
x = tf.nn.bias_add(x, b)
return tf.nn.relu(x)
def maxpool2d(x, k=2):
# MaxPool2D wrapper
return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
padding='SAME')
# Create model
def conv_net(x, weights, biases, dropout):
# Reshape input picture
x = tf.reshape(x, shape=[-1, 28, 28, 1])
# Convolution Layer
conv1 = conv2d(x, weights['wc1'], biases['bc1'])
# Max Pooling (down-sampling)
conv1 = maxpool2d(conv1, k=2)
# Convolution Layer
conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])
# Max Pooling (down-sampling)
conv2 = maxpool2d(conv2, k=2)
# Fully connected layer
# Reshape conv2 output to fit fully connected layer input
fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]])
fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])
fc1 = tf.nn.relu(fc1)
# Apply Dropout
fc1 = tf.nn.dropout(fc1, dropout)
# Output, class prediction
out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])
return out
# Store layers weight & bias
weights = {
# 5x5 conv, 1 input, 32 outputs
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
# 5x5 conv, 32 inputs, 64 outputs
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
# fully connected, 7*7*64 inputs, 1024 outputs
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
# 1024 inputs, 10 outputs (class prediction)
'out': tf.Variable(tf.random_normal([1024, n_classes]))
}
biases = {
'bc1': tf.Variable(tf.random_normal([32])),
'bc2': tf.Variable(tf.random_normal([64])),
'bd1': tf.Variable(tf.random_normal([1024])),
'out': tf.Variable(tf.random_normal([n_classes]))
}
# Construct model
pred = conv_net(x, weights, biases, keep_prob)
# Define loss and optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
# Evaluate model
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
# Initializing the variables
init = tf.initialize_all_variables()
# Launch the graph
with tf.Session() as sess:
sess.run(init)
step = 1
# Keep training until reach max iterations
while step * batch_size < training_iters:
batch_x, batch_y = mnist.train.next_batch(batch_size)
test = batch_x[0]
fig = plt.figure()
plt.imshow(test.reshape((28, 28), order='C'), cmap='Greys',
interpolation='nearest')
print (weights['wc1'].eval()[0])
plt.imshow(weights['wc1'].eval()[0][0].reshape(4, 8), cmap='Greys', interpolation='nearest')
# Run optimization op (backprop)
sess.run(optimizer, feed_dict={x: batch_x, y: batch_y,
keep_prob: dropout})
if step % display_step == 0:
# Calculate batch loss and accuracy
loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x,
y: batch_y,
keep_prob: 1.})
print "Iter " + str(step*batch_size) + ", Minibatch Loss= " + \
"{:.6f}".format(loss) + ", Training Accuracy= " + \
"{:.5f}".format(acc)
step += 1
print "Optimization Finished!"
# Calculate accuracy for 256 mnist test images
print "Testing Accuracy:", \
sess.run(accuracy, feed_dict={x: mnist.test.images[:256],
y: mnist.test.labels[:256],
keep_prob: 1.})
```
# 示例 2 -- CIFAR10 數據集和圖像分類
在此示例中,我們將研究圖像理解中使用最廣泛的數據集之一,該數據集用作簡單但通用的基準。 在此示例中,我們將構建一個簡單的 CNN 模型,以了解解決此類分類問題所需的一般計算結構。
## 數據集說明和加載
該數據集包含 40,000 個`32x32`像素的圖像,代表以下類別:飛機,汽車,鳥類,貓,鹿,狗,青蛙,馬,船和卡車。 在此示例中,我們將只處理 10,000 個圖像包中的第一個。
以下是您可以在數據集中找到的一些圖像示例:

## 數據集預處理
我們必須對原始數據集進行一些數據結構調整,首先將其轉換為`[10000, 3, 32, 32]`多維數組,然后將通道維移動到最后一個順序。
```py
datadir='data/cifar-10-batches-bin/'
plt.ion()
G = glob.glob (datadir + '*.bin')
A = np.fromfile(G[0],dtype=np.uint8).reshape([10000,3073])
labels = A [:,0]
images = A [:,1:].reshape([10000,3,32,32]).transpose (0,2,3,1)
plt.imshow(images[14])
print labels[11]
images_unroll = A [:,1:]
```
## 模型架構
在這里,我們將定義我們的建模函數,該函數是一系列卷積和池化操作,并使用最終的平坦層和邏輯回歸來確定當前樣本的分類概率。
```py
def conv_model (X, y):
X= tf. reshape(X, [-1, 32, 32, 3])
with tf.variable_scope('conv_layer1'):
h_conv1=tf.contrib.layers.conv2d(X, num_outputs=16, kernel_size=[5,5], activation_fn=tf.nn.relu)#print (h_conv1)
h_pool1=max_pool_2x2(h_conv1)#print (h_pool1)
with tf.variable_scope('conv_layer2'):
h_conv2=tf.contrib.layers.conv2d(h_pool1, num_outputs=16, kernel_size=[5,5], activation_fn=tf.nn.relu)
#print (h_conv2)
h_pool2=max_pool_2x2(h_conv2)
h_pool2_flat = tf.reshape(h_pool2, [-1,8*8*16 ])
h_fc1 = tf.contrib.layers.stack(h_pool2_flat, tf.contrib.layers.fully_connected ,[96,48], activation_fn=tf.nn.relu )
return skflow.models.logistic_regression(h_fc1,y)
```
## 損失函數說明和優化器
以下是函數:
```py
classifier = skflow.TensorFlowEstimator(model_fn=conv_model, n_classes=10, batch_size=100, steps=2000, learning_rate=0.01)
```
### 訓練和準確率測試
使用以下兩個命令,我們開始使用圖像集對模型進行擬合并生成訓練后模型的評分:
```py
%time classifier.fit(images, labels, logdir='/tmp/cnn_train/')
%time score =metrics.accuracy_score(labels, classifier.predict(images))
```
## 結果描述
結果如下:
| 參數 | 結果 1 | 結果 2 |
| --- | --- | --- |
| CPU 時間 | 用戶 35 分鐘 6 秒 | 用戶 39.8 秒 |
| 系統 | 1 分鐘 50 秒 | 7.19 秒 |
| 總時間 | 36 分鐘 57 秒 | 47 秒 |
| 墻上時間 | 25 分鐘 3 秒 | 32.5 秒 |
| 準確率 | 0.612200 | |
### 完整源代碼
以下是完整的源代碼:
```py
import glob
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import tensorflow.contrib.learn as skflow
from sklearn import metrics
from tensorflow.contrib import learn
datadir='data/cifar-10-batches-bin/'
plt.ion()
G = glob.glob (datadir + '*.bin')
A = np.fromfile(G[0],dtype=np.uint8).reshape([10000,3073])
labels = A [:,0]
images = A [:,1:].reshape([10000,3,32,32]).transpose (0,2,3,1)
plt.imshow(images[15])
print labels[11]
images_unroll = A [:,1:]
def max_pool_2x2(tensor_in):
return tf.nn.max_pool(tensor_in, ksize= [1,2,2,1], strides= [1,2,2,1], padding='SAME')
def conv_model (X, y):
X= tf. reshape(X, [-1, 32, 32, 3])
with tf.variable_scope('conv_layer1'):
h_conv1=tf.contrib.layers.conv2d(X, num_outputs=16, kernel_size=[5,5], activation_fn=tf.nn.relu)#print (h_conv1)
h_pool1=max_pool_2x2(h_conv1)#print (h_pool1)
with tf.variable_scope('conv_layer2'):
h_conv2=tf.contrib.layers.conv2d(h_pool1, num_outputs=16, kernel_size=[5,5], activation_fn=tf.nn.relu)
#print (h_conv2)
h_pool2=max_pool_2x2(h_conv2)
h_pool2_flat = tf.reshape(h_pool2, [-1,8*8*16 ])
h_fc1 = tf.contrib.layers.stack(h_pool2_flat, tf.contrib.layers.fully_connected ,[96,48], activation_fn=tf.nn.relu )
return skflow.models.logistic_regression(h_fc1,y)
images = np.array(images,dtype=np.float32)
classifier = skflow.TensorFlowEstimator(model_fn=conv_model, n_classes=10, batch_size=100, steps=2000, learning_rate=0.01)
%time classifier.fit(images, labels, logdir='/tmp/cnn_train/')
%time score =metrics.accuracy_score(labels, classifier.predict(images))
```
# 總結
在本章中,我們了解了最先進的神經網絡架構的組成部分之一:卷積神經網絡。 使用此新工具,我們可以處理更復雜的數據集和概念抽象,因此我們將能夠了解最新的模型。
在下一章中,我們將使用另一種新形式的神經網絡以及更新的神經網絡架構的一部分:循環神經網絡。
- TensorFlow 1.x 深度學習秘籍
- 零、前言
- 一、TensorFlow 簡介
- 二、回歸
- 三、神經網絡:感知器
- 四、卷積神經網絡
- 五、高級卷積神經網絡
- 六、循環神經網絡
- 七、無監督學習
- 八、自編碼器
- 九、強化學習
- 十、移動計算
- 十一、生成模型和 CapsNet
- 十二、分布式 TensorFlow 和云深度學習
- 十三、AutoML 和學習如何學習(元學習)
- 十四、TensorFlow 處理單元
- 使用 TensorFlow 構建機器學習項目中文版
- 一、探索和轉換數據
- 二、聚類
- 三、線性回歸
- 四、邏輯回歸
- 五、簡單的前饋神經網絡
- 六、卷積神經網絡
- 七、循環神經網絡和 LSTM
- 八、深度神經網絡
- 九、大規模運行模型 -- GPU 和服務
- 十、庫安裝和其他提示
- TensorFlow 深度學習中文第二版
- 一、人工神經網絡
- 二、TensorFlow v1.6 的新功能是什么?
- 三、實現前饋神經網絡
- 四、CNN 實戰
- 五、使用 TensorFlow 實現自編碼器
- 六、RNN 和梯度消失或爆炸問題
- 七、TensorFlow GPU 配置
- 八、TFLearn
- 九、使用協同過濾的電影推薦
- 十、OpenAI Gym
- TensorFlow 深度學習實戰指南中文版
- 一、入門
- 二、深度神經網絡
- 三、卷積神經網絡
- 四、循環神經網絡介紹
- 五、總結
- 精通 TensorFlow 1.x
- 一、TensorFlow 101
- 二、TensorFlow 的高級庫
- 三、Keras 101
- 四、TensorFlow 中的經典機器學習
- 五、TensorFlow 和 Keras 中的神經網絡和 MLP
- 六、TensorFlow 和 Keras 中的 RNN
- 七、TensorFlow 和 Keras 中的用于時間序列數據的 RNN
- 八、TensorFlow 和 Keras 中的用于文本數據的 RNN
- 九、TensorFlow 和 Keras 中的 CNN
- 十、TensorFlow 和 Keras 中的自編碼器
- 十一、TF 服務:生產中的 TensorFlow 模型
- 十二、遷移學習和預訓練模型
- 十三、深度強化學習
- 十四、生成對抗網絡
- 十五、TensorFlow 集群的分布式模型
- 十六、移動和嵌入式平臺上的 TensorFlow 模型
- 十七、R 中的 TensorFlow 和 Keras
- 十八、調試 TensorFlow 模型
- 十九、張量處理單元
- TensorFlow 機器學習秘籍中文第二版
- 一、TensorFlow 入門
- 二、TensorFlow 的方式
- 三、線性回歸
- 四、支持向量機
- 五、最近鄰方法
- 六、神經網絡
- 七、自然語言處理
- 八、卷積神經網絡
- 九、循環神經網絡
- 十、將 TensorFlow 投入生產
- 十一、更多 TensorFlow
- 與 TensorFlow 的初次接觸
- 前言
- 1.?TensorFlow 基礎知識
- 2. TensorFlow 中的線性回歸
- 3. TensorFlow 中的聚類
- 4. TensorFlow 中的單層神經網絡
- 5. TensorFlow 中的多層神經網絡
- 6. 并行
- 后記
- TensorFlow 學習指南
- 一、基礎
- 二、線性模型
- 三、學習
- 四、分布式
- TensorFlow Rager 教程
- 一、如何使用 TensorFlow Eager 構建簡單的神經網絡
- 二、在 Eager 模式中使用指標
- 三、如何保存和恢復訓練模型
- 四、文本序列到 TFRecords
- 五、如何將原始圖片數據轉換為 TFRecords
- 六、如何使用 TensorFlow Eager 從 TFRecords 批量讀取數據
- 七、使用 TensorFlow Eager 構建用于情感識別的卷積神經網絡(CNN)
- 八、用于 TensorFlow Eager 序列分類的動態循壞神經網絡
- 九、用于 TensorFlow Eager 時間序列回歸的遞歸神經網絡
- TensorFlow 高效編程
- 圖嵌入綜述:問題,技術與應用
- 一、引言
- 三、圖嵌入的問題設定
- 四、圖嵌入技術
- 基于邊重構的優化問題
- 應用
- 基于深度學習的推薦系統:綜述和新視角
- 引言
- 基于深度學習的推薦:最先進的技術
- 基于卷積神經網絡的推薦
- 關于卷積神經網絡我們理解了什么
- 第1章概論
- 第2章多層網絡
- 2.1.4生成對抗網絡
- 2.2.1最近ConvNets演變中的關鍵架構
- 2.2.2走向ConvNet不變性
- 2.3時空卷積網絡
- 第3章了解ConvNets構建塊
- 3.2整改
- 3.3規范化
- 3.4匯集
- 第四章現狀
- 4.2打開問題
- 參考
- 機器學習超級復習筆記
- Python 遷移學習實用指南
- 零、前言
- 一、機器學習基礎
- 二、深度學習基礎
- 三、了解深度學習架構
- 四、遷移學習基礎
- 五、釋放遷移學習的力量
- 六、圖像識別與分類
- 七、文本文件分類
- 八、音頻事件識別與分類
- 九、DeepDream
- 十、自動圖像字幕生成器
- 十一、圖像著色
- 面向計算機視覺的深度學習
- 零、前言
- 一、入門
- 二、圖像分類
- 三、圖像檢索
- 四、對象檢測
- 五、語義分割
- 六、相似性學習
- 七、圖像字幕
- 八、生成模型
- 九、視頻分類
- 十、部署
- 深度學習快速參考
- 零、前言
- 一、深度學習的基礎
- 二、使用深度學習解決回歸問題
- 三、使用 TensorBoard 監控網絡訓練
- 四、使用深度學習解決二分類問題
- 五、使用 Keras 解決多分類問題
- 六、超參數優化
- 七、從頭開始訓練 CNN
- 八、將預訓練的 CNN 用于遷移學習
- 九、從頭開始訓練 RNN
- 十、使用詞嵌入從頭開始訓練 LSTM
- 十一、訓練 Seq2Seq 模型
- 十二、深度強化學習
- 十三、生成對抗網絡
- TensorFlow 2.0 快速入門指南
- 零、前言
- 第 1 部分:TensorFlow 2.00 Alpha 簡介
- 一、TensorFlow 2 簡介
- 二、Keras:TensorFlow 2 的高級 API
- 三、TensorFlow 2 和 ANN 技術
- 第 2 部分:TensorFlow 2.00 Alpha 中的監督和無監督學習
- 四、TensorFlow 2 和監督機器學習
- 五、TensorFlow 2 和無監督學習
- 第 3 部分:TensorFlow 2.00 Alpha 的神經網絡應用
- 六、使用 TensorFlow 2 識別圖像
- 七、TensorFlow 2 和神經風格遷移
- 八、TensorFlow 2 和循環神經網絡
- 九、TensorFlow 估計器和 TensorFlow HUB
- 十、從 tf1.12 轉換為 tf2
- TensorFlow 入門
- 零、前言
- 一、TensorFlow 基本概念
- 二、TensorFlow 數學運算
- 三、機器學習入門
- 四、神經網絡簡介
- 五、深度學習
- 六、TensorFlow GPU 編程和服務
- TensorFlow 卷積神經網絡實用指南
- 零、前言
- 一、TensorFlow 的設置和介紹
- 二、深度學習和卷積神經網絡
- 三、TensorFlow 中的圖像分類
- 四、目標檢測與分割
- 五、VGG,Inception,ResNet 和 MobileNets
- 六、自編碼器,變分自編碼器和生成對抗網絡
- 七、遷移學習
- 八、機器學習最佳實踐和故障排除
- 九、大規模訓練
- 十、參考文獻