# 二、圖像分類
圖像分類是將整個圖像分類為單個標簽的任務。 例如,給定圖像是狗還是貓,圖像分類任務可以將圖像標記為狗或貓。 在本章中,我們將了解如何使用 TensorFlow 建立這樣的圖像分類模型,并學習提高準確率的技術。
我們將在本章介紹以下主題:
* 在 TensorFlow 中訓練 MNIST 模型
* 在 Keras 中訓練 MNIST 模型
* 其他流行的圖像測試數據集
* 更大的深度學習模型
* 訓練貓與狗的模型
* 開發實際應用
# 在 TensorFlow 中訓練 MNIST 模型
在本節中,我們將了解**混合國家標準技術研究所數據庫**(**MNIST**)的數據,并建立一個簡單的分類模型。 本部分的目的是學習深度學習的通用框架,并將其用于 TensorFlow。 首先,我們將建立一個感知機或邏輯回歸模型。 然后,我們將訓練 CNN 以獲得更高的準確率。 我們還將看到 TensorBoard 如何幫助可視化訓練過程并了解參數。
# MNIST 數據集
`MNIST`數據具有從 0 到 9 的手寫數字,其中 60,000 張用于訓練的圖像和 10,000 張用于測試的圖像。 該數據庫被廣泛用于嘗試使用最少預處理的算法。 這是一個學習機器學習算法的好而緊湊的數據庫。 這是最著名的圖像分類問題數據庫。 這里顯示了一些示例:

從上圖中可以看出,這些手寫字符有 10 個標簽。 將圖像標準化為 28 個圖像像素乘以 28 個圖像像素的尺寸,轉換為灰度尺寸,并居中為固定尺寸。 這是一個很小的數據集,可以在上面快速測試算法。 在下一節中,我們將看到如何加載此數據集以在 TensorFlow 中使用。
# 加載 MNIST 數據
直接從 TensorFlow 加載`MNIST`數據。 請注意,在加載數據時,我們指定單熱編碼作為參數。 標簽存儲為整數,但為了進行訓練,應將其加載為一鍵編碼。 從現在開始,假設讀者正在使用導入了 TensorFlow `tf`的編輯器運行代碼。 以下是要加載`MNIST_data`的代碼段:
```py
from tensorflow.examples.tutorials.mnist import input_data
mnist_data = input_data.read_data_sets('MNIST_data', one_hot=True)
```
對于首次運行,將下載數據,并且可能需要一些時間。 從第二次運行開始,將使用緩存的數據。 在下一節中,我們將構建一個感知機來對數字進行分類。
# 建立一個感知機
感知機是單層神經網絡。 本章介紹的概念(例如,完全連接的層,`activation`函數,隨機梯度下降,`logits`,單熱編碼,softmax 和交叉熵)在這里將很有用。 您將學習如何在 TensorFlow 中定義神經網絡的這些組件,并使用該網絡訓練`MNIST`數據。
# 為輸入數據和目標定義占位符
占位符是傳遞數據的張量。 占位符不是特定值,但將在計算過程中接收輸入。 首先聲明感知機的輸入大小,類數,批量大小以及迭代或批量的總數。 `x_input`是稍后將在其中輸入圖像的輸入。 `y_input`是占位符,將在其中提供一鍵式標簽或目標,如下所示:
```py
input_size = 784 no_classes = 10 batch_size = 100 total_batches = 200 x_input = tf.placeholder(tf.float32, shape=[None, input_size])
y_input = tf.placeholder(tf.float32, shape=[None, no_classes])
```
`shape`參數中的`None`表示它可以是任意大小,因為我們尚未定義批量大小。 第二個參數是`x_input`的張量大小和`y_input`的類數。 根據占位符的類型,我們以浮點數形式發送了數據。 接下來,我們可以定義感知機。
# 定義全連接層的變量
讓我們通過解釋`weights`和`bias`等變量來定義一個簡單的線性分類器或感知機。 這些變量的值將在計算過程中獲悉。 這些也稱為模型參數。 權重變量使用具有輸入大小和類數形狀的正態隨機分布進行初始化。 由于圖像被整形為單個向量,因此輸入大小為`784`。 類的數量是 10,它等于數據集中的位數。 偏差變量還使用大小等于類數的隨機正態分布進行初始化。 `weights`和`bias`定義如下:
```py
weights = tf.Variable(tf.random_normal([input_size, no_classes]))
bias = tf.Variable(tf.random_normal([no_classes]))
```
變量的初始化可以為零,但隨機正態分布可提供穩定的訓練。 然后對輸入進行加權,并加上偏置以產生`logits`,如下所示:
```py
logits = tf.matmul(x_input, weights) + bias
```
必須將感知機產生的`logits`與單熱標簽`y_input`進行比較。 正如在第 1 章“入門”中所了解的,最好使用 softmax 和交叉熵來比較`logits`和單熱標簽。
TensorFlow 的 `tf.nn.softmax_cross_entropy_with_logits` API 為我們做到了。 可以通過平均交叉熵來計算損耗。 然后,交叉熵通過`tf.train.GradientDescentOptimizer`完成的梯度下降優化得到饋送。 優化器接受損失,并以`0.5`的學習率將其最小化。 接下來顯示 softmax,交叉熵,損耗,優化的計算:
```py
softmax_cross_entropy = tf.nn.softmax_cross_entropy_with_logits(
labels=y_input, logits=logits)
loss_operation = tf.reduce_mean(softmax_cross_entropy)
optimiser = tf.train.GradientDescentOptimizer(
learning_rate=0.5).minimize(loss_operation)
```
softmax 和交叉熵是從`tf.nn`包一起計算的,該包還有其他幾種有用的方法。 `tf.train`有幾個優化器,在這里,我們使用原始梯度下降。 您可以訪問 TensorFlow API 文檔以了解其他可選參數。 到目前為止,已定義了占位符,變量和操作,但尚未填充張量。
閱讀 TensorFlow 中提供的[優化器列表](https://www.tensorflow.org/api_guides/python/train)。 Adam 優化器對于計算機視覺應用特別有用。 它通常會收斂得更快,因此我們不需要定義學習率。 有關優化器的理論總結,請訪問[這里](http://ruder.io/optimizing-gradient-descent)。
# 用數據訓練模型
現在,您已經定義了模型和訓練操作。 下一步是開始使用數據訓練模型。 在訓練過程中,計算梯度并更新權重。 變量尚未初始化。 接下來,啟動會話并使用全局變量初始化程序初始化變量:
```py
session = tf.Session()
session.run(tf.global_variables_initializer())
```
本書中的大多數示例都需要前兩行。 假定讀者將在需要的地方使用這兩行。 現在,該圖已準備好填充數據并開始訓練。 通過循環,批量讀取數據并訓練模型。 通過使用所需的張量運行會話來進行模型訓練。 為了使圖更新權重,必須調用優化器:
```py
for batch_no in range(total_batches):
mnist_batch = mnist_data.train.next_batch(batch_size)
_, loss_value = session.run([optimiser, loss_operation], feed_dict={
x_input: mnist_batch[0],
y_input: mnist_batch[1]
})
print(loss_value)
```
`run`方法的第一個參數可以具有一個數組,要求為其提供值的輸出。 我們通過損失是因為打印損失會告訴我們模型是否正在訓練中。 隨著我們將損失降至最低,預計損失將減少。 `feed_dict`是一個 Python 字典,用于直接將輸入和目標標簽提供給占位符。 一旦該循環結束,損耗通常應低于 0.46。 接下來,我們可以通過計算精度來評估模型的工作效果,如下所示:
```py
predictions = tf.argmax(logits, 1)
correct_predictions = tf.equal(predictions, tf.argmax(y_input, 1))
accuracy_operation = tf.reduce_mean(tf.cast(correct_predictions,
tf.float32))
test_images, test_labels = mnist_data.test.images, mnist_data.test.labels
accuracy_value = session.run(accuracy_operation, feed_dict={
x_input: test_images,
y_input: test_labels
})
print('Accuracy : ', accuracy_value)
session.close()
```
該預測應該是最大激活的索引。 應該將其與 MNIST 標簽上的基本事實進行比較,以進行正確的預測。 使用正確預測的平均值計算準確率。 可以通過將測試數據作為提要字典運行會話來評估數據的準確率。 當整個程序運行時,最終應產生 90% 左右的精度。 如果沒有用于訓練和測試的更簡單的 API,該模型的定義似乎太明確了。 此基本定義水平為 TensorFlow 賦予了表達能力。 在下一部分中,我們將看到更高級別的 API。 感知機獲得的精度不是很高,在下一節中,我們將使用具有卷積層的更深的網絡來提高精度。
# 建立多層卷積網絡
在本節中,我們將看到如何在 TensorFlow 中創建多層卷積網絡,并觀察更深的網絡如何提高分類準確率。 我們將使用 TensorFlow 層的 API 定義層,而不是從頭開始定義它們。 最佳實踐方法已根植于這些方法中。 可以從上一節開始導入庫,數據集和占位符。 這次,我們將使用 TensorBoard 可視化訓練過程。 為了可視化變量的統計信息,必須將變量統計信息的值添加到`tf.summary`中。
摘要將被寫入 TensorBoard 可以解釋的文件夾中。 我們定義一個函數來編寫摘要,以便可以使用 TensorBoard 可視化它們:
```py
def add_variable_summary(tf_variable, summary_name):
with tf.name_scope(summary_name + '_summary'):
mean = tf.reduce_mean(tf_variable)
tf.summary.scalar('Mean', mean)
with tf.name_scope('standard_deviation'):
standard_deviation = tf.sqrt(tf.reduce_mean(
tf.square(tf_variable - mean)))
tf.summary.scalar('StandardDeviation', standard_deviation)
tf.summary.scalar('Maximum', tf.reduce_max(tf_variable))
tf.summary.scalar('Minimum', tf.reduce_min(tf_variable))
tf.summary.histogram('Histogram', tf_variable)
```
變量`summary`函數寫入變量的摘要。 摘要中添加了五個統計量:平均值,標準差,最大值,最小值和直方圖。 匯總可以是`scalar`或`histogram`。 當記錄多個變量時,我們將看到如何在 TensorBoard 中可視化這些值。 與以前的模型不同,我們將`MNIST`數據的大小調整為一個正方形,并像二維圖像一樣使用它。 以下是將圖像整形為 28 個圖像像素乘 28 個圖像像素的命令:
```py
x_input_reshape = tf.reshape(x_input, [-1, 28, 28, 1],
name='input_reshape')
```
尺寸`-1`表示批量大小可以是任何數字。 請注意,有一個名為`name`的自變量會在 TensorBoard 圖形中反映出來,以便于理解。 我們將定義一個 2D 卷積層,其中定義了輸入,過濾器,內核和激活。 可以在任何地方調用此方法以獲取更多示例,并且在激活函數必須具有**整流線性單元**(**ReLU**)的情況下很有用。 `convolution`函數層定義如下:
```py
def convolution_layer(input_layer, filters, kernel_size=[3, 3],
activation=tf.nn.relu):
layer = tf.layers.conv2d(
inputs=input_layer,
filters=filters,
kernel_size=kernel_size,
activation=activation,
)
add_variable_summary(layer, 'convolution')
return layer
```
有`kernel_size`和`activation`的默認參數。 匯總將添加到函數中的層,然后返回該層。 每當調用該函數時,都必須將`input_layer`作為參數傳遞。 這個定義將使我們的其他代碼變得簡單而小巧。 以非常相似的方式,我們將為`pooling_layer`定義一個函數,如下所示:
```py
def pooling_layer(input_layer, pool_size=[2, 2], strides=2):
layer = tf.layers.max_pooling2d(
inputs=input_layer,
pool_size=pool_size,
strides=strides
)
add_variable_summary(layer, 'pooling')
return layer
```
該層的`pool_size`和`strides`的默認參數分別為`[2, 2]`和`2`。 這些參數通常工作良好,但可以在必要時進行更改。 也為該層添加了摘要。 接下來,我們將定義一個密集層,如下所示:
```py
def dense_layer(input_layer, units, activation=tf.nn.relu):
layer = tf.layers.dense(
inputs=input_layer,
units=units,
activation=activation
)
add_variable_summary(layer, 'dense')
return layer
```
定義的密集層具有用于激活的默認參數,并且還添加了變量摘要。 `pooling_layer`從卷積層獲取特征圖,并通過使用池大小和跨距進行跳過來將其縮小為一半。 所有這些層均以圖方式連接,并且已被定義。 沒有一個值被初始化。 可以添加另一個卷積層,以將采樣特征從第一卷積層轉換為更好的特征。 合并后,我們可以將激活重塑為線性形式,以便通過密集的層進行饋送:
```py
convolution_layer_1 = convolution_layer(x_input_reshape, 64)
pooling_layer_1 = pooling_layer(convolution_layer_1)
convolution_layer_2 = convolution_layer(pooling_layer_1, 128)
pooling_layer_2 = pooling_layer(convolution_layer_2)
flattened_pool = tf.reshape(pooling_layer_2, [-1, 5 * 5 * 128],
name='flattened_pool')
dense_layer_bottleneck = dense_layer(flattened_pool, 1024)
```
卷積層之間的唯一區別是過濾器的大小。 重要的是,各層之間的尺寸必須適當地變化。 選擇內核和步幅的參數是任意的,這些數字是根據經驗選擇的。 定義了兩個卷積層,然后可以是一個全連接層。 密集層 API 可以采用單個維的任何向量并將其映射到任意數量的隱藏單元,如本例中的`1024`。 隱藏層之后是 ReLU 激活 ,以使其成為非線性計算。 也為此層添加了變量摘要。 接下來是具有退出率的退出層。 保持較高水平將阻止網絡學習。 根據使用的時間,可以將訓練模式設置為`True`和`False`。 在訓練中,我們將其設置為`True`(默認為`False`)。 在計算準確率時,我們將不得不更改此設置。 因此,為此保留了一個布爾值,將在訓練過程中喂入:
```py
dropout_bool = tf.placeholder(tf.bool)
dropout_layer = tf.layers.dropout(
inputs=dense_layer_bottleneck,
rate=0.4,
training=dropout_bool
)
```
丟棄層再次被饋送到一個密實層,這稱為對率。 對率是最后一層,激活會導致類數增加。 激活將針對特定類別(即目標類別)加標,并且最多可以獲得這 10 個激活的最大值:
```py
logits = dense_layer(dropout_layer, no_classes)
```
對率的輸出與上一節中創建的模型非常相似。 現在,對數可以通過 softmax 層傳遞,然后像以前一樣進行交叉熵計算。 在這里,我們添加了一個作用域名稱,以在 TensorBoard 中獲得更好的可視化效果,如下所示:
```py
with tf.name_scope('loss'):
softmax_cross_entropy = tf.nn.softmax_cross_entropy_with_logits(
labels=y_input, logits=logits)
loss_operation = tf.reduce_mean(softmax_cross_entropy, name='loss')
tf.summary.scalar('loss', loss_operation)
```
可以使用`tf.train` API 的方法優化此`loss`函數。 在這里,我們將使用`Adamoptimiser`。 學習率無需定義,并且在大多數情況下效果良好:
```py
with tf.name_scope('optimiser'):
optimiser = tf.train.AdamOptimizer().minimize(loss_operation)
```
像以前一樣計算準確率,但是為正確的預測和準確率計算添加了名稱范圍:
```py
with tf.name_scope('accuracy'):
with tf.name_scope('correct_prediction'):
predictions = tf.argmax(logits, 1)
correct_predictions = tf.equal(predictions, tf.argmax(y_input, 1))
with tf.name_scope('accuracy'):
accuracy_operation = tf.reduce_mean(
tf.cast(correct_predictions, tf.float32))
tf.summary.scalar('accuracy', accuracy_operation)
```
還添加了精度的標量摘要。 下一步是啟動會話并初始化變量,如上一節所述。 這些行在這里不再重復。 必須合并這些摘要,并且必須定義用于編寫訓練和測試摘要的文件:
```py
merged_summary_operation = tf.summary.merge_all()
train_summary_writer = tf.summary.FileWriter('/tmp/train', session.graph)
test_summary_writer = tf.summary.FileWriter('/tmp/test')
```
注意,該圖只用`summary_writer`寫入一次。 訓練與之前非常相似,除了訓練時的精度計算和值被添加到摘要中。 接下來,可以批量加載數據并可以開始訓練:
```py
test_images, test_labels = mnist_data.test.images, mnist_data.test.labels
for batch_no in range(total_batches):
mnist_batch = mnist_data.train.next_batch(batch_size)
train_images, train_labels = mnist_batch[0], mnist_batch[1]
_, merged_summary = session.run([optimiser, merged_summary_operation],
feed_dict={
x_input: train_images,
y_input: train_labels,
dropout_bool: True
})
train_summary_writer.add_summary(merged_summary, batch_no)
if batch_no % 10 == 0:
merged_summary, _ = session.run([merged_summary_operation,
accuracy_operation], feed_dict={
x_input: test_images,
y_input: test_labels,
dropout_bool: False
})
test_summary_writer.add_summary(merged_summary, batch_no)
```
每次迭代都會返回摘要以獲取訓練數據,并將其添加到編寫器中。 對于第十次迭代,將添加測試摘要。 請注意,僅在訓練期間而不是在測試期間啟用丟棄。 我們已經完成了定義以及網絡摘要,可以運行該網絡。 要查看訓練過程,我們可以按照第 1 章,“入門”中所述前往 TensorBoard。
# 在深度學習中使用 TensorBoard
在瀏覽器中打開 TensorBoard 后,轉到圖表選項卡。 應該顯示我們定義并接受訓練的圖。 右鍵單擊節點,我們可以選擇要從主圖中刪除的操作。 對齊后,圖應如下所示:

該圖說明了在先前實例中經過訓練和定義的圖
注意我們定義的所有層的顯示效果如何。 這對于檢查架構的定義非常有用。 圖的方向與所有細節都很好地可視化了。 通過單擊每個節點,您可以看到該節點的詳細信息,例如輸入和輸出張量形狀,如下所示:

這些值可用于交叉檢查層參數的定義。 請注意左下方的圖例,以使自己熟悉此頁面,如下所示:

名稱范圍已分組,可以通過單擊節點上的加號來查看各個組件。 節點按顏色排列。 現在我們可以移至標量頁面。 通過在頁面上四處移動,可以發現精度圖,如下圖所示:

橙色線用于訓練數據,藍色線用于測試數據。 他們大致遵循相同的模式。 表示原始值的亮線稍微少一些,而亮線是平滑的曲線。 可以在 UI 中選擇平滑系數。 測試數據的準確率已達到 97% 以上。 以下是損失摘要中的圖:

在訓練過程中,訓練和測試數據的損失都在穩步減少,這是一個好兆頭。 在訓練過程中將刷新所有摘要的數據,我們可以見證準確率的提高和損失的減少,從而獲得 97.38% 的出色測試精度。
這可以幫助您查看模型是否正在學習并且正在朝著更好的方向發展。 其他匯總(例如最小值,最大值,平均值和標準差)也很有用。 以下是密集層的圖形:

這些摘要對于注意權重的變化很有用。 這些分布也可以顯示為直方圖,如下所示:

這些是對數的權重分布。 這些是 TensorBoard 可能提供的美麗可視化效果,并且在訓練中非常有幫助。 通過使模型更深入,我們可以見證準確率的巨大提高。 在下一節中,我們將看到如何使用 Keras API 訓練相同的模型。 現在您可以看到 TensorBoard 在檢查深度學習模型和訓練過程中的特征。
# 在 Keras 中訓練 MNIST 模型
在本節中,我們將使用通過 `tf.keras` API 定義的與上一節相同的模型。 最好從 TensorFlow 學習 Keras 和`Layer`包,因為它們可以在幾個開源代碼中看到。 本書的目的是使您了解 TensorFlow 的各種產品,以便您可以在其之上構建產品。
“讀取代碼的次數多于寫入代碼的次數。”
牢記前面的引用,向您展示了如何使用各種 AP??I 實現相同的模型。 任何最新算法實現的開放源代碼都將是這些 API 的組合。 接下來,我們將從 Keras 實現開始。
# 準備數據集
Keras 提供`MNIST`數據。 首先,導入`tensorflow`。 然后定義一些常量,例如批量大小,類和周期數。 可以根據計算機上可用的 RAM 選擇批次大小。 批量大小越大,所需的 RAM 越多。 批次大小對準確率的影響很小。 此處的類數等于 10,并且針對不同的問題而有所不同。 周期的數量決定了訓練必須經過整個數據集的次數。 如果在所有周期結束時減少損失,則可以將其設置為較高的數字。 在某些情況下,訓練時間較長可以提高準確率。 現在讓我們看一下創建數據集的步驟:
1. 設置輸入圖像的尺寸,如下所示:
```py
batch_size = 128
no_classes = 10
epochs = 2
image_height, image_width = 28, 28
```
2. 使用 Keras 工具將數據從磁盤加載到內存:
```py
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
```
3. 將向量重塑為圖像格式,并使用給定的代碼定義卷積的輸入尺寸:
```py
x_train = x_train.reshape(x_train.shape[0], image_height, image_width, 1)
x_test = x_test.reshape(x_test.shape[0], image_height, image_width, 1)
input_shape = (image_height, image_width, 1)
```
4. 如下將數據類型轉換為`float`:
```py
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
```
5. 通過減去數據均值來歸一化數據:
```py
x_train /= 255
x_test /= 255
```
6. 將分類標簽轉換為單熱編碼:
```py
y_train = tf.keras.utils.to_categorical(y_train, no_classes)
y_test = tf.keras.utils.to_categorical(y_test, no_classes)
```
這與 TensorFlow 編寫代碼的方式非常不同。 數據已加載到內存中,此處`Placeholders`的概念均不存在。
# 建立模型
在本節中,我們將使用一些卷積層,然后是全連接層,以訓練前面的數據集。 構造一個簡單的順序模型,該模型具有兩個卷積層,然后是池化層,丟棄層和密集層。 順序模型具有`add`方法,可以將多個層堆疊在一起。 第一層具有 64 個過濾器,第二層具有 128 個過濾器。 所有過濾器的內核大小均為 3。 在卷積層之后應用最大池。 卷積層的輸出被展平,并通過丟包連接連接到一對全連接層。
最后一層連接到 softmax,因為這是一個多類分類問題。 以下代碼顯示了如何定義模型:
```py
def simple_cnn(input_shape):
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(
filters=64,
kernel_size=(3, 3),
activation='relu',
input_shape=input_shape
))
model.add(tf.keras.layers.Conv2D(
filters=128,
kernel_size=(3, 3),
activation='relu'
))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Dropout(rate=0.3))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(units=1024, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=0.3))
model.add(tf.keras.layers.Dense(units=no_classes, activation='softmax'))
model.compile(loss=tf.keras.losses.categorical_crossentropy,
optimizer=tf.keras.optimizers.Adam(),
metrics=['accuracy'])
return model
simple_cnn_model = simple_cnn(input_shape)
```
該模型剛剛定義,必須進行編譯。 在編譯損失期間,必須定義優化器和指標。 損失將是交叉熵,并通過 Adam 算法進行了優化,我們將以準確率作為度量標準。 使用加載的數據,訓練和評估數據。 使用訓練參數加載訓練數據并擬合模型:
```py
simple_cnn_model.fit(x_train, y_train, batch_size, epochs, (x_test, y_test))
train_loss, train_accuracy = simple_cnn_model.evaluate(
x_train, y_train, verbose=0)
print('Train data loss:', train_loss)
print('Train data accuracy:', train_accuracy)
```
使用 Keras API 時,不會創建會話。 然后按以下方式評估測試數據:
```py
test_loss, test_accuracy = simple_cnn_model.evaluate(
x_test, y_test, verbose=0)
print('Test data loss:', test_loss)
print('Test data accuracy:', test_accuracy)
```
評估也可以在不顯式創建會話的情況下創建。 運行完成后,結果應類似于以下內容:
```py
Loss for train data: 0.0171295607952
Accuracy of train data: 0.995016666667
Loss for test data: 0.0282736890309
Accuracy of test data: 0.9902
```
這樣可以使測試數據的準確率達到 99%。 請注意,訓練精度高于測試數據,并且始終打印它們都是一個好習慣。 精度的差異是由于迭代次數造成的。 由于數據集的差異,準確率比 TensorFlow 中創建的先前模型要高一些。
# 其他流行的圖像測試數據集
`MNIST`數據集是用于測試算法的最常用數據集。 但是還有其他數據集可用于測試圖像分類算法。
# CIFAR 數據集
**加拿大高級研究機構**(**CIFAR-10**)數據集包含 60,000 張圖像,其中 50,000 張圖像用于訓練,10,000 張圖像用于測試。 類的數量是 10。圖像尺寸是 32 像素 x 32 像素。 以下是從每個類別中隨機選擇的圖像:

這些圖像很小,僅包含一個對象。 `CIFAR-100`數據集包含相同數量的圖像,但具有 100 個類別。 因此,每個類別只有 600 張圖像。 每個圖像都帶有一個超級標簽和一個精美標簽。 如果您想進行實驗,可以在`tf.keras.datasets`上找到此數據集。
# Fashion-MNIST 數據集
`Fashion-MNIST`是替代`MNIST`數據集而創建的數據集。 創建為`MNIST`的此數據集被認為太簡單了,可以直接用`MNIST`代替。
以下是在執行**主成分分析**(**PCA**)之后從數據集中隨機選擇的示例:

數據集大小,標簽數量和圖像大小類似于`MNIST`。 可以在[這個頁面](https://github.com/zalandoresearch/fashion-mnist)上找到更多詳細信息。 您可以運行先前學習的模型并檢查準確率。
# ImageNet 數據集和競賽
ImageNet 是具有 14,197,122 圖像,21,841 個同義詞集索引的計算機視覺數據集。 同義詞集是 WordNet 層次結構中的一個節點,而節點又是一組同義詞。 每年都會舉辦一次比賽,其中有 1000 個此類數據集。 它已成為評估圖像分類算法表現的標準基準。
在 2013 年,基于深度學習的計算機視覺模型獲得了第一名。 從那時起,只有深度學習模型贏得了競爭。 以下是多年來在比賽中排名前五位的錯誤率:

您會注意到,多年來精度以及層的深度一直在增加。 接下來,我們將了解該圖中存在的模型。
# 更大的深度學習模型
我們將審視幾種模型定義,這些模型定義在 ImageNet 競賽中取得了最新的成果。 我們將在以下主題中單獨研究它們。
# AlexNet 模型
[**Krizhevsky 等人**](https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf)提出了 AlexNet(是第一個引起人們對計算機視覺深度學習的廣泛興趣的作品),它一直是這個領域里的先驅和影響力。 該模型贏得了 ImageNet 2013 挑戰。 錯誤率是 15.4%,明顯優于下一個。 該模型是具有五個卷積層的相對簡單的架構。 面臨的挑戰是對 1,000 種對象進行分類。 圖像和數據包含 1500 萬條帶標注的圖像,其中包含 22,000 多個類別。 其中,只有 1,000 個類別用于比賽。 AlexNet 使用 ReLU 作為激活函數,發現它的訓練速度比其他激活函數快幾倍。 該模型的架構如下所示:

復制自 Krizhevsky 等人。
本文還使用了數據增強技術,例如圖像翻譯,水平翻轉和隨機裁剪。 漏失層防止過擬合 。 該模型使用原始**隨機梯度下降**(**SGD**)進行訓練。 仔細選擇 SGD 的參數進行訓練。 學習率在一組固定的訓練迭代中變化。 動量和權重衰減采用固定值進行訓練。 本文介紹了一種稱為**局部響應規范化**(**LRN**)的概念。 LRN 層對濾鏡上的每個像素進行歸一化,以避免在特定濾鏡中發生巨大的激活。
不再使用該層,因為最近的研究表明,由于 LRN,沒有太大的改進。 AlexNet 總共有 6000 萬個參數。
# VGG-16 模型
**VGG** 模型代表牛津大學的, **視覺幾何組** 。 該模型非常簡單,并且比 AlexNet 具有更大的深度。 該紙有兩個模型,深度分別為 16 和 19 層。 所有的 CNN 層都使用`3 x 3`步幅的濾鏡和 1 尺寸的墊,以及 2 步幅的最大合并尺寸 2。這導致參數數量減少。 盡管由于最大池化而減小了大小,但過濾器的數量卻隨著層的增加而增加。 16 層深度模型的架構如下:

該模型具有 1.38 億個參數,是此處描述的所有模型中最大的。 但是參數的一致性很好。 其特征是,隨著網絡的深入,圖像的尺寸越小,過濾器的數量就越多。 所使用的數據增強技術之一是規模抖動。 比例抖動是一種增強技術,其中具有隨機大小的一側被認為會改變比例。
# Google Inception-V3 模型
[**Inception-V3** 是 Szegedy 等人提出的](https://arxiv.org/pdf/1409.4842.pdf),并介紹了具有更好泛化方法的初始概念。 該架構在 2014 年贏得了 ImageNet 競賽的冠軍。它旨在提高速度和尺寸的效率。 它的參數比 AlexNet 小 12 倍。 初始階段是構建宏架構的微架構。 每個隱藏層都有一個較高級別的圖像表示。 在每一層,我們可以選擇使用池化或其他層。 初始使用多個內核,而不是使用一種類型的內核。 平均池之后是各種大小的卷積,然后將它們合并在一起。
可以基于數據學習內核參數。 使用多個內核,該模型可以檢測較小的特征以及較高的抽象度。 `1 x 1`卷積將減少特征,從而減少計算量。 這將在推理過程中占用較少的 RAM。 以下是最簡單形式的啟動模塊,其中包含具有各種內核大小和池化的卷積選項:

請注意,與 AlexNet 或 VGG 相反,操作是并行進行的。 輸出量巨大,因此引入了`1 x 1`的過濾器以降低尺寸。 將縮小的尺寸添加到架構后,它將變為:

該模型的整個架構如下,包括所有的風吹草動:

該圖說明了 Google Inception V3 模型架構[經 Szegedy 等人的許可復制]
有 9 個初始模塊,共 100 層,它們具有良好的表現。
# Microsoft ResNet-50 模型
[**ResNet** 是 He 等人提出的](https://arxiv.org/pdf/1512.03385.pdf),并在 2015 年贏得了 ImageNet 競賽。此方法表明可以訓練更深的網絡。 網絡越深,精度變得越飽和。 這甚至不是由于過擬合或由于存在大量參數,而是由于減少了訓練誤差。 這是由于無法反向傳播梯度。 可以通過以下方法將梯度直接發送到帶有殘差塊的更深層來克服:

每兩層相連,形成一個殘留塊。 您可以看到訓練是在各層之間傳遞的。 通過這種技術,反向傳播會將誤差帶到較早的層。
可以使用來自[這里](https://github.com/tensorflow/tensorflow/tree/r1.4/tensorflow/python/keras/_impl/keras/applications)的模型定義,它定義了模型中的每一層,并且提供`ImageNet`數據集上的預訓練權重。
# SqueezeNet 模型
[Iandola 等人介紹了 **SqueezeNet** 模型](https://arxiv.org/pdf/1602.07360.pdf),以減少模型尺寸和參數數量。
通過使用`1 x 1`過濾器替換`3 x 3`過濾器,使網絡變得更小,如下所示:

經 Iandola 等人許可復制。
`3 x 3`過濾器的輸入數量也減少了在較高級別發生時各層的下采樣,從而提供了較大的激活圖:

經 Iandola 等人許可復制
# 空間轉換器網絡
Jaderberg 等人提出的[**空間轉換器網絡**](https://arxiv.org/pdf/1506.02025.pdf)嘗試在傳遞到 CNN 之前對圖像進行轉換。 這與其他網絡不同,因為它嘗試在卷積之前修改圖像。 該網絡學習參數以變換圖像。 學習用于**仿射變換**的參數。 通過應用仿射變換,可以實現**空間不變性**。 在以前的網絡中,空間不變性是通過最大池化層實現的。 空間轉換器網絡的位置如下所示:

經 Jaderberg 等人許可復制
# DenseNet 模型
[DenseNet 是 Huang 等人提出的 ResNet 的擴展](https://arxiv.org/pdf/1608.06993.pdf)。 在 ResNet 塊中,上一層通過求和合并到下一層。 在 DenseNet 中,上一層通過連接合并到下一層。 DenseNet 將所有層連接到上一層,將當前層連接到下一層。
在下圖中,可以看出特征圖是如何作為輸入提供給其他層的:

經 Huang 等人許可復制
這樣,它提供了多個優點,例如更平滑的梯度,特征變換等。 這也減少了參數的數量:

經 Huang 等人許可復制
我們已經介紹了圖像分類任務的所有最新算法。 任何架構均可用于圖像分類任務。 在下一節中,我們將看到如何使用這些先進的架構訓練模型來預測寵物,并提高準確率。
# 訓練貓與狗的模型
在本部分中,我們將準備和訓練用于預測貓與狗的模型,并了解一些可提高準確率的技術。 大多數圖像分類問題都屬于這種范例。 本節介紹的技術,例如擴充和遷移學習,對于一些問題很有用。
# 準備數據
為了進行分類,我們將從 **kaggle** 下載數據并以適當的格式存儲。 注冊并登錄 [Kaggle](http://www.kaggle.com) 并轉到[貓狗大戰](https://www.kaggle.com/c/dogs-vs-cats/data)。 從該頁面下載`train.zip`和`test1.zip`文件。 `train.zip`文件包含 25,000 張寵物數據圖像。 我們將僅使用部分數據來訓練模型。 具有更多計算能力的讀者,例如**圖形處理單元**(**GPU**),可以使用比建議的更多的數據。 運行以下腳本以重新排列圖像并創建必要的文件夾:
```py
import os
import shutil
work_dir = '' # give your correct directory
image_names = sorted(os.listdir(os.path.join(work_dir, 'train')))
def copy_files(prefix_str, range_start, range_end, target_dir):
image_paths = [os.path.join(work_dir, 'train', prefix_str + '.' + str(i) + '.jpg')
for i in range(range_start, range_end)]
dest_dir = os.path.join(work_dir, 'data', target_dir, prefix_str)
os.makedirs(dest_dir)
for image_path in image_paths:
shutil.copy(image_path, dest_dir)
copy_files('dog', 0, 1000, 'train')
copy_files('cat', 0, 1000, 'train')
copy_files('dog', 1000, 1400, 'test')
copy_files('cat', 1000, 1400, 'test')
```
對于我們的實驗,我們將僅使用 1000 張貓和狗的圖像。 因此,將圖像 0–999 從下載的文件夾復制到`cats`下新創建的`train` 文件夾。 同樣,將 1,000–1,400 復制到`data/test/cat`,將`train/dogs`中的 0–999 和`data/test/dog`中的 1,000–1,400 復制,這樣我們每個類別都有 1,000 個訓練示例和 400 個驗證示例。
# 使用簡單的 CNN 進行基準測試
讓我們在該數據集上運行先前的`simple_cnn`模型,并查看其表現。 該模型的表現將成為我們判斷其他技術的基本基準。 我們將為數據加載和訓練定義一些變量,如下所示:
```py
image_height, image_width = 150, 150
train_dir = os.path.join(work_dir, 'train')
test_dir = os.path.join(work_dir, 'test')
no_classes = 2
no_validation = 800
epochs = 2
batch_size = 200
no_train = 2000
no_test = 800
input_shape = (image_height, image_width, 3)
epoch_steps = no_train // batch_size
test_steps = no_test // batch_size
```
該常數用于本節中的訓練貓和狗模型的討論中討論的技術。 在這里,我們正在使用 2,800 張圖像進行訓練和測試,這對于個人計算機的 RAM 是合理的。 但這對于更大的數據集是不可持續的。 最好一次只加載一批圖像進行訓練和測試。 為此,`tf.keras`具有稱為`ImageDataGenerator`的類,可在必要時讀取圖像。 假定從上一節中導入了`simple_cnn`模型。 以下是使用生成器加載圖像的示例:
```py
generator_train = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1\. / 255)
generator_test = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1\. / 255)
```
加載時,此定義還會重新縮放圖像。 接下來,我們可以使用`flow_from_directory`方法從目錄中讀取圖像,如下所示:
```py
train_images = generator_train.flow_from_directory(
train_dir,
batch_size=batch_size,
target_size=(image_width, image_height))
test_images = generator_test.flow_from_directory(
test_dir,
batch_size=batch_size,
target_size=(image_width, image_height))
```
加載圖像的目錄,批量大小和圖像的目標大小作為參數傳遞。 此方法執行重新縮放,并分批傳遞數據以擬合模型。 該生成器可直接用于擬合模型。 該模型的方法 `fit_generator`可以按以下方式使用:
```py
simple_cnn_model.fit_generator(
train_images,
steps_per_epoch=epoch_steps,
epochs=epochs,
validation_data=test_images,
validation_steps=test_steps)
```
該模型適合來自訓練圖像生成器的數據。 從訓練中定義周期數,并傳遞驗證數據以獲取模型過度訓練的表現。 該`fit_generator`支持并行處理數據和模型訓練。 CPU 執行重新縮放,而 GPU 可以執行模型訓練。 這使得計算資源的效率很高。 經過 50 個周期后,該模型的準確率應為 60%。 接下來,我們將看到如何擴充數據集以獲得改進的表現。
# 擴充數據集
數據擴充提供了增加數據集大小的方法。 數據擴充會在訓練期間引入噪聲,從而在模型中為各種輸入生成魯棒性。 該技術在數據集較小且可以組合并與其他技術一起使用的情況下很有用。 接下來,我們將看到不同類型的擴充。
# 增強技術
可以通過多種方式來增強圖像,如下所述:
* **翻轉**:圖像在水平或垂直方向上被鏡像或翻轉
* **隨機裁剪**:裁剪隨機部分,因此該模型可以處理遮擋
* **剪切**:變形圖像來影響對象的形狀
* **縮放**:訓練圖像的縮放部分來處理不同比例的圖像
* **旋轉**:旋轉對象來處理對象中各種程度的變化
* **增白**:增白是通過僅保留重要數據的主成分分析完成的
* **歸一化**:通過標準化均值和方差來歸一化像素
* **通道偏移**:更改顏色通道來使模型對各種偽像引起的顏色變化具有魯棒性
所有這些技術都在`ImageDataGenerator`中實現,以增加數據集的大小。 以下是`generator_train`的修改版本,其中包含前面討論的一些增強技術:
```py
generator_train = tf.keras.preprocessing.image.ImageDataGenerator(
rescale=1\. / 255,
horizontal_flip=True,
zoom_range=0.3,
shear_range=0.3,)
```
替換前面代碼中的`generator_train`將使精度提高到 90%。 更改擴充的參數,并注意更改。 在下一節中,我們將討論一種稱為遷移學習的技術,該技術有助于以更少的數據訓練更大的模型。
# 模型的遷移學習或微調
遷移學習是從預先訓練的模型中學習的過程,該模型在較大的數據集上進行了訓練。 用隨機初始化訓練模型通常需要時間和精力才能獲得結果。 使用預訓練的模型初始化模型可以加快收斂速度??,并節省時間和能源。 這些經過預訓練的模型通常使用精心選擇的超參數進行訓練。
可以直接使用預訓練模型的幾層,而無需進行任何修改,也可以對其進行位訓練以適應變化。 在本節中,我們將學習如何對在`ImageNet`數據集上具有數百萬個類別的模型進行調整或遷移學習。
# 瓶頸特征訓練
上一節中介紹的模型很簡單,因此準確率可能較低。 應該從它們構建復雜的模型。 它們不能從頭開始構建。 因此,提取瓶頸特征并對它們進行分類器訓練。 瓶頸特征是訓練數百萬張圖像的復雜架構所產生的特征。 圖像是通過前進完成的,并存儲了最終層的特征。 從這些中,訓練了一個簡單的邏輯分類器進行分類。 提取瓶頸層,如下所示:
```py
generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1\. / 255)
model = tf.keras.applications.VGG16(include_top=False)
train_images = generator.flow_from_directory(
train_dir,
batch_size=batch_size,
target_size=(image_width, image_height),
class_mode=None,
shuffle=False
)
train_bottleneck_features = model.predict_generator(train_images, epoch_steps)
test_images = generator.flow_from_directory(
test_dir,
batch_size=batch_size,
target_size=(image_width, image_height),
class_mode=None,
shuffle=False
)
test_bottleneck_features = model.predict_generator(test_images, test_steps)
```
將采用 VGG 模型并將其用于預測圖像。 標簽分配如下:
```py
train_labels = np.array([0] * int(no_train / 2) + [1] * int(no_train / 2))
test_labels = np.array([0] * int(no_test / 2) + [1] * int(no_test / 2))
```
使用瓶頸特征構建,編譯和訓練具有兩層的順序模型,并且可以使用以下給出的代碼來實現:
```py
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=train_bottleneck_features.shape[1:]))
model.add(tf.keras.layers.Dense(1024, activation='relu'))
model.add(tf.keras.layers.Dropout(0.3))
model.add(tf.keras.layers.Dense(1, activation='softmax'))
model.compile(loss=tf.keras.losses.categorical_crossentropy,
optimizer=tf.keras.optimizers.Adam(),
metrics=['accuracy'])
```
使用以下所示的代碼對這些瓶頸特征進行模型訓練:
```py
model.fit(
train_bottleneck_features,
train_labels,
batch_size=batch_size,
epochs=epochs,
validation_data=(test_bottleneck_features, test_labels))
```
這提供了一種不同的方法來訓練模型,并且在訓練數據較少時很有用。 這通常是訓練模型的更快方法。 僅使用預訓練模型的最終激活來適應新任務。 這個想法可以擴展為微調幾層,如下所示:
# 在深度學習中微調幾層
可以加載預訓練的模型,并且僅可以訓練幾層。 當給定的問題與模型所訓練的圖像非常不同時,此方法會更好地工作。 **微調**是深度學習中的常見做法。 當數據集較小時,這具有優勢。 優化也可以更快地獲得。
在小型數據集上訓練深度網絡會導致過擬合。 使用微調程序也可以避免這種過擬合。 在較大的數據集上訓練的模型也應該相似,因為我們希望激活和特征與較小的數據集相似。 您可以從存儲的權重路徑開始,如下所示:
```py
top_model_weights_path = 'fc_model.h5'
```
加載**視覺幾何組**(**VGG**)模型,并將初始層設置為不可訓練。 下一部分將詳細介紹 VGG 模型。 目前,將 VGG 視為適用于圖像數據的大型深度學習模型。 使用以下給出的代碼,用新的可訓練層替換全連接層:
```py
model = tf.keras.applications.VGG16(include_top=False)
```
可以在 VGG 模型的頂部構建一個小型的兩層前饋網絡,通常具有隱藏的單元,激活和退出,如下所示:
```py
model_fine_tune = tf.keras.models.Sequential()
model_fine_tune.add(tf.keras.layers.Flatten(input_shape=model.output_shape))
model_fine_tune.add(tf.keras.layers.Dense(256, activation='relu'))
model_fine_tune.add(tf.keras.layers.Dropout(0.5))
model_fine_tune.add(tf.keras.layers.Dense(no_classes, activation='softmax'))
```
頂級模型還必須裝有經過充分訓練的砝碼。 然后可以將頂級模型添加到卷積基礎中:
```py
model_fine_tune.load_weights(top_model_weights_path)
model.add(model_fine_tune)
```
我們可以將前 25 個層設置為不可訓練,直到最后一個卷積塊,這樣它們的權重才會被更新。 僅其余層將被更新:
```py
for vgg_layer in model.layers[:25]:
vgg_layer.trainable = False
```
使用梯度下降優化器以緩慢的學習率(4 量級)編譯模型:
```py
model.compile(loss='binary_crossentropy',
optimizer=tf.keras.optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
```
我們可以將之前介紹的增強技術與剪切,縮放和翻轉結合使用。 可以從目錄中將流與訓練和驗證數據集一起添加到生成器。 現在可以將模型與數據增強結合起來進行微調。 這種訓練方式比以前的所有方法都具有更好的準確率。 以下是轉學的指南:
| **數據大小** | **相似數據集** | **不同的數據集** |
| --- | --- | --- |
| 較小的數據 | 微調輸出層 | 微調更深層 |
| 更大的數據 | 微調整個模型 | 從頭開始訓練 |
根據數據大小,可以確定要微調的層數。 數據越少,需要調整的層數就越少。 我們已經看到了如何使用遷移學習技術來提高模型的準確率。
# 開發實際應用
識別貓和狗是一個很酷的問題,但不太可能是重要的問題。 產品中使用的圖像分類的實際應用可能會有所不同。 您可能有不同的數據,目標等。 在本節中,您將學習解決這些不同設置的提示和技巧。 解決新問題時應考慮的因素如下:
* 目標數量。 是 10 類問題還是 10,000 類問題?
* 類內差異有多大? 例如,是否必須在一個類別標簽下標識不同類型的貓?
* 類間差異有多大? 例如,是否需要識別不同的貓?
* 數據有多大?
* 數據的平衡程度如何?
* 是否已經有一個用很多圖像訓練的模型?
* 部署推斷時間和模型大小需要什么? 在 iPhone 上是 50 毫秒還是在 Google Cloud Platform 上是 10 毫秒? 可以消耗多少 RAM 來存儲模型?
處理圖像分類問題時,請嘗試回答這些問題。 根據答案,您可以設計訓練架構并提高準確率,如下一節所述。
# 選擇合適的模型
架構有很多選擇。 根據部署的靈活性,可以選擇模型。 請記住,卷積較小且較慢,但是密集層較大且較快。 在大小,運行時間和準確率之間需要權衡。 建議在最終決定之前測試所有架構。 根據應用,某些模型可能比其他模型更好。 您可以減小輸入大小以加快推理速度。 可以根據以下部分所述的指標來選擇架構。
# 解決欠擬合和過擬合的方案
對于該問題,模型有時可能太大或太小。 可以將其分別分類為欠擬合或過擬合。 當模型太小時會發生擬合不足,而在訓練精度較低時可以進行測量。 當模型太大并且訓練和測試精度之間存在較大差距時,就會發生過擬合。 擬合不足可以通過以下方法解決:
* 獲取更多數據
* 嘗試更大的模型
* 如果數據很小,請嘗試使用遷移學習技術或進行數據擴充
過擬合可以通過以下方法解決:
* 將丟棄法和批量規范化等技術用于正則化
* 擴充數據集
時刻提防損失。 損耗應隨著迭代次數的減少而減少。 如果損失沒有減少,則表明訓練已停止。 一種解決方案是嘗試使用其他優化器。 類別失衡可以通過加權損失函數來解決。 始終使用 **TensorBoard** 觀看摘要。 很難估計需要多少數據。 本部分是訓練任何深度學習模型的最佳課程。 接下來,我們將介紹一些特定于應用的指南。
# 人臉性別和年齡檢測
應用可能需要從人臉檢測性別和年齡。 人臉圖像可以是通過人臉檢測器獲取的 。 可以將經過裁剪的人臉圖像作為訓練數據提供,并且應該給出相似的經過裁剪的人臉以進行推斷。 根據所需的推理時間,可以選擇 OpenCV 或 CNN 人臉檢測器。 對于訓練,可以使用 Inception 或 ResNet。 如果由于是視頻而所需的推理時間要少得多,則最好使用三個卷積,然后是兩個全連接層。 請注意,年齡數據集通常存在巨大的類別失衡,因此使用不同的度量標準(如準確率和召回率)將有所幫助。
# 自定義模型的微調
自定義模型的微調是一個不錯的選擇。 在這里,具有多個對屬性進行分類的 softmax 層將很有用。 這些屬性可以是圖案,顏色等。
# 品牌安全
使用**支持向量機**(**SVM**)來訓練瓶頸層是一個不錯的選擇,因為各個類別的圖像可能會完全不同。 通常將其用于內容審核,以幫助避免顯示露骨的圖像。 您已經了解了如何解決圖像分類中的新問題。
# 總結
我們已經介紹了用于訓練分類任務的基本但有用的模型。 我們看到了使用 Keras 和 TensorFlow API 的 MNIST 數據集的簡單模型。 我們還看到了如何利用 TensorBoard 觀看訓練過程。 然后,我們討論了一些特定應用的最新架構。 還介紹了幾種提高準確率的方法,例如數據增強,瓶頸層訓練和微調預訓練模型。 還介紹了為新模型訓練模型的提示和技巧。
在下一章中,我們將看到如何可視化深度學習模型。 我們還將在本章中部署經過訓練的模型以進行推斷。 我們還將看到如何將訓練有素的層用于通過應用進行圖像搜索。 然后,我們將了解自編碼器的概念并將其用于特征的維數。
- 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
- 六、自編碼器,變分自編碼器和生成對抗網絡
- 七、遷移學習
- 八、機器學習最佳實踐和故障排除
- 九、大規模訓練
- 十、參考文獻