【Python】製作LMDB數據集文件(文件統一命名-數據增強-獲取train.txt和test.txt)LMDB文件時會出現killed問題

學習點:

          製作LMDB數據集需要分類好的原始圖像文件夾、對應的txt文件、還可能有mean均值文件,所以寫了一個腳本文件生成LMDB數據集需要的train.txt和val.txt文件,並針對小樣本進行了數據增強,平移旋轉亮度等操作。

1、原始數據源

        根據上圖可知,我們需要將每個類的名稱改稱從0開始的,所以先保存類列表到word.txt中,根據.重命名類名稱,修改後的文件類表如右圖所示:對應的這部分代碼爲:

#將每個分類的名稱寫入word.txt 86.Betta picta ( Spotted betta )-6334,並以開頭數字作爲文件夾的新名稱
def save_and_rename_file():
    with open('./words.txt', 'w') as f:
        #os.walk()根據你要遍歷的總目錄地址,返回:root 文件夾的本身地址;dirs:該文件夾內所有目錄的名字-list
        #files:該文件夾中所有的文件(不包括子目錄)
        for root, dirs, files in os.walk(data_dir):
            for dir in dirs:
                print(dir)
                f.write(dir + "\n")
                new_name = str(int(dir.split('.')[0]))
                os.rename(os.path.join(data_dir, dir), os.path.join(data_dir, new_name))

      保存的word.txt內容爲:

2、形成train.txt和al.txt文件

2.1 首先獲得總目錄下的所有文件,並寫入到all_image.txt文件夾中,代碼如下

#創建對應的數據集txt文檔
def create_dataset(txt_file):
    dirs = os.listdir(data_dir)
    with open(txt_file, 'w') as f:
        for dir in dirs:
            #caffe標籤從0開始,否則會出現錯誤
            label = int(dir) - 1
            #遍歷子文件夾內容
            for file in os.listdir(os.path.join(data_dir, dir)):
                # check image format;取文件的屬性一屆
                prefix = file.split('.')[-1]
                #如果不是圖像則進入下次判斷
                if prefix not in ['jpg', 'JPG', 'png', 'PNG']:
                    continue
                # check is valid image
                file_path = os.path.join(data_dir, dir, file)
                if not is_valid_image(file_path):
                    continue
                #打標籤 42/3a5d40992dba684c665f536ec7c52ecc.jpg 41
                f.write(dir+'/'+file + " " + str(label) + "\n")

這樣即形成了初始的txt文件,內容如下

2.2 數據增強

由於我們的樣本比較少,這裏我們對數據集進行了數據增強(旋轉,亮度)代碼如下,效果如下

#擴增數據集
def do_img_aument(txt_file):
    images = list()
    paths = list()
    count = 0
    with open(txt_file, 'r') as f:
        for line in f:
            file = line.split(" ")[0]
            path = os.path.join(data_dir, file)
            paths.append(path)
            img = cv.imread(path)
            images.append(img)
            count = count + 1
            #隨機增強,每過20就對累計圖像作一次擴增,相當於線程池
            if count % 20 == 0:
                print("do image augment")
                new_images = img_aug(images)
                for j in range(len(new_images)):
                    new_img = new_images[j]
                    new_path = paths[j].split(".")[0] + "_aug.jpg"
                    print(new_path)
                    cv.imwrite(new_path, new_img)
                #清空池
                images = []
                paths = []

2.3 形成train.txt和val.txt文件

注意:這裏需要將數據集打亂才能得到比較好的結果,我數據集和驗證集的比例爲[8:2],代碼如下

#根據得到總的數據集,從中分離出一部分作爲驗證集[8:2]
def split_trainval(txt_file):
    data_set = list()
    with open(txt_file, 'r') as f:
        for line in f:
            data_set.append(line)
    #打亂順序
    random.shuffle(data_set)
    #得到總的大小
    size = len(data_set)
    train_size = int(size * 0.8)
    train_set = data_set[0:train_size]
    valid_set = data_set[train_size:]
#   將結果分別存入對應的訓練集和測試集
    with open('./train.txt', 'w') as f:
        for data in train_set:
            f.write(data)
    with open('./val.txt', 'w') as f:
        for data in valid_set:
            f.write(data)

效果如圖所示:

2.4label映射

根據第一部獲取的word.txt,我們將label和Class進行映射,這樣最後會方便我的尋找【0,1,2】表示的是什麼類別,代碼如下

#打標籤 [0,1,2,3]-[XXX的種類]
def make_labels():
    labels = list()
    with open("./words.txt", 'r') as f:
        for line in f:
            class_numb = int(line.split('.')[0]) - 1
            class_name = line.split('.')[-1].split(" ")[0]
            labels.append(str(class_numb) + " " + class_name)
    with open("./labels.txt", 'w') as f:
        for label in labels:
            f.write(label + "\n")

3、製作均值文件

執行一段代碼caffe代碼就可以,比較簡單,

#!/usr/bin/env sh
# Compute the mean image from the imagenet training lmdb
# N.B. this is available in data/ilsvrc12

EXAMPLE=examples/fishes
DATA=data/fishes
TOOLS=build/tools

$TOOLS/compute_image_mean $EXAMPLE/train_lmdb \
  $DATA/imagenet_mean.binaryproto

echo "Done."

4、製作LMDB 文件

     基本條件滿足後,就開始製作LMDB文件了,製作也是比較簡單,網上都有,這裏簡單說一下過程:

1、執行caffe-example文件下的create_imagenet.sh文件(創建均值文件是第二個)

2、執行後就可以看到效果了。這裏在說一下文件裏面的內容

代碼中resize一般要設置爲Resize=true;不然製作LMDB文件時會出現killed,這並不是CNN要求,主要是最後連接層的原因,後面的圖像就可以置爲false。具體可以網上搜索一下:resize爲什麼需要設置爲true?剩下的就是路徑的問題了。我們可以用心去看看EXAMPLE-DATA-TOOLS對應的什麼?其中tools比較好理解就是caffe的工具;data主要是你訓練集的總目錄和下面的TRAIN_DATA_ROOT /VAL_DATA_ROOT相關(可以從目錄中看出存在父子關係);EXAMPLE就和LMDB文件的存放相關了。

 

 

 

 

 

原始的數據源名稱是比較亂的,但是caffe分類需要從0開始,不然會報錯, 

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