基於Tensorflow和卷積神經網路對加碼圖片進行復現
Tensorflow是Google推出的深度學習框架,也是目前最為流行的開源深度學習框架之一,使用Tensorflow能夠完成很多複雜的圖片處理任務。
在本文中將使用圖片加解碼的原理,然後配合一個簡單的卷積神經網路,訓練出一個能夠實現打了碼賽克的圖片復現的功能。
卷積神經網路是深度學習中訓練神經網路最常用的一種模型,對圖片的處理有很好的效果。文中說到的圖片加解碼流程,簡單的理解就是對圖片進行壓縮和解壓過程,而在卷積神經網路中的體現可以看做是進行卷積使原始圖片降低維度,然後再做一次逆過程使降維後的圖片升維。
下文展示的是部分實現代碼
首先是導入Tensorflow 的庫函數
import tensorflow as tfn
命名為tf基本上是行業規範。之後是導入MNIST的數據集,文中進行訓練的數據集是MNIST數據集,MNIST是一個手寫開源共享的數字資料庫,它有60000個訓練樣本集和10000個測試樣本集。
from tensorflow.examples.tutorials.mnist import input_datanmnist = input_data.read_data_sets(MNIST_data, one_hot = True)n
如果本地沒有存儲數據集,執行這條代碼後系統會自動進行下載,存放在MNIST_data文件夾內。
導入完成數據之後可以做一下簡單的數據可視化,比如顯示訓練集中的一張圖片
查看圖片的shape,發現維度是(784,),其實導入的MNIST數據集裡面所有的圖片維度都是(784,),而且圖片還是單通道的,所以如果要做可視化的時候還要進行一次shape轉換。
img = mnist.train.images[20]nimg = img.reshape((28,28))nplt.imshow(img)n
不過還有個更加簡單的方法,直接導入數據的時候就讓圖片的shape就是(28,28),reshape設置為False。
mnist = input_data.read_data_sets(MNIST_data, one_hot = True, reshape = False)n
之後是代碼的核心部分,首先定義的是卷積神經網路的的輸入和輸出,因為開始的輸入和最終的輸出都是一張28*28*1的圖片,所以這裡的佔位變數為 (None, 28, 28, 1),None等待的是batch的輸入。
x = tf.placeholder(tf.float32, (None, 28, 28, 1), name = input)ny = tf.placeholder(tf.float32,(None, 28, 28, 1), name = output)n
定義卷積神經網路中每層的權重和偏至,這裡用字典的形式保存每層卷積網路的權重值和偏置值,之後就可以方便調用了。權重的初始值使用的是縮減正態分布隨機生成的(這裡標準差設置為0.1,這樣使權重集中在負0.1和0.1的範圍之內,沒有這個參數後面訓練cost會達到10w以上,耗費更多的訓練時間),因為權重使用的是縮減的正態分布,所以偏至可以全部初始化為0。
weights = {n conv1:tf.Variable(tf.truncated_normal([3, 3, 1, 64],stddev = 0.1)),n conv2:tf.Variable(tf.truncated_normal([3, 3, 64, 64],stddev = 0.1)),n conv3:tf.Variable(tf.truncated_normal([3, 3, 64, 32],stddev = 0.1)),n conv4:tf.Variable(tf.truncated_normal([3, 3, 32, 32],stddev = 0.1)),n conv5:tf.Variable(tf.truncated_normal([3, 3, 32, 64],stddev = 0.1)),n conv6:tf.Variable(tf.truncated_normal([3, 3, 64, 64],stddev = 0.1)),n output:tf.Variable(tf.truncated_normal([3, 3, 64, 1],stddev = 0.1))n}nnbiases = {n b1:tf.Variable(tf.zeros([64])),n b2:tf.Variable(tf.zeros([64])),n b3:tf.Variable(tf.zeros([32])),n b4:tf.Variable(tf.zeros([32])),n b5:tf.Variable(tf.zeros([64])),n b6:tf.Variable(tf.zeros([64])),n b_output:tf.Variable(tf.zeros([1]))n}n
定義卷積神經網路模型結構,這裡conv2d、maxpooling2d和upsampling是自己定義的函數名稱(可在完整代碼文檔查看),這裡重點描述的是卷積神經網路結構,可以看出是3層卷積+3層池化+3層Upsampling+3層逆卷積+1層輸出卷積的網路模型架構。這一系列的過程就是上文說的先降維然後再升維的過程。
conv1 = conv2d(x, weights[conv1], biases[b1])nconv1 = maxpooling2d(conv1)nnconv2 = conv2d(conv1, weights[conv2], biases[b2])nconv2 = maxpooling2d(conv2)nnconv3 = conv2d(conv2, weights[conv3], biases[b3])nconv3 = maxpooling2d(conv3)nnconv4 = upsampling(conv3, 7, 7)nconv4 = conv2d(conv4, weights[conv4], biases[b4])nnconv5 = upsampling(conv4, 14,14)nconv5 = conv2d(conv5, weights[conv5], biases[b5])nnconv6 = upsampling(conv5, 28,28)nconv6 = conv2d(conv6, weights[conv6], biases[b6])nnoutput = tf.nn.conv2d(conv6, weights[output], strides = [1,1,1,1], padding =SAME)noutput = tf.nn.bias_add(output, biases[b_output])n
定義卷積神經網路模型訓練時的Loss和優化函數,雖然代碼比較簡單,但是這個是卷積神經網路的核心,因為一切機器學習的目的就是一個找最優解的過程。這裡激活函數使用的是sigmoid,因為我們做的不是一個分類問題,所有不必選擇softmax。優化演算法使用的是Adma。
cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels = y, logits = logits))noptimizer = tf.train.AdamOptimizer(learning_rate = 0.001).minimize(cost)n
最後就是進行模型的訓練。但是在訓練前要對輸入的圖片進行碼賽克處理,這樣我們的模型才能夠學到解碼的方法。希望達到的解碼效果如下。
生成碼賽克圖片的代碼如下,方法就是添加隨機像素然後再進行一次修剪,修剪的目的是為了達到原始圖片的0到1的像素分布值。
noisy_imgs = imgs + 0.5*np.random.randn(*imgs.shape)nnoisy_imgs = np.clip(noisy_imgs, 0., 1.)n
然後選好epochs(訓練批次)和batch_size(沒次訓練使用的數據集大小)就可以讓模型跑起來了。這裡選擇2個epoch,實踐發現兩個已經能夠達到很好的效果了,而且會有過擬合的趨勢。
epochs = 2nbatch_size = 128nninit = tf.global_variables_initializer()nnsess = tf.Session()nsess.run(init)nnfor epoch in range(epochs):n for i in range(mnist.train.num_examples//batch_size):n batch = mnist.train.next_batch(batch_size)n imgs = batch[0].reshape((-1, 28, 28, 1))n noisy_imgs = imgs + 0.5*np.random.randn(*imgs.shape)n noisy_imgs = np.clip(noisy_imgs, 0., 1.)n batch_cost, _ = sess.run([cost,optimizer], feed_dict={x:noisy_imgs, y:imgs})n if i % 10 == 0:n print (Epoch: {}/{} Batch: {}.format(epoch+1, epochs, i),Trianing loss: {:.4f}.format(batch_cost))n
訓練完成後loss已經降到了0.1左右了。
最後選出10張測試訓練集裡面的圖片進行效果驗證
效果還算湊合,如果使用更加好的卷積網路會取得更好的效果。
完整代碼:JaimeTang/AutoEncoder
推薦閱讀:
※龍媽專屬決策樹 | 原來她最大的王牌不是龍
※一文搞懂RNN(循環神經網路)基礎篇
※李宏毅機器學習2016 第十四講 深度自編碼器
※除了啤酒和尿布,關聯規則分析究竟還有哪些實際應用?
※Gradient Boosting
TAG:深度学习DeepLearning | 机器学习 |