#coding:utf-8

import tensorflow as tf
from PIL import Image,ImageFilter
from tensorflow.examples.tutorials.mnist import input_data

def imageprepare(argv): # 該函式讀一張圖片,處理後返回一個數組,進到網路中預測
    """
    This function returns the pixel values.
    The imput is a png file location.
    """
    im = Image.open(argv).convert('L')
    width = float(im.size[0])
    height = float(im.size[1])
    newImage = Image.new('L', (28, 28), (255))  # creates white canvas of 28x28 pixels

    if width > height:  # check which dimension is bigger
        # Width is bigger. Width becomes 20 pixels.
        nheight = int(round((20.0 / width * height), 0))  # resize height according to ratio width
        if nheight == 0:  # rare case but minimum is 1 pixel
            nheight = 1
            # resize and sharpen
        img = im.resize((20, nheight), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
        wtop = int(round(((28 - nheight) / 2), 0))  # caculate horizontal pozition
        newImage.paste(img, (4, wtop))  # paste resized image on white canvas
    else:
        # Height is bigger. Heigth becomes 20 pixels.
        nwidth = int(round((20.0 / height * width), 0))  # resize width according to ratio height
        if (nwidth == 0):  # rare case but minimum is 1 pixel
            nwidth = 1
            # resize and sharpen
        img = im.resize((nwidth, 20), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
        wleft = int(round(((28 - nwidth) / 2), 0))  # caculate vertical pozition
        newImage.paste(img, (wleft, 4))  # paste resized image on white canvas

    # newImage.save("sample.png")

    tv = list(newImage.getdata())  # get pixel values

    # normalize pixels to 0 and 1. 0 is pure white, 1 is pure black.
    tva = [(255 - x) * 1.0 / 255.0 for x in tv]
    return tva
def weight_variable(shape):
    initial = tf.truncated_normal(shape,stddev=0.1) #生成一個截斷的正態分佈
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1,shape = shape)
    return tf.Variable(initial)

#卷基層
def conv2d(x,W):
    return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
#池化層
def max_pool_2x2(x):
    return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#定義兩個placeholder
x = tf.placeholder(tf.float32, [None,784])
#y = tf.placeholder(tf.float32,[None,10])

#改變x的格式轉為4D的向量[batch,in_height,in_width,in_channels]
x_image = tf.reshape(x, [-1,28,28,1])

#初始化第一個卷基層的權值和偏置
W_conv1 = weight_variable([5,5,1,32]) #5*5的取樣視窗 32個卷積核從一個平面抽取特徵 32個卷積核是自定義的
b_conv1 = bias_variable([32])  #每個卷積核一個偏置值

#把x_image和權值向量進行卷積,再加上偏置值,然後應用於relu啟用函式
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)
h_pool1 = max_pool_2x2(h_conv1) #進行max-pooling

#初始化第二個卷基層的權值和偏置
W_conv2 = weight_variable([5,5,32,64]) # 5*5的取樣視窗 64個卷積核從32個平面抽取特徵  由於前一層操作得到了32個特徵圖
b_conv2 = bias_variable([64]) #每一個卷積核一個偏置值

#把h_pool1和權值向量進行卷積 再加上偏置值 然後應用於relu啟用函式
h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2) #進行max-pooling

#28x28的圖片第一次卷積後還是28x28 第一次池化後變為14x14
#第二次卷積後 變為14x14 第二次池化後變為7x7
#通過上面操作後得到64張7x7的平面

#初始化第一個全連線層的權值
W_fc1 = weight_variable([7*7*64,1024])#上一層有7*7*64個神經元,全連線層有1024個神經元
b_fc1 = bias_variable([1024]) #1024個節點

#把第二個池化層的輸出扁平化為一維
h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64])
#求第一個全連線層的輸出
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1)

#keep_prob用來表示神經元的輸出概率
keep_prob  = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)

#初始化第二個全連線層
W_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])

#計算輸出
gailv = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2) 

saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    saver.restore(sess,'/home/xxx/logs/mnistmodel-1')
    array = imageprepare('/home/xxx/logs/7.jpg') # 讀一張包含數字的圖片
    prediction = tf.argmax(gailv, 1) # 預測
    prediction = prediction.eval(feed_dict={x:[array],keep_prob:1.0},session=sess)
    print('The digits in this image is:%d' % prediction[0])
複製程式碼

結果 手寫數字圖片7被預測為7

I tensorflow/core/common_runtime/gpu/gpu_device.cc:906] DMA: 0 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 0:   Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 1080 Ti, pci bus id: 0000:03:00.0)
The digits in this image is:7