【tensorflow學習】實現卷積神經網絡

【tensorflow學習】實現卷積神經網絡

基礎知識

CNN基礎知識
卷積層和池化層後輸出計算

應用

實現手寫數字識別
數據集MNIST

#encoding=utf8
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import pandas as pd
import argparse
import math
import numpy as np

def parse_arg():
    parser = argparse.ArgumentParser("Training for MNIST model.")
    parser.add_argument(
        "--train_data_dir",
        type=str,
        required=True,
        help="The path of training data.")
    parser.add_argument(
        "--test_data_dir",
        type=str,
        help="The path of test data.")
    parser.add_argument(
        "--batch_size",
        type=int,
        default=10,
        help="The number of batch size.")
    parser.add_argument(
        "--train_round",
        type=int,
        default=10,
        help="The number of train round.")
    return parser.parse_args()

#對label進行熱編碼
def one_hot(index):
    default = np.array([0.0]*10)
    default[index[0]] = 1
    return default

#從csv中讀取訓練數據
def read_data(filename):
    train_data_df = pd.read_csv(filename, sep=',', header=None)
    label = train_data_df.iloc[:,0:1].values
    label = np.array(list(map(one_hot, list(label))))
    
    feature = train_data_df.iloc[:,1:].values
    return label, feature

def generate_batch(feature, label, batch_size=1024):
    m = feature.shape[0]
    batch_num = math.ceil(m * 1.0 / batch_size)
    feature_batch_list = []
    label_batch_list = []
    for id in range(batch_num):
        label_batch_list.append(label[max(0,id * batch_size):min((id+1) * batch_size, m)])
        feature_batch_list.append(feature[max(0,id * batch_size):min((id+1) * batch_size, m)])
    return feature_batch_list, label_batch_list, batch_num 

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')


#定義模型結構
def cnn_model(args, label, feature):
    feature_num = feature.shape[1]
    label_size = label.shape[1]
    n = feature_num
    x = tf.placeholder(dtype="float", name='x', shape=[None, n]) 
    y = tf.placeholder(dtype="float", name='Y', shape=[None, label_size]) 
    x_reshape = tf.reshape(x, [-1, 28, 28, 1])
    Weights = {
        "w_conv1" : tf.Variable(tf.truncated_normal([5, 5, 1, 32], stddev=0.1), name = "Conv1_Weight"), 
        "w_conv2" : tf.Variable(tf.truncated_normal([5, 5, 32, 64], stddev=0.1), name = "Conv2_Weight"), 
        "w_fc1" : tf.Variable(tf.truncated_normal([7 * 7 * 64, 2000], stddev=0.1), name = "Fc1_Weight"), 
        "w_fc2" : tf.Variable(tf.truncated_normal([2000, 1000], stddev=0.1), name = "Fc2_Weight"), 
        "w_fc3" : tf.Variable(tf.truncated_normal([1000, 10], stddev=0.1), name = "Fc3_Weight")
    }
    Biases = {
        "b_conv1" : tf.Variable(tf.zeros([32])+ 0.1, name = "Conv1_Bias"), 
        "b_conv2" : tf.Variable(tf.zeros([64])+ 0.1, name = "Conv2_Bias"), 
        "b_fc1" : tf.Variable(tf.zeros([2000])+ 0.1, name = "Fc1_Bias"), 
        "b_fc2" : tf.Variable(tf.zeros([1000])+ 0.1, name = "Fc2_Bias"), 
        "b_fc3" : tf.Variable(tf.zeros([10])+ 0.1, name = "Fc3_Bias")
    }
    Conv1 = tf.nn.conv2d(x_reshape, Weights["w_conv1"], strides=[1, 1, 1, 1], padding = 'SAME')
    Conv1_active = tf.nn.relu(Conv1 + Biases["b_conv1"])
    Conv1_pooling = tf.nn.max_pool(Conv1_active, ksize = [1,2,2,1], strides = [1, 2, 2, 1], padding = 'SAME')
    Conv2 = tf.nn.conv2d(Conv1_pooling, Weights["w_conv2"], strides=[1, 1, 1, 1], padding = 'SAME')
    Conv2_active = tf.nn.relu(Conv2 + Biases["b_conv2"])
    Conv2_pooling = tf.nn.max_pool(Conv2_active, ksize = [1,2,2,1], strides = [1, 2, 2, 1], padding = 'SAME')
    Conv2_flat = tf.reshape(Conv2_pooling, [-1, 7 * 7 * 64])
    Fc1 = tf.nn.sigmoid(tf.matmul(Conv2_flat, Weights["w_fc1"]) + Biases["b_fc1"]) 
    #drop_out機制避免過擬合
    keep_prob = tf.placeholder(tf.float32)
    Fc1_dropout = tf.nn.dropout(Fc1, keep_prob)
    Fc2 = tf.nn.sigmoid(tf.matmul(Fc1_dropout, Weights["w_fc2"]) + Biases["b_fc2"]) 
    Fc2_dropout = tf.nn.dropout(Fc2, keep_prob)
    predict = tf.nn.softmax(tf.matmul(Fc2_dropout, Weights["w_fc3"]) + Biases["b_fc3"], name="predict")
    
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits = predict))
    opt = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
    correct_prediction=tf.argmax(predict,1,"correct_prediction")
    correct_labels=tf.argmax(y,1, name="correct_labels")
    
    accuracy=tf.reduce_mean(tf.cast(tf.equal(correct_prediction, correct_labels),tf.float32), name="accuracy")
    
    init = tf.global_variables_initializer()
    #saver = tf.train.Saver()
    with tf.Session() as sess:
        sess.run(init)
        feature_batch, label_batch, batch_num = generate_batch(feature, label, args.batch_size)
        for i in range(args.train_round):
            for batch_id in range(batch_num):
                _, l ,ty, ty_predict, oy, accuracy1 = sess.run([opt, loss, correct_labels,correct_prediction, y, accuracy], feed_dict={x:feature_batch[batch_id], y:label_batch[batch_id], keep_prob:0.5})
                print("Epoch: {0} Batch: {1} Loss: {2} accuracy{3}".format(i, batch_id * args.batch_size,  l, accuracy1))
        print("Done")

if __name__ == '__main__':
    args = parse_arg()
    label, feature = read_data(args.train_data_dir) 
    cnn_model(args, label, feature)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章