【3】caffe的python介面學習:生成配置檔案
阿新 • • 發佈:2018-11-09
caffe是C++語言寫的,可能很多人不太熟悉,因此想用更簡單的指令碼語言來實現。caffe提供matlab介面和python介面,這兩種語言就非常簡單,而且非常容易進行視覺化,使得學習更加快速,理解更加深入。
以上這些操作都是訓練之前的預處理操作,不管是用什麼介面,都要用到。
首先,我們需要掌握的,就是如何寫配置檔案,通過下面的程式碼來學習:
#!/usr/bin/env python # encoding: utf-8 ''' @author: lele Ye @contact:
[email protected] @software: pycharm 2018.2 @file: 01LMDB和配置生成網路檔案.py @time: 2018/10/12 19:27 @desc: ''' from caffe import layers as L, params as P, to_proto import os path = '/home/yeler082/caffe_learning/data/' # 儲存資料和配置檔案的路徑 train_lmdb = path + 'train_db' # 訓練資料LMDB檔案的位置 val_lmdb = path + 'val_db' # 驗證資料LMDB檔案的位置 mean_file = path + 'mean.binaryproto' # 均值檔案的位置 train_proto = path + 'train.prototxt' # 生成的訓練配置檔案儲存的位置 val_proto = path + 'val.prototxt' # 生成的驗證配置檔案儲存的位置 # 編寫一個函式,用於生成網路 def create_net(lmdb, batch_size, include_acc=False): # 建立第一層:資料層。向上傳遞兩類資料:圖片資料和對應的標籤 data, label = L.Data(source=lmdb, backend=P.Data.LMDB, batch_size=batch_size, ntop=2, transform_param=dict(crop_size=40, mean_file=mean_file, mirror=True)) # 建立第二屋:卷積層 conv1 = L.Convolution(data, kernel_size=5, stride=1, num_output=16, pad=2, weight_filler=dict(type='xavier')) # 建立啟用函式層 relu1 = L.ReLU(conv1, in_place=True) # 建立池化層 pool1 = L.Pooling(relu1, pool=P.Pooling.MAX, kernel_size=3, stride=2) conv2 = L.Convolution(pool1, kernel_size=3, stride=1, num_output=32, pad=1, weight_filler=dict(type='xavier')) relu2 = L.ReLU(conv2, in_place=True) pool2 = L.Pooling(relu2, pool=P.Pooling.MAX, kernel_size=3, stride=2) # 建立一個全連線層 fc3 = L.InnerProduct(pool2, num_output=1024, weight_filler=dict(type='xavier')) relu3 = L.ReLU(fc3, in_place=True) # 建立一個dropout層 drop3 = L.Dropout(relu3, in_place=True) fc4 = L.InnerProduct(drop3, num_output=10, weight_filler=dict(type='xavier')) # 建立一個softmax層 loss = L.SoftmaxWithLoss(fc4, label) if include_acc: # 在訓練階段,不需要accuracy層,但是在驗證階段,是需要的 acc = L.Accuracy(fc4, label) return to_proto(loss, acc) else: return to_proto(loss) def write_net(): if not os.path.exists(path): os.mkdir(path) # 將以上的設定寫入到prototxt檔案 with open(train_proto, 'w') as f: f.write(str(create_net(train_lmdb, batch_size=64))) # 寫入配置檔案 with open(val_proto, 'w') as f: f.write(str(create_net(val_lmdb, batch_size=32, include_acc=True))) if __name__ == '__main__': write_net() print ("generate the prototxt in "+path)
通過上面這個檔案的執行,我們就會得到兩個配置檔案:train.prototxt和val.prototxt,分別用於訓練階段和驗證階段。
這種方式生成配置檔案,必須有個前提,就是要先把原始圖片轉換成LMDB檔案才行。如果我們已經把原始圖片做成了一個列表清單(txt檔案,一行一張圖片),則可以不用LMDB格式作為輸入資料,可以用ImageData作為資料來源輸入,程式碼如下:
#!/usr/bin/env python # encoding: utf-8 ''' @author: lele Ye @contact: [email protected] @software: pycharm 2018.2 @file: 02txt和配置生成網路檔案.py @time: 2018/10/12 19:41 @desc: ''' from caffe import layers as L, params as P, to_proto import os path = '/home/yeler082/caffe_learning/data/' train_list = path + 'train.txt' val_list = path + 'val.txt' train_proto = path + 'train_02.prototxt' val_proto = path + 'val_02.prototxt' def create_net(img_list, batch_size, include_acc=False): data, label = L.ImageData(source=img_list, batch_size=batch_size, new_width=48, new_height=48, ntop=2, transform_param=dict(crop_size=40, mirror=True)) conv1 = L.Convolution(data, kernel_size=5, stride=1, num_output=16, pad=2, weight_filler=dict(type='xavier')) relu1 = L.ReLU(conv1, in_place=True) pool1 = L.Pooling(relu1, pool=P.Pooling.MAX, kernel_size=3, stride=2) conv2 = L.Convolution(pool1, kernel_size=53, stride=1, num_output=32, pad=1, weight_filler=dict(type='xavier')) relu2 = L.ReLU(conv2, in_place=True) pool2 = L.Pooling(relu2, pool=P.Pooling.MAX, kernel_size=3, stride=2) conv3 = L.Convolution(pool2, kernel_size=53, stride=1, num_output=32, pad=1, weight_filler=dict(type='xavier')) relu3 = L.ReLU(conv3, in_place=True) pool3 = L.Pooling(relu3, pool=P.Pooling.MAX, kernel_size=3, stride=2) fc4 = L.InnerProduct(pool3, num_output=1024, weight_filler=dict(type='xavier')) relu4 = L.ReLU(fc4, in_place=True) drop4 = L.Dropout(relu4, in_place=True) fc5 = L.InnerProduct(drop4, num_output=7, weight_filler=dict(type='xavier')) loss = L.SoftmaxWithLoss(fc5, label) if include_acc: acc = L.Accuracy(fc5, label) return to_proto(loss, acc) else: return to_proto(loss) def write_net(): if not os.path.exists(path): os.mkdir(path) # with open(train_proto, 'w') as f: f.write(str(create_net(train_list, batch_size=64))) # with open(val_proto, 'w') as f: f.write(str(create_net(val_list, batch_size=32, include_acc=True))) if __name__ == '__main__': write_net() print ("generate the prototxt in "+path)
這是利用第二種方法生成的訓練配置檔案。
即第一層由原來的Data型別,變成了ImageData型別,不需要LMDB檔案和均值檔案,但需要一個txt檔案 。