Posted on

Dense全連接層介紹

Tensorflow的全連接層

對Tensorflow而言,全連接層的類別為: tf.keras.layers.Dense
相關介紹: https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense

甚麼是全連接層

在 Dense 層中,每個輸入都會對每個輸出進行綜合計算,得到一個輸出值。這個綜合計算包括了對輸入和前一層輸出的矩陣乘法,以及對輸入和輸出的加權和。計算過程中,對輸入的乘法是通過對每個輸入的加權,得到的权重矩陣就是Dense層的權重矩陣。這些权重矩陣就是Dense層所學習的模型參數。

這層的經典用途就是進行分類,把特徵轉成概率,進而做出預測, 可以實現多種不同的操作, 如全連接,激活函數等,是基礎網路結構的基礎。

Dense層中通常還會有一個偏差項, 每個輸出都有一個偏差項, 該項是Dense層的一部分參數, 也會在學習過程中更新。

最后 Dense層 還會有一個激活函數, 用於對綜合計算的結果進行非線性轉換, 增加網絡的非線性表達能力。

全連接層的優點

在多數的深度學習模型中,輸出層常常使用 Dense 層,這是因為 Dense 層具有下列優點:

1. Dense層可以實現任意的非線性轉換,而輸出層需要進行非線性轉換,因為在大多數情況下,輸出的預測結果需要進行非線性轉換。

2. Dense層具有較高的計算效率,對於輸出層來說,需要進行大量的運算,而 Dense 層可以高效地完成這些運算。

3. Dense層 可以通過學習來自動調整權重和偏差,而且可以將輸入特徵在輸出層進行組合, 獲得高維度且有用的輸出.

因此, Dense層 是輸出層的選擇之一,並且被廣泛使用。

簡單的圖片介紹

下圖第二和第三層,與全部前一層相連接,便為Dense層

我們可以單純使用Dense來建構一個MNIST的分類器,其格式如下:

import tensorflow as tf
# Import TensorFlow Datasets
import tensorflow_datasets as tfds
tfds.disable_progress_bar()

# Helper libraries
import math
import numpy as np
import matplotlib.pyplot as plt
import logging
logger = tf.get_logger()
logger.setLevel(logging.ERROR)
dataset, metadata = tfds.load('fashion_mnist', as_supervised=True, with_info=True)
train_dataset, test_dataset = dataset['train'], dataset['test']
class_names = metadata.features['label'].names
print("Class names: {}".format(class_names))
num_train_examples = metadata.splits['train'].num_examples
num_test_examples = metadata.splits['test'].num_examples
print("Number of training examples: {}".format(num_train_examples))
print("Number of test examples:     {}".format(num_test_examples))
def normalize(images, labels):
  images = tf.cast(images, tf.float32)
  images /= 255
  return images, labels

# The map function applies the normalize function to each element in the train
# and test datasets
train_dataset =  train_dataset.map(normalize)
test_dataset  =  test_dataset.map(normalize)

# The first time you use the dataset, the images will be loaded from disk
# Caching will keep them in memory, making training faster
train_dataset =  train_dataset.cache()
test_dataset  =  test_dataset.cache()
# Take a single image, and remove the color dimension by reshaping
for image, label in test_dataset.take(1):
  break
image = image.numpy().reshape((28,28))

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
BATCH_SIZE = 32
train_dataset = train_dataset.cache().repeat().shuffle(num_train_examples).batch(BATCH_SIZE)
test_dataset = test_dataset.cache().batch(BATCH_SIZE)
model.fit(train_dataset, epochs=5, steps_per_epoch=math.ceil(num_train_examples/BATCH_SIZE))

test_loss, test_accuracy = model.evaluate(test_dataset, steps=math.ceil(num_test_examples/32))
print('Accuracy on test dataset:', test_accuracy)

for test_images, test_labels in test_dataset.take(1):
  test_images = test_images.numpy()
  test_labels = test_labels.numpy()
  predictions = model.predict(test_images)
np.argmax(predictions[0])

實踐概念

Dense層是使用線性代數裡的矩陣運算概念實現的。

具體地說,Dense層的計算過程包括了對輸入和前一層輸出的矩陣乘法,以及對輸入和輸出的加權和。 這個綜合計算可以用下面這個矩陣的形式來表示

y = W*x + b

其中 y 是 Dense 層的輸出,x 是輸入,W 是 Dense 層的權重矩陣, b 是偏差項。

這個運算滿足矩陣乘法的性質, W 可以看成是一個 m x n 的矩陣, x 是一個 n x 1 的向量, 這樣 y 就是一個 m x 1 的向量,就是輸出。這種運算方式可以幫助網絡在運算過程中組合特徵,輸出高維度且有用的特徵。