看網(wǎng)上的教程什么的屑柔,大部分都只是訓(xùn)練完就完事了屡萤,我想很多人和我一樣關(guān)心怎么根據(jù)訓(xùn)練的結(jié)果去測(cè)試我們自己的圖片,這部分真的好少看到锯蛀。還有就是代碼很多都沒(méi)有解釋灭衷,這是不友好的,畢竟看的都是新手旁涤,解釋就很重了翔曲。
廢話完
這篇文章你可以學(xué)到怎么寫(xiě)代碼實(shí)現(xiàn)簡(jiǎn)單的CNN網(wǎng)絡(luò)。包括數(shù)據(jù)讀取劈愚,數(shù)據(jù)訓(xùn)練瞳遍,模型存儲(chǔ),測(cè)試結(jié)果菌羽。大概需要20分鐘讀完掠械。
第一部分:先上代碼
導(dǎo)入庫(kù)
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import numpy as np
from PIL import Image
數(shù)據(jù)源,這里的minstData 是在和代碼同目錄的文件夾。讀取這個(gè)文件下的數(shù)據(jù)
需要先去下載mnist 數(shù)據(jù)放置minstData這個(gè)目錄下猾蒂,mnist數(shù)據(jù)需要到網(wǎng)上下載均唉,因?yàn)閲?guó)內(nèi)被墻
mnist = input_data.read_data_sets("minstData", one_hot=True)
讀取mnist中的訓(xùn)練圖片,訓(xùn)練對(duì)應(yīng)的標(biāo)簽肚菠,測(cè)試的圖片舔箭,測(cè)試標(biāo)簽
trX, trY, teX, teY = mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels
定義訓(xùn)練輸入數(shù)據(jù)的結(jié)構(gòu),28行28列的矩陣蚊逢,即圖片的像素大小
trX = trX.reshape(-1, 28, 28, 1)
同訓(xùn)練的輸入結(jié)構(gòu)
teX = teX.reshape(-1, 28, 28, 1)
定義輸入层扶,輸出,的數(shù)據(jù)坑(就是先定義數(shù)據(jù)形狀烙荷,后面會(huì)喂具體數(shù)據(jù))
x = tf.placeholder(tf.float32, [None, 28, 28, 1])
這10是因?yàn)閿?shù)字的結(jié)果只有0到9共10總情況
y = tf.placeholder(tf.float32, [None, 10])
定義權(quán)重的函數(shù)
def init_Weight(shape):
#根據(jù)輸入的數(shù)據(jù)形狀镜会,隨機(jī)生成對(duì)應(yīng)的權(quán)重值
return tf.Variable(tf.random_normal(shape, stddev=0.01))
這里初始化權(quán)重,2個(gè)3代表的是卷積核實(shí)3*3的數(shù)組终抽。
第一層權(quán)重的輸入是1因?yàn)橛?xùn)練圖片的顏色是黑白只有一個(gè)通道戳表。
為什么是32,這個(gè)其實(shí)無(wú)所謂的拿诸,32代表的是有32個(gè)3*3的數(shù)組去和輸入的數(shù)據(jù)卷
積扒袖。每個(gè)卷積代表獲取一種屬性,32也就是獲取32種圖片的特性亩码,當(dāng)然也可以是其#他 的數(shù)量比如20
后面為啥子卷積核的數(shù)量會(huì)變2倍季率?告訴你這是真幾把坑。為嘛描沟,因?yàn)槌鼗?/h1>
池化后圖片會(huì)變小飒泻,呃呃呃,我也不知道為嘛吏廉,感覺(jué)是一種規(guī)定泞遗,全部設(shè)置為
32也是OK 的,但是注意一點(diǎn)前后的數(shù)量要對(duì)應(yīng)席覆。
12844是為嘛呢史辙?128是代表卷積核的數(shù)量,44是應(yīng)為這個(gè)是他圖片大小有2828--1414--77--4*4池化的大小的為2
w = init_Weight([3, 3, 1, 32])
w2 = init_Weight([3, 3, 32, 64])
w3 = init_Weight([3, 3, 64, 128])
w4 = init_Weight([128 * 4 * 4, 625]) # 全連接層
wo = init_Weight([625, 10])
這里定義CNN網(wǎng)絡(luò)模型了
def mode(X, w, w2, w3, w4, wo, p_keep_conv, p_hide_conv):
#2828--1414,池化佩伤,“SAME”是卷積保持原來(lái)的大小聊倔。
l1a = tf.nn.relu(tf.nn.conv2d(X, w, strides=[1, 1, 1, 1], padding="SAME"))
l1 = tf.nn.max_pool(l1a, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
l1 = tf.nn.dropout(l1, p_keep_conv)
l2a = tf.nn.relu(tf.nn.conv2d(l1, w2, strides=[1, 1, 1, 1], padding="SAME"))
l2 = tf.nn.max_pool(l2a, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
l2 = tf.nn.dropout(l2, p_keep_conv)
l3a = tf.nn.relu(tf.nn.conv2d(l2, w3, strides=[1, 1, 1, 1], padding="SAME"))
l3 = tf.nn.max_pool(l3a, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
l3 = tf.reshape(l3, [-1, w4.get_shape().as_list()[0]])
l3 = tf.nn.dropout(l3, p_keep_conv)
# 全連接層
l4 = tf.nn.relu(tf.matmul(l3, w4))
l4 = tf.nn.dropout(l4, p_hide_conv)
# 輸出層
lo = tf.matmul(l4, wo)
return lo
保存的神經(jīng)元數(shù)量
p_keep_conv = tf.placeholder(tf.float32)
隱藏的神經(jīng)元數(shù)量
p_hide_conv = tf.placeholder(tf.float32)
得到訓(xùn)練結(jié)果
py_x = mode(x, w, w2, w3, w4, wo, p_keep_conv, p_hide_conv)
定義損失函數(shù)
coss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=py_x, labels=y))
訓(xùn)練
train_op = tf.train.RMSPropOptimizer(0.01, 0.9).minimize(coss)
predict_op = tf.argmax(py_x, 1)
batch_size = 128
test_size = 256
獲取保存的對(duì)象
save=tf.train.Saver()
開(kāi)始這里標(biāo)記為A
with tf.Session() as sess:
#初始化所有對(duì)象
tf.global_variables_initializer().run()
for i in range(100):
training_batch = zip(range(0, len(trX), batch_size),
range(batch_size, len(trX) + 1, batch_size))
for start, end in training_batch:
sess.run(train_op, feed_dict={x: trX[start:end], y: trY[start:end],
p_keep_conv: 0.8, p_hide_conv: 0.5})
test_indices = np.arange(len(teX))
np.random.shuffle(test_indices)
test_indices = test_indices[0:test_size]
print(i, np.mean(np.argmax(teY[test_indices], axis=1) ==
sess.run(predict_op, feed_dict={x: teX[test_indices],
p_keep_conv: 1.0,
p_hide_conv: 1.0})))
#模型保存到j(luò)iangf這個(gè)目錄下,需要自己創(chuàng)建
save.save(sess,"jiangf/test.ckpt")
結(jié)束這里標(biāo)記為A
---------------上面的是訓(xùn)練并保存模型----------------------
---------讀取保存的模型并識(shí)別自己的圖片--------------
識(shí)別自己我圖片生巡,先將我標(biāo)記的A區(qū)域注釋耙蔑,已經(jīng)訓(xùn)練好了,現(xiàn)在不需要訓(xùn)練了
注釋掉孤荣,下面開(kāi)始識(shí)別我們的圖片
with tf.Session() as sess2:
#恢復(fù)保存的模型
save.restore(sess2, "jiangf/test.ckpt")
#讀取pic 目錄下預(yù)先存好的圖片
image_path = "pic/train6.bmp"
keep_prob = tf.placeholder(tf.float32, [1, 10])
img = Image.open(image_path).convert('L') # 灰度圖(L)
img_array=np.array(img).reshape([-1,28,28,1])
print(img_array)
y = sess2.run(predict_op, feed_dict={x: img_array, p_keep_conv:
1.0,p_hide_conv: 1.0})
print('Predict digit', y) # 輸出結(jié)果甸陌。