tensorlfow初學--mnist手寫數字識別

mmnist手寫數據集

不知道爲什麼就入了tensorflow的坑,然後一個人沒事就漸漸的學了起來,感覺雖然剛開始各種不懂,但漸漸的有了一些興趣了。記錄一下,算是備忘。


#tensoflow_mnist v1


#-------------------------------------------------------------------------------------------------
# import tensorflow as tf
# from tensorflow.examples.tutorials.mnist import input_data
# mnist=input_data.read_data_sets('mnist_test',one_hot=True)

# image_size=28
# labels_size=10
# learning_rate=0.05
# steps_number=1000
# batch_size=100

# training_data=tf.placeholder(tf.float32,[None,image_size*image_size])
# labels=tf.placeholder(tf.float32,[None,labels_size])

# W=tf.Variable(tf.truncated_normal([image_size*image_size,labels_size],stddev=0.1))
# b=tf.Variable(tf.constant(0.1,shape=[labels_size]))


# output=tf.matmul(training_data,W)+b

# loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=output))

# #train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
# #優化
# train_step=tf.train.AdamOptimizer(learning_rate).minimize(loss)


# correct_prediction=tf.equal(tf.argmax(output,1),tf.argmax(labels,1))
# accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

# with tf.Session() as sess:
#     sess.run(tf.global_variables_initializer())
#     for i in range (steps_number):
#         input_batch,labels_batch=mnist.train.next_batch(batch_size)
#         feed_dict={training_data:input_batch,labels:labels_batch}
#         train_step.run(feed_dict=feed_dict)
#         if i%100==0:
#             train_accuracy=accuracy.eval(feed_dict=feed_dict)
#             print("step %d ,training batch accuracy : %g"%(i,train_accuracy*100))
            
#             test_accuracy=accuracy.eval(feed_dict={training_data:mnist.test.images,labels:mnist.test.labels})
#             print("Test accuracy : %g"%(test_accuracy*100))
#----------------------------------------------------------------------------------




#tensorflow_mnist v2

#---------------------------------------------------------------------------------
import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data


#輸入層節點--圖像像素
INPUT_NODE = 784
#輸出層節點--類別數目0-9
OUTPUT_NODE = 10
#單隱藏層節點500
LAYER1_NODE=500
#一個訓練batch中的訓練數據個數
BATCH_SIZE=100
#基本學習率
LEARNING_RATE_BASE=0.8  
#學習率衰減值
LEARNING_RATE_DECAY=0.99
#描述模型複雜度正則化在損失函數中的係數
REGULARIZATION_RATE=0.0001
#訓練輪數
TRAINING_STEPS=3000
#滑動平均衰減率
MOVING_AVERAGE_DACAY=0.99



#定義了一個輔助函數,給定神經網路的輸入輸出所有參數,計算神經網絡的前向傳播結果
def inference(input_tensor,avg_class,weights1,biases1,weights2,biases2):
    #如果沒有提供滑動平均類
    if avg_class==None:
        #使用relu計算前向傳播結果
        layer1=tf.nn.relu(tf.matmul(input_tensor,weights1)+biases1)
        return tf.matmul(layer1,weights2)+biases2
    else:
        #根據avg.average計算變量的滑動平均值,在計算前向傳播結果
        layer1=tf.nn.relu(tf.matmul(input_tensor,avg_class.average(weights1))+avg_class.average(biases1))
        return tf.nn.relu(tf.matmul(layer1,avg_class(weights2))+avg_class(biases2))



def train(mnist):
    x=tf.placeholder(tf.float32,[None,INPUT_NODE],name='x-input')
    y_=tf.placeholder(tf.float32,[None,OUTPUT_NODE],name='y-input')
    #生成隱藏層參數
    weights1=tf.Variable(tf.truncated_normal([INPUT_NODE,OUTPUT_NODE],stddev=0.1))
    biases1=tf.Variable(tf.constant(0.1,shape=[LAYER1_NODE]))
    #生成輸出層參數
    weights2=tf.Variable(tf.truncated_normal([LAYER1_NODE,OUTPUT_NODE],stddev=0.1))
    biases2=tf.Variable(tf.constant(0.1,shape=[OUTPUT_NODE]))
    y=inference(x,None,weights1,biases1,weights2,biases2)


    #定義存儲訓練輪數的變量
    global_step=tf.Variable(0,trainable=False)
    #初始化滑動平均類
    variable_average=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DACAY,global_step)
    variable_average_op=variable_average.apply(tf.trainable_variables())
    average_y=inference(x,variable_average,weights1,biases1,weights2,biases2)
    #計算交叉熵:損失函數
    #採用sparse_softmax_cross_entropy_with_logits函數計算交叉熵,當分類問題只有一個答案時可以使用這個計算交叉熵。
    cross_entropy = tf.nn.sparse_softmax_cross_entropy(
        labels=y, logits=tf.argmax(y_,1))
    #計算交叉熵損失
    cross_entropy_mean=tf.reduce_mean(cross_entropy)
    #計算L2正則化損失
    regularizer=tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
    #計算模型的正則化損失
    regularization=regularizer(weights1)+regularizer(weights2)
    #計算總的損失
    loss=cross_entropy_mean+regularization
    #設置指數衰減的學習率
    learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,                #基礎學習率
    global_step,                                                                #迭代輪數
    mnist.train.num_examples/BATCH_SIZE,                                        #訓練所有的數據需要的迭代次數
    LEARNING_RATE_DECAY)                                                        #學習率衰減速度

    #優化算法來優化損失函數
    train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step)
    with tf.control_dependencies([train_step,variable_average_op]):
        train_op=tf.no_op(name='train')
    correct_prediction=tf.equal(tf.argmax(average_y,1),tf.argmax(y_,1))
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
    with tf.Session() as sess:
        tf.initialize_all_variables.run()
        validate_feed={x:mnist.validate.images,y_:mnist.validate.labels}
        test_feed={x:mnist.test.images,y_:mnist.test.labels}
        for i in range(TRAINING_STEPS):
            if i%1000==0:
                validate_acc=sess.run(accuracy,feed_dict=validate_feed)
                print('after %d training steps,validation accuracy ','using average model is %g'%(i,validate_acc))
            #產生batch
            xs,ys=mnist.train_next_batch(BATCH_SIZE)
            sess.run(train_op,feed_dict={x:xs,y_:ys})
        #驗證最終的正確率
        test_acc=sess.run(accuracy,feed_dict=test_feed)
        print('after %d training steps,validation accuracy ','using average model is %g'%(i,test_acc))


def main():
    mnist=input_data.read_data_sets('mnist',one_hot=True)
    train=(mnist)

if __name__=='__main__':
    tf.app.run()
        




一些重要的函數

1.激活函數(前向傳播,產生一個結果)

線性激活函數和激活函數去線性化
一般需要對線性函去線性化,tensorflow中定義了7中非線性激活函數tf.nn.relu,tf.sigmoid,tf.tanh等

2.損失函數(計算得到的結果和正確值之間的差距)

1損失函數包括經典的softmax等損失函數,通過將前向傳播的結果作爲輸入,產生一個不同類別概率輸出。

3.反向傳播 梯度下降(神經網絡優化)

梯度下降就是通過不斷調節參數,使總損失朝着更小的方向移動,這裏的小有可能是局部最小。由於損失計算太過耗時,爲了加速計算,出現了隨機梯度下降,這種算法優化的不是全部訓練數據的損失,而是在每一輪迭代中,隨機優化某一條數據上的損失,這樣每一輪參數更新的速度就加快了,缺點,因爲不是全部數據,所以無法達到全局最優,甚至無法到達局部最優。
爲了綜和梯度下降和隨機梯度下降,採取了折中的策略——每次計算一小部分訓練數據的損失函數,也就是batch_size,在一個batch上優化參數速度快,且在全局可減小收斂迭代次數,有點分治的感覺

4.補充(神經網絡的進一步優化)

聽過設置學習率控制參數更新的幅度,不宜過大,也不宜過小,過大不容易收斂,過小太過耗時,收斂較慢,tensorflow中給出了設置學習率的方法——指數衰減法,它會隨着迭代的繼續減小學習率,使得衰減趨於平緩

5.正則化(過擬合問題)

過擬合就是訓練出來的的模型可能對訓練數據刻畫的太好,而對時間數據的預測卻並不能很好的預測。正則化就是在損失函數中加入刻畫模型複雜度的指標。R(w)=J(θ)+λR(w)R(w)=J(\theta)+\lambda*R(w)。其中R(w)刻畫的是模型的複雜程度,λ\lambda是權重。這裏的θ\theta值得是神經網路所有的參數。一般模型複雜度由w決定。常見的刻畫模型複雜度的函數R(w)R(w)有兩種,一種是L1L1正則化R(w)=w1=iwiR(w)=||w||_1=\sum_i|w_i|
L2L2正則化
R(w)=w22=iwi2R(w)=||w||_2^2=\sum_i|w_i^2|
正則化就是通過限制權重的大小防止模型任意擬合隨機噪聲L1L1會讓參數變得稀疏,L2L2則不會,相對來說L2L2更爲簡潔在實際中需要結合二者R(w)=iαwi+(1α)wi2R(w)=\sum_i\alpha|w_i|+(1-\alpha)*w_i^2

滑動平均模型

滑動平均模型可使模型在測試數據數據上更加健壯,在使用梯度下降時使用滑動平均模型可以提高模型在測試集上的表現tensorflow提供了tf.ExponentialMovingAverage來實現滑動平均模型,在初始化ExponentialMovingAverage需要提供decay(衰減率),這個衰減率用於控制模型更新的速率。ExponentialMovingAverage會爲每個參數維護一個影子變量,每次更新變量都會更新影子變量

總結

總結一下自己對於神經網絡的瞭解
首先,神經網絡分爲輸入層,隱藏層,輸出層,每層都有一個維度,也就是這裏的每層的節點,這裏想說一下batch_size
batch_size:每次訓練的樣本數
如果設置的過大
1.對內存要求較高
2.訓練到一定程度參數便變化不大,梯度下降方向也不變了
如果設置的過小
收斂困難,每次修正參數都會有比較大的變化
再就是前向傳播產生預測值,通過反向傳播更新參數,達到訓練目的則停止訓練,反之,則重新取下一個樣本進行訓練,最後得到結果

感受

感覺今天比較開心吧,想學習更多,備戰明年的數模。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章