1. 程式人生 > >TensorFlow 中的卷積網絡

TensorFlow 中的卷積網絡

extra .so div 使用 connect rop del glob ges

TensorFlow 中的卷積網絡

是時候看一下 TensorFlow 中的卷積神經網絡的例子了。

網絡的結構跟經典的 CNNs 結構一樣,是卷積層,最大池化層和全鏈接層的混合。

這裏你看到的代碼與你在 TensorFlow 深度神經網絡的代碼類似,我們按 CNN 重新組織了結構。

如那一節一樣,這裏你將會學習如何分解一行一行的代碼。你還可以下載代碼自己運行。

感謝 Aymeric Damien 提供了這節課的原始 TensorFlow 模型。

現在開看下!

數據集

你從之前的課程中見過這節課的代碼。這裏我們導入 MNIST 數據集,用一個方便的函數完成對數據集的 batch,縮放和獨熱編碼。

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(".", one_hot=True, reshape=False)

import tensorflow as tf

# Parameters
# 參數
learning_rate = 0.00001
epochs = 10
batch_size = 128

# Number of samples to calculate validation and accuracy
# Decrease this if you‘re running out of memory to calculate accuracy
# 用來驗證和計算準確率的樣本數 # 如果內存不夠,可以調小這個數字 test_valid_size = 256 # Network Parameters # 神經網絡參數 n_classes = 10 # MNIST total classes (0-9 digits) dropout = 0.75 # Dropout, probability to keep units

Weights and Biases

# Store layers weight & bias
weights = {
    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]))} 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]))}

卷積

技術分享圖片

3×3 卷積濾波器。來源:http://deeplearning.stanford.edu/wiki/index.php/Feature_extraction_using_convolution

這是一個 3x3 的卷積濾波器的示例。以 stride 為 1 應用到一個範圍在 0 到 1 之間的數據上。每一個 3x3 的部分與權值 [[1, 0, 1], [0, 1, 0], [1, 0, 1]] 做卷積,把偏置加上後得到右邊的卷積特征。這裏偏置是 0 。TensorFlow 中這是通過 tf.nn.conv2d()tf.nn.bias_add() 來完成的。

def conv2d(x, W, b, strides=1):
    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)

tf.nn.conv2d() 函數與權值 W 做卷積。

在 TensorFlow 中,strides 是一個4個元素的序列;第一個位置表示 stride 的 batch 參數,最後一個位置表示 stride 的特征(feature)參數。最好的移除 batch 和特征(feature)的方法是你直接在數據集中把他們忽略,而不是使用 stride。要使用所有的 batch 和特征(feature),你可以把第一個和最後一個元素設成1。

中間兩個元素指縱向(height)和橫向(width)的 stride,之前也提到過 stride 通常是正方形,height = width。當別人說 stride 是 3 的時候,他們意思是 tf.nn.conv2d(x, W, strides=[1, 3, 3, 1])

為了更簡潔,這裏的代碼用了tf.nn.bias_add() 來添加偏置。 tf.add() 這裏不能使用,因為 tensors 的維度不同。

最大池化

技術分享圖片

帶有 2x2 濾波器 和 stride 為 2 的最大池化。來源:

上面是一個最大池化的示例。濾波器大小是 2x2,stride 是 2。左邊是輸入,右邊是輸出。 四個 2x2 的顏色代表每一次濾波器應用在左側來構建右側的最大結果。例如。[[1, 1], [5, 6]] 變成 6,[[3, 2], [1, 2]] 變成 3。

def maxpool2d(x, k=2):
    return tf.nn.max_pool(
        x,
        ksize=[1, k, k, 1],
        strides=[1, k, k, 1],
        padding=SAME)

tf.nn.max_pool() 函數做的與你期望的一樣,它通過設定 ksize 參數來設定濾波器大小,從而實現最大池化。

模型

Image from Explore The Design Space video

在下面的代碼中,我們創建了 3 層來實現卷積,最大池化以及全鏈接層和輸出層。每一層對維度的改變都寫在註釋裏。例如第一層在卷積部分把圖片從 28x28x1 變成了 28x28x32。後面應用了最大池化,每個樣本變成了 14x14x32。從 conv1 經過多層網絡,最後到 output 生成 10 個分類。

def conv_net(x, weights, biases, dropout):
    # Layer 1 - 28*28*1 to 14*14*32
    conv1 = conv2d(x, weights[wc1], biases[bc1])
    conv1 = maxpool2d(conv1, k=2)

    # Layer 2 - 14*14*32 to 7*7*64
    conv2 = conv2d(conv1, weights[wc2], biases[bc2])
    conv2 = maxpool2d(conv2, k=2)

    # Fully connected layer - 7*7*64 to 1024
    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)
    fc1 = tf.nn.dropout(fc1, dropout)

    # Output Layer - class prediction - 1024 to 10
    out = tf.add(tf.matmul(fc1, weights[out]), biases[out])
    return out

Session

現在讓我們開始運行神經網絡!

# tf Graph input
x = tf.placeholder(tf.float32, [None, 28, 28, 1])
y = tf.placeholder(tf.float32, [None, n_classes])
keep_prob = tf.placeholder(tf.float32)

# Model
logits = conv_net(x, weights, biases, keep_prob)

# Define loss and optimizer
cost = tf.reduce_mean(    tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)    .minimize(cost)

# Accuracy
correct_pred = tf.equal(tf.argmax(logits, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

# Initializing the variables
init = tf. global_variables_initializer()

# Launch the graph
with tf.Session() as sess:
    sess.run(init)

    for epoch in range(epochs):
        for batch in range(mnist.train.num_examples//batch_size):
            batch_x, batch_y = mnist.train.next_batch(batch_size)
            sess.run(optimizer, feed_dict={
                x: batch_x,
                y: batch_y,
                keep_prob: dropout})

            # Calculate batch loss and accuracy
            loss = sess.run(cost, feed_dict={
                x: batch_x,
                y: batch_y,
                keep_prob: 1.})
            valid_acc = sess.run(accuracy, feed_dict={
                x: mnist.validation.images[:test_valid_size],
                y: mnist.validation.labels[:test_valid_size],
                keep_prob: 1.})

            print(Epoch {:>2}, Batch {:>3} -
                  Loss: {:>10.4f} Validation Accuracy: {:.6f}.format(
                epoch + 1,
                batch + 1,
                loss,
                valid_acc))

    # Calculate Test Accuracy
    test_acc = sess.run(accuracy, feed_dict={
        x: mnist.test.images[:test_valid_size],
        y: mnist.test.labels[:test_valid_size],
        keep_prob: 1.})
    print(Testing Accuracy: {}.format(test_acc))

TensorFlow 中的卷積網絡