cifar-10-TensorFlow

數據集

    Cifar-10由60000張32*32的RGB彩色圖片構成,一共包含有飛機、汽車、鳥、貓、鹿、狗、青蛙、馬、船、卡車這10個類別。50000張訓練,10000張測試。
    比較知名的模型如AlexNet、NIN、ResNet等都曾在Cifar-10數據集上來評價自己的性能。
    它還有一姐妹級的數據集Cifar-100,顧名思義就是包含100個類別,數據更加複雜。關於Cifar數據集的相關介紹以及數據的下載可見官網。
    正是因爲Cifar-10數據集不大、類別明確、獲取方便、訓練簡單,同時模型的可參照性強,因此作爲深度學習的初學者作爲一個進階的內容,再適合不過了

import numpy as np
# 序列化和反序列化
import pickle
from sklearn.preprocessing import OneHotEncoder
import warnings
warnings.filterwarnings('ignore')
import tensorflow as tf
數據加載
def unpickle(file):
    import pickle
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='ISO-8859-1')
    return dict

# def unpickle(file):
#     import pickle
#     with open(file, 'rb') as fo:
#         dict = pickle.load(fo, encoding='bytes') #讀進來的是二進制
#     return dict

labels = []
X_train = []
for i in range(1,6):
    data = unpickle('./cifar-10-batches-py/data_batch_%d'%(i))
    labels.append(data['labels'])
    X_train.append(data['data'])
    
# 將list類型轉換爲ndarray
y_train = np.array(labels).reshape(-1) #0-9
X_train = np.array(X_train)

# reshape
X_train = X_train.reshape(-1,3072) #32*32*3=3072 50000個數據

# 目標值概率
one_hot = OneHotEncoder()
y_train =one_hot.fit_transform(y_train.reshape(-1,1)).toarray()
display(X_train.shape,y_train.shape)
#(50000, 3072)
#(50000, 10)

網絡結構

    conv1->relu1->pool1->conv2->relu2->pool2->conv3->relu3>pool3->fc1->dropout1->fc2->out. 三層網絡 兩個全連接層
    所有的卷積核採用的都是3x3大小, pool的核也是3x3,步長爲2x2.
    中間加入bn(batch_ normalization)層.batch_size設置成100, 迭代500次, 之後減小學習率. 歸一化

構建神經網絡
X = tf.placeholder(dtype=tf.float32,shape = [None,3072])
y = tf.placeholder(dtype=tf.float32,shape = [None,10])
kp = tf.placeholder(dtype=tf.float32)

### !!! 給成常量了
def gen_v(shape):
    return tf.Variable(tf.truncated_normal(shape = shape))
    #生成改進版的正態分佈 只要中間概率大的部分

def conv(input_,filter_,b):
    conv = tf.nn.relu(tf.nn.conv2d(input_,filter_,strides=[1,1,1,1],padding='SAME') + b)
    return tf.nn.max_pool(conv,[1,3,3,1],[1,2,2,1],'SAME')

def net_work(input_,kp):
    
#     形狀改變,4維
    input_ = tf.reshape(input_,shape = [-1,32,32,3])
#     第一層
    filter1 = gen_v(shape = [3,3,3,64])
    b1 = gen_v(shape = [64])
    conv1 = conv(input_,filter1,b1)
#     歸一化
    conv1 = tf.layers.batch_normalization(conv1,training=True)
    #layer 層 batch一批
#     第二層
    filter2 = gen_v([3,3,64,128])
    b2 = gen_v(shape = [128])
    conv2 = conv(conv1,filter2,b2)
    conv2 = tf.layers.batch_normalization(conv2,training=True)
    
#     第三層
    filter3 = gen_v([3,3,128,256])
    b3 = gen_v([256])
    conv3 = conv(conv2,filter3,b3)
    conv3 = tf.layers.batch_normalization(conv3,training=True)
    
#     第一層全連接層
    dense = tf.reshape(conv3,shape = [-1,4*4*256]) #數據形狀改變一下
    fc1_w = gen_v(shape = [4*4*256,1024])
    fc1_b = gen_v([1024])
    fc1 = tf.matmul(dense,fc1_w) + fc1_b
    fc1 = tf.layers.batch_normalization(fc1,training=True)
    fc1 = tf.nn.relu(fc1)
#     fc1.shape = [-1,1024]
     
#     dropout
    dp = tf.nn.dropout(fc1,keep_prob=kp) #保留比例
    
#     第二層全連接層
    fc2_w = gen_v(shape = [1024,1024])
    fc2_b = gen_v(shape = [1024])
    fc2 = tf.nn.relu(tf.layers.batch_normalization(tf.matmul(dp,fc2_w) + fc2_b,training=True))
    
#     輸出層
    out_w = gen_v(shape = [1024,10])
    out_b = gen_v(shape = [10])
    out = tf.matmul(fc2,out_w) + out_b
    return out
損失函數準確率
out = net_work(X,kp)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y,logits=out))

# 準確率
y_ = tf.nn.softmax(out)

# equal 相當於 == 
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y,axis = -1),tf.argmax(y_,axis = 1)),tf.float16))
#tf.cast([True,True,True,False,False,True])
#[1,1,1,0,1]
accuracy #準確率
#<tf.Tensor 'Mean_8:0' shape=() dtype=float16>
最後化
opt = tf.train.AdamOptimizer().minimize(loss)
opt
#<tf.Operation 'Adam_3' type=NoOp>
開啓訓練
epoches = 50000
saver = tf.train.Saver()
X_train.shape
y_train.shape
#(50000, 10)

index = 0
def next_batch(X,y):
    global index
    batch_X = X[index*128:(index+1)*128]
    batch_y = y[index*128:(index+1)*128]
    index+=1
    if index == 390: #50000//128=390 一批是128個數據
        index = 0
    return batch_X,batch_y

test = unpickle('./cifar-10-batches-py/test_batch')
y_test = test['labels']
y_test = np.array(y_test)
X_test = test['data']
y_test = one_hot.transform(y_test.reshape(-1,1)).toarray()
y_test[:10]
#array([[0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
#       [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
#       [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.]])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(epoches):
        batch_X,batch_y = next_batch(X_train,y_train)
        opt_,loss_ = sess.run([opt,loss],feed_dict = {X:batch_X,y:batch_y,kp:0.5})
        print('----------------------------',loss_)
        if i % 100 == 0:
            score_test = sess.run(accuracy,feed_dict = {X:X_test,y:y_test,kp:1.0})
            score_train = sess.run(accuracy,feed_dict = {X:batch_X,y:batch_y,kp:1.0})
            print('iter count:%d。mini_batch loss:%0.4f。訓練數據上的準確率:%0.4f。測試數據上準確率:%0.4f'%
                  (i+1,loss_,score_train,score_test))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章