使用tensorflow layers相關API快速構建卷積神經網絡

Layers API介紹

tf.layers包中包含了CNN卷積神經網絡的大多數層類型,當前封裝支持的層包括:

  • 卷積層
  • 均值池化層
  • 最大池化層
  • 扁平層
  • 密集層
  • dropout層
  • BN層
  • 轉置卷積層

我們將基於卷積層、池化層、扁平層與密集層構建一個簡單網絡模型,實現手寫數字識別mnist數據集的訓練。首先需要詳解的介紹一下卷積層與池化層API與參數。 tf.layers.conv2d是卷積層組件、定義與參數解釋如下:

conv2d(
    inputs,
    filters,
    kernel_size,
    strides=(1, 1),
    padding='valid',
    data_format='channels_last',
    dilation_rate=(1, 1),
    activation=None,
    use_bias=True,
    kernel_initializer=None,
    bias_initializer=init_ops.zeros_initializer(),
    kernel_regularizer=None,
    bias_regularizer=None,
    activity_regularizer=None,
    kernel_constraint=None,
    bias_constraint=None,
    trainable=True,
    name=None,
    reuse=None
)

# 參數解釋如下:

input表示輸入tensor
filters表示輸出的深度維度、也是卷積核的個數
kernel_size 卷積核的大小,一個整數或者是一個元組
strides=(1, 1), 卷積時候的步長、一個整數或者一個元組,默認是1x1的步長
padding 填充方式,默認valid意思是不夠的丟棄,如果是same表示不夠時候補零
dilation_rate 是否使用膨脹卷積,默認不使用
activation激活函數
use_bias 是否使用增益偏置
kernel_initializer卷積核初始化參數方式,如果設置爲None默認爲xavier_initializer
bias_initializer 增益初始化,默認初始化爲零
kernel_regularizer卷積核正則化
bias_regularizer 增益偏置正則化
activity_regularizer對輸出進行正則化
kernel_constraint 約束、當核被Optimizer更新後應用到核上。Optimizer用來實現對權重矩陣的範數約束或者值約束。映射函數必須將未被影射的變量作爲輸入,且一定輸出映射後的變量(有相同的大小)。做異步的分佈式訓練時,使用約束可能是不安全的。
bias_constraint 約束、當偏差向量被Optimizer更新後應用到偏差向量上
trainable 是否可訓練,廢話,當然是True
name 給這個卷積操作取個名字,方便以後獲取它

tf.layers.max_pooling2d是最大池化層組件、定義與參數解釋如下:

max_pooling2d(
    inputs,
    pool_size, 
    strides,
    padding='valid', 
    data_format='channels_last',
    name=None
)
input表示輸入tensor
pool_size表示輸出的深度維度、也是卷積核的個數
strides=(1, 1), 卷積時候的步長、一個整數或者一個元組,默認是1x1的步長
padding 填充方式,默認valid意思是不夠的丟棄,如果是same表示不夠時候補零
data_format表示數據格式順序,默認是channels_last數據的格式順序爲(batch, height, width, channels)。如果是 channels_first數據格式順序爲 (batch, channels, height, width)
name最大池化層的名字

代碼實現

聲明輸入的佔位符

x = tf.placeholder(shape=[None, 784], dtype=tf.float32)
y = tf.placeholder(shape=[None, 10], dtype=tf.float32)
keep_prob = tf.placeholder(dtype=tf.float32)
x_image = tf.reshape(x, [-1, 28, 28, 1])

構建網絡 基於layers相關層API只需10行代碼的卷積網絡,包括兩個卷積層+兩個池化層+兩個全鏈接層+一個輸出層。

def conv_net(x_dict, n_classes, dropout):
    conv1 = tf.layers.conv2d(x_dict, 32, 5, activation=tf.nn.relu)
    pool1 = tf.layers.max_pooling2d(conv1, pool_size=2, strides=2)

    conv2 = tf.layers.conv2d(pool1, 64, 3, activation=tf.nn.relu)
    pool2 = tf.layers.max_pooling2d(conv2, pool_size=2, strides=2)

    fc1 = tf.layers.flatten(pool2, name="fc1")
    fc2 = tf.layers.dense(fc1, 1024)
    fc2 = tf.layers.dropout(fc2, rate=dropout)
    out = tf.layers.dense(fc2, n_classes)
    return out

訓練網絡

logits = conv_net(x_image, num_classes, keep_prob)
cross_loss = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y)
loss = tf.reduce_mean(cross_loss)
step = tf.train.AdamOptimizer(learning_rate).minimize(loss)

# accuracy
acc_mat = tf.equal(tf.argmax(logits, 1), tf.argmax(y, 1))
acc = tf.reduce_sum(tf.cast(acc_mat, tf.float32))
prediction = tf.argmax(logits, axis=1)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(20000):
        is_training = True
        batch_xs, batch_ys = mnist.train.next_batch(min_batch)
        _, curr_loss = sess.run([step, loss], feed_dict={x: batch_xs, y: batch_ys, keep_prob: 0.5})
        if (i + 1) % 1000 == 0:
            is_training = False
            conv_y, curr_acc = sess.run([logits, acc], feed_dict={x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0})
            print("current loss: %f, current test Accuracy : %f" % (curr_loss, curr_acc))

最終在測試集上得到的準確率高達99%以上, 有圖爲證:

不要因路遠而躊躇,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章