卷積網絡博大精深,不同的網絡模型,跑出來的結果是不一樣,在不知道使用什么網絡的情況下跑自己的數據集時,我建議最好去參考基於cnn的手寫數字識別網絡構建,在其基礎上進行改進,對於一般測試數據集有很大的幫助。
分享一個網絡構架和一中訓練方法:
# coding:utf-8
import os
import tensorflow as tf
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# cnn模型高度抽象特征
def cnn_face_discern_model(X_,Y_):
weights = {
"wc1":tf.Variable(tf.random_normal([3,3,1,64],stddev=0.1)),
"wc2":tf.Variable(tf.random_normal([5,5,64,128],stddev=0.1)),
"wd3":tf.Variable(tf.random_normal([7*7*128,1024],stddev=0.1)),
"wd4": tf.Variable(tf.random_normal([1024, 12], stddev=0.1))
}
biases = {
"bc1":tf.Variable(tf.random_normal([64],stddev=0.1)),
"bc2":tf.Variable(tf.random_normal([128],stddev=0.1)),
"bd3": tf.Variable(tf.random_normal([1024],stddev=0.1)),
"bd4": tf.Variable(tf.random_normal([12],stddev=0.1))
}
x_input = tf.reshape(X_,shape=[-1,28,28,1])
# 第一層卷積層
_conv1 = tf.nn.conv2d(x_input,weights["wc1"],strides=[1,1,1,1],padding="SAME")
_conv1_ = tf.nn.relu(tf.nn.bias_add(_conv1,biases["bc1"]))
# 第一層池化層
_pool1 = tf.nn.max_pool(_conv1_,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")
# 第一層失活層
_pool1_dropout = tf.nn.dropout(_pool1,0.7)
# 第二層卷積層
_conv2 = tf.nn.conv2d(_pool1_dropout,weights["wc2"],strides=[1,1,1,1],padding="SAME")
_conv2_ = tf.nn.relu(tf.nn.bias_add(_conv2,biases["bc2"]))
# 第二層池化層
_pool2 = tf.nn.max_pool(_conv2_,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")
# 第二層失活層
_pool2_dropout = tf.nn.dropout(_pool2,0.7)
# 使用全連接層提取抽象特征
# 全連接層1
_densel = tf.reshape(_pool2_dropout,[-1,weights["wd3"].get_shape().as_list()[0]])
_y1 = tf.nn.relu(tf.add(tf.matmul(_densel,weights["wd3"]),biases["bd3"]))
_y2 = tf.nn.dropout(_y1,0.7)
# 全連接層2
out = tf.add(tf.matmul(_y2,weights["wd4"]),biases["bd4"])
# 損失函數 loss
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=Y_, logits=out)) # 計算交叉熵
# 優化目標 optimizing
optimizing = tf.train.AdamOptimizer(0.001).minimize(loss) # 使用adam優化器來以0.0001的學習率來進行微調
# 精確度 accuracy
correct_prediction = tf.equal(tf.argmax(Y_, 1), tf.argmax(out, 1)) # 判斷預測標簽和實際標簽是否匹配
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
return {
"loss":loss,
"optimizing":optimizing,
"accuracy":accuracy,
"out":out
}
批量訓練方法:
# 開始准備訓練cnn
X = tf.placeholder(tf.float32,[None,28,28,1])
# 這個12屬於人臉類別,一共有幾個id
Y = tf.placeholder(tf.float32, [None,12])
# 實例化模型
cnn_model = cnn_face_discern_model(X,Y)
loss,optimizing,accuracy,out = cnn_model["loss"],cnn_model["optimizing"],cnn_model["accuracy"],cnn_model["out"]
# 啟動訓練模型
bsize = 960/60
with tf.Session() as sess:
# 實例所有參數
sess.run(tf.global_variables_initializer())
for epoch in range(100):
for i in range(15):
x_bsize,y_bsize = x_train[i*60:i*60+60,:,:,:],y_train[i*60:i*60+60,:]
sess.run(optimizing,feed_dict={X:x_bsize,Y:y_bsize})
if (epoch+1)%10==0:
los = sess.run(loss,feed_dict={X:x_test,Y:y_test})
acc = sess.run(accuracy,feed_dict={X:x_test,Y:y_test})
print("epoch:%s loss:%s accuracy:%s"%(epoch,los,acc))
score= sess.run(accuracy,feed_dict={X:x_test,Y:y_test})
y_pred = sess.run(out,feed_dict={X:x_test})
# 這個是類別,測試集預測出來的類別。
y_pred = np.argmax(y_pred,axis=1)
print("最后的精確度為:%s"%score)
