深度學習tensorflow實戰筆記(1)全連線神經網路(FCN)訓練自己的資料(從txt檔案中讀取)

蒲衣翁發表於2018-04-03

      寫在前面的話:離上一次寫部落格已經有些日子了,以前的工程都是在caffe平臺下做的,caffe平臺雖然挺好用的,但是caffe主要用於做CNN,對於其它的網路模型用起來不太方便,所以博主轉戰tensorflow,Google對待tensorflow就想當年對待Android一樣,雖然現在推出了很多其它機器學習(深度學習)框架,不過tensorflow的便利性還是很值得稱讚的,最起碼博主感覺上手很容易的。

      tensorflow平臺用於機器學習或者深度學習的程式碼大多數是基於mnist或者cifar-10等標準資料集的,這種資料集封裝了標註格式,tf平臺都有專門的針對這類資料處理操作,但是要想訓練自己的資料,並不是一件容易的事情,博主倒弄了幾天,終於跑通了如果用多層感知機以及卷積神經網路訓練自己的資料,包括資料讀入、測試、特徵提取等操作。本篇部落格主要介紹如何從txt檔案中讀取自己的資料,用於訓練多層感知機,後續的部落格介紹如何處理影像資料,以及CNN的相關內容。都是一些非常實用的乾貨。

1、準備資料

     把資料放進txt檔案中(資料量大的話,就寫一段程式自己把資料自動的寫入txt檔案中,任何語言都能實現),資料之間用逗號隔開,最後一列標註資料的標籤(用於分類),比如0,1。每一行表示一個訓練樣本。如下圖所示。

其中前三列表示資料(特徵),最後一列表示資料(特徵)的標籤。注意:標籤需要從0開始編碼!

2、實現全連線網路

      這個過程我就不多說了,如何非常簡單,就是普通的程式碼實現,本篇部落格的重點在於使用自己的資料,有些需要注意的地方我在後面會做註釋。直接上程式碼

#隱含層引數設定
in_units=3  #輸入神經元個數
h1_units=5  #隱含層輸出神經元個數

#第二個隱含層神經元個數
h2_units=6


W1=tf.Variable(tf.truncated_normal([in_units,h1_units],stddev=0.1)) #隱含層權重,W初始化為截斷正態分佈
b1=tf.Variable(tf.zeros([h1_units]))  #隱含層偏執設定為0
W2=tf.Variable(tf.truncated_normal([h1_units,h2_units],stddev=0.1)) #第二個隱含層權重,W初始化為截斷正態分佈
b2=tf.Variable(tf.zeros([h2_units]))  #第二個隱含層偏執設定為0

W3=tf.Variable(tf.zeros([h2_units,2])) #輸出層權重和偏執都設定為0
b3=tf.Variable(tf.zeros([2]))

#定義輸入變數x和dropout比率
x=tf.placeholder(tf.float32,[None,3]) #列是
keep_prob=tf.placeholder(tf.float32)

#定義一個隱含層
hidden1=tf.nn.relu(tf.matmul(x,W1)+b1)
hidden1_drop=tf.nn.dropout(hidden1,keep_prob)

#定義第二個隱藏層
hidden2=tf.nn.relu(tf.matmul(hidden1_drop,W2)+b2)
hidden2_drop=tf.nn.dropout(hidden2,keep_prob)
需要注意的地方:
in_units=3  #輸入神經元個數,和特徵的維度對應起來
x=tf.placeholder(tf.float32,[None,3]) #和特徵的維度對應起來

3、實現損失函式

      標準的softmax和交叉熵,不多說了。    

y=tf.nn.softmax(tf.matmul(hidden2_drop,W3)+b3)

#定義損失函式和選擇優化器
y_=tf.placeholder(tf.float32,[None,2])  #列是2,表示兩類,行表示輸入的訓練樣本個數,None表示不定

corss_entropy=tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y),reduction_indices=[1]))
train_step=tf.train.AdagradOptimizer(0.3).minimize(corss_entropy)

       需要注意的地方:

y_=tf.placeholder(tf.float32,[None,2])  #有幾類就寫幾,我寫的是兩類,所以就是2

4、從txt中讀取資料,並做處理

    重點來了,首先從txt中把資料讀取出來,然後對標籤進行獨熱編碼,什麼是獨熱編碼?索引表示類別,是哪個類別這一維就是非零(用1)。程式碼實現:

data=np.loadtxt('txt.txt',dtype='float',delimiter=',')

#將樣本標籤轉換成獨熱編碼
def label_change(before_label):
    label_num=len(before_label)
    change_arr=np.zeros((label_num,2))  #2表示有兩類
    for i in range(label_num):
        #該樣本標籤資料要求從0開始
            change_arr[i,int(before_label[i])]=1
    return change_arr

#用於提取資料
def train(data):
    data_train_x=data[:7,:3]   #取前幾行作為訓練資料,7表示前7行,3表示取前三列,排除資料標籤
    data_train_y=label_change(data[:7,-1])
    return data_train_x,data_train_y


data_train_x,data_train_y=train(data)

需要注意的地方在程式碼中我都做了註釋,不再贅述。

5、開始訓練和測試

訓練部分
for i in range(5):  #迭代,取batch進行訓練
   img_batch, label_batch = tf.train.shuffle_batch([data_train_x, data_train_y],   #隨機取樣本
                                                    batch_size=2,
                                                    num_threads=2,
                                                    capacity=7,
                                                    min_after_dequeue=2,
                                                    enqueue_many=True)
   coord = tf.train.Coordinator()  
   threads = tf.train.start_queue_runners(coord=coord, sess=sess) 


   img_batch,label_batch=sess.run([img_batch,label_batch])

   train_step.run({x:img_batch,y_:label_batch,keep_prob:0.75}    
#預測部分
correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
print(accuracy.eval({x:data_train_x,y_:data_train_y,keep_prob:1.0}))   

     這樣就全部流程完成。其中網路結構可以做相應的修改,核心在於如何從txt中讀取自己的資料輸入到全連線神經網路(多層感知機)中進行訓練和測試。

當然,也可以在定義變數的時候直接輸入,不用從txt中讀取。即:

image=[[1.0,2.0,3.0],[9,8,5],[9,5,6],[7,5,3],[6,12,7],[8,3,6],[2,8,71]]  
label=[[0,1],[1,0],[1,0],[1,0],[1,0],[0,1],[0,1]]        
image_test=[[9,9,9]]     
label_test=[[0,1]] 

  直接定於資料的話,適合小資料量的情況,大資料量的情況並不適用。

  好了,本篇部落格介紹到此結束。下一篇介紹如何處理影像資料。

相關文章