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%以上, 有圖爲證:
不要因路遠而躊躇,