1. 程式人生 > >使用Tensorflow來讀取訓練自己的資料(二)

使用Tensorflow來讀取訓練自己的資料(二)

接上一篇,繼續分析,model.py,也就是模型的構建。兩個卷積層,兩個池化層,以及後面的全連線層怎麼通過tensorflow定義的。

import tensorflow as tf

def inference(images, batch_size, n_classess):
    # conv1,shape=[kernel size, kernel size, channels, kernel numbers]
    # 第一個卷積層
    # tf.variable_scope() 主要結合 tf.get_variable() 來使用,實現變數共享。下次呼叫不用重新產生,這樣可以儲存引數
with tf.variable_scope('conv1') as scope: #初始化權重,[3,3,3,16] weights = tf.get_variable('weights', shape = [3, 3, 3, 16], dtype = tf.float32, initializer = tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32)) #tf.truncated_normal隨機數生成函式,此外還有tf.random_normal, tf.random_uniform, tf.random_gamma
#初始化偏置,16個 biases = tf.get_variable('biases', shape=[16], dtype = tf.float32, initializer = tf.constant_initializer(0.1)) #tf.constant_initializer初始化常數,通常偏置項都是用它初始化 # 實現卷積運算,第一個引數輸入影象,[batch, in_height, in_width, in_channels]這樣的shape, # 具體含義是[訓練時一個batch的圖片數量, 圖片高度, 圖片寬度, 影象通道數],注意這是一個4維的Tensor,要求型別為float32和float64其中之一
# 第二個引數filter:相當於CNN中的卷積核,它要求是一個Tensor,具有[filter_height, filter_width, in_channels, out_channels]這樣的shape, # 具體含義是[卷積核的高度,卷積核的寬度,影象通道數,卷積核個數], # 第三個引數strides:卷積時在影象每一維的步長,這是一個一維的向量,長度4 # 第四個引數padding:string型別的量,只能是"SAME","VALID"其中之一,這個值決定了不同的卷積方式 # 結果返回一個Tensor,這個輸出,就是我們常說的feature map,shape仍然是[batch, height, width, channels]這種形式 conv = tf.nn.conv2d(images, weights, strides=[1,1,1,1], padding='SAME') # 將偏置加在所得的值上面 pre_activation = tf.nn.bias_add(conv, biases) # 將計算結果通過relu啟用函式完成去線性化 conv1 = tf.nn.relu(pre_activation, name= scope.name) # pool1 and norm1 # 池化層 with tf.variable_scope('pooling1_lrn') as scope: # tf.nn.max_pool實現了最大池化層的前向傳播過程,引數和conv2d類似,ksize過濾器的尺寸 pool1 = tf.nn.max_pool(conv1, ksize=[1,3,3,1],strides=[1,2,2,1],padding='SAME',name='poolong1') # 區域性響應歸一化(Local Response Normalization),一般用於啟用,池化後的一種提高準確度的方法。 norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1, alpha=0.001/9.0, beta=0.75, name='norm1') # conv2第二卷積層 # 計算過程和第一層一樣,唯一區別為名稱空間 with tf.variable_scope('conv2') as scope: weights = tf.get_variable('weights', shape=[3,3,16,16], dtype=tf.float32, initializer=tf.truncated_normal_initializer(stddev=0.1,dtype=tf.float32)) biases = tf.get_variable('biases', shape=[16], dtype=tf.float32, initializer=tf.constant_initializer(0.1)) conv = tf.nn.conv2d(norm1, weights, strides=[1,1,1,1],padding='SAME') pre_activation = tf.nn.bias_add(conv, biases) conv2 = tf.nn.relu(pre_activation, name='conv2') # pool2 and norm2第二池化層 with tf.variable_scope('pooling2_lrn') as scope: norm2 = tf.nn.lrn(conv2, depth_radius=4,bias=1,alpha=0.001/9,beta=0.75,name='norm2') pool2 = tf.nn.max_pool(norm2, ksize=[1,3,3,1],strides=[1,1,1,1],padding='SAME',name='pooling2') # local3全連線層 with tf.variable_scope('local3') as scope: # -1代表的含義是不用我們自己指定這一維的大小,函式會自動計算 reshape = tf.reshape(pool2, shape=[batch_size, -1]) # 獲得reshape的列數,矩陣點乘要滿足列數等於行數 dim = reshape.get_shape()[1].value weights = tf.get_variable('weights', shape=[dim,128],dtype=tf.float32,initializer=tf.truncated_normal_initializer(stddev=0.005,dtype=tf.float32)) biases = tf.get_variable('biases',shape=[128], dtype=tf.float32,initializer=tf.constant_initializer(0.1)) local3 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name=scope.name) # local4全連線層 with tf.variable_scope('local4') as scope: weights = tf.get_variable('weights',shape=[128,128],dtype=tf.float32,initializer=tf.truncated_normal_initializer(stddev=0.005,dtype=tf.float32)) biases = tf.get_variable('biases', shape=[128],dtype=tf.float32, initializer=tf.constant_initializer(0.1)) local4 = tf.nn.relu(tf.matmul(local3,weights) + biases, name = 'local4') # softmax邏輯迴歸 with tf.variable_scope('softmax_linear') as scope: weights = tf.get_variable('softmax_linear',shape=[128, n_classess],dtype=tf.float32,initializer=tf.truncated_normal_initializer(stddev=0.005,dtype=tf.float32)) biases = tf.get_variable('biases',shape=[n_classess],dtype=tf.float32,initializer=tf.constant_initializer(0.1)) softmax_linear = tf.add(tf.matmul(local4, weights),biases,name='softmax_linear') return softmax_linear # 定義損失函式,定義傳入值和標準值的差距 def losses(logits, labels): with tf.variable_scope('loss') as scope: # 計算使用了softmax迴歸後的交叉熵損失函式 # logits表示神經網路的輸出結果,labels表示標準答案 cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels,name='xentropy_per_example') # 求cross_entropy所有元素的平均值 loss = tf.reduce_mean(cross_entropy, name='loss') # 對loss值進行標記彙總,一般在畫loss, accuary時會用到這個函式。 tf.summary.scalar(scope.name+'/loss',loss) return loss # 通過梯度下降法為最小化損失函式增加了相關的優化操作 def trainning(loss, learning_rate): with tf.name_scope('optimizer'): # 在訓練過程中,先例項化一個優化函式,比如tf.train.GradientDescentOptimizer,並基於一定的學習率進行梯度優化訓練 optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) # 設定一個用於記錄全域性訓練步驟的單值 global_step = tf.Variable(0, name='global_step',trainable=False) # 新增操作節點,用於最小化loss,並更新var_list,返回為一個優化更新後的var_list,如果global_step非None,該操作還會為global_step做自增操作 train_op = optimizer.minimize(loss, global_step=global_step) return train_op # 定義評價函式,返回準確率 def evaluation(logits, labels): with tf.variable_scope('accuracy') as scope: correct = tf.nn.in_top_k(logits,labels,1) # 計算預測的結果和實際結果的是否相等,返回一個bool型別的張量 # K表示每個樣本的預測結果的前K個最大的數裡面是否含有target中的值。一般都是取1。 # 轉換型別 correct = tf.cast(correct, tf.float16) accuracy = tf.reduce_mean(correct) #取平均值,也就是準確率 # 對準確度進行標記彙總 tf.summary.scalar(scope.name+'/accuracy',accuracy) return accuracy