嘗試解決cifar10問題


我理解這個問題和貓狗的不同,在於將2類擴展為10類,其它的地方我准備采用相同的方法。
注意事項:
1、我要用kaggle的數據集,而不是用其它的數據集;
2、最終得到的結果要以test為導向;

1、先打開jupyter,並且把數據集傳到dl_machine上去。想辦法讀入數據
通過觀察kaggle,可以發現pd的使用非常高,很大程度上是因為它對csv文件的支持非常好吧。
df =pd.read_csv( 'trainLabels.csv',header = 0,sep = ',')
#filename可以直接從盤符開始,標明每一級的文件夾直到csv文件,header=0表示頭部為空第一行為標題
#sep=','表示數據間分隔符是逗號
print df.head()
print df.tail()

2、能否將圖片數據讀入內存?
基本的思路就是遍歷圖片,然后根據名稱去找類別。
這其實是經常會遇到的問題。
TRAIN_DIR = './train/'
TEST_DIR = './test/'

tmp = df[(df.label == "airplane ")] 
train_airplane   =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_airplane", len(train_airplane))
tmp = df[(df.label == "automobile ")] 
train_automobile   =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_automobile", len(train_automobile))
tmp = df[(df.label == "bird ")] 
train_bird   =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_bird", len(train_bird))
tmp = df[(df.label == "cat")] 
train_cat =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_cat", len(train_cat))
tmp = df[(df.label == "deer")] 
train_deer =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_deer", len(train_deer))
tmp = df[(df.label == "dog")] 
train_dog   =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_dog", len(train_dog))
tmp = df[(df.label == "frog")] 
train_frog =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_frog", len(train_frog))
tmp = df[(df.label == "horse")] 
train_horse =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_horse", len(train_horse))
tmp = df[(df.label == "ship")] 
train_ship =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_ship", len(train_ship))
tmp = df[(df.label == "truck")] 
train_truck =  [TRAIN_DIR + str(i) + '.png' for i in a. id]
print( "train_truck", len(train_truck))
    
test_images =  [TEST_DIR + str(i) + '.png' for i in os.listdir(TEST_DIR)]
print( "test_images", len(test_images))
這個過程分為了a、獲得文件名;b、讀取文件。兩個部分。CIFAR還只是10類的,還可以手工編碼,如果是100位的,肯定就不能采用這種方法。
df =pd.read_csv( 'trainLabels.csv',header = 0,sep = ',')
train_airplane   =  [ str(i) + '.png' for i in df[(df.label == "airplane")]. id]
這種方法是正確、高效的,直接能夠獲得一個list,我希望的是能夠直接包含這些文件的絕對地址。
簡化的方法,當然是使用數組。但是現在我不適合手寫,最好去參考比較成熟的代碼。

3、看看,看看。我開始體會到為什么很多代碼里面都有“看看”這個步驟,因為你在編寫代碼的時候只有這種方式才能確保你的代碼編寫是正確的。

def show_cifar10(idx) :
    airplane     = read_image(train_airplane[idx])
    automobile   = read_image(train_automobile[idx])
    bird         = read_image(train_bird[idx])
    cat         = read_image(train_cat[idx])
    deer         = read_image(train_deer[idx])
    dog         = read_image(train_dog[idx])
    frog         = read_image(train_frog[idx])
    horse       = read_image(train_horse[idx])
    ship         = read_image(train_ship[idx])
    truck       = read_image(train_truck[idx])
    pair = np.concatenate((airplane, automobile,bird,cat,deer,dog,frog,horse,ship,truck), axis = 1)
    plt.figure(figsize =( 10, 5))
    plt.imshow(pair)
    plt.show()
    
for idx in range( 0, 5) :
    show_cifar10(idx)
4、文件已經獲得,是否已經可以塞到模型里面去??
           如果要塞到模型中去,現有模式是采用直接解析目錄文件的方式,為此廣泛使用了軟鏈接。基於之前獲得的完全路徑,這個地方其實是很好做的。需要注意的是塞進去之前,首先檢驗一下文件是否存在:
for filename in train_truck[ :TESTNUM] :
    if( os.path.exists(TRAIN_DIR +filename)) :
        os.symlink(TRAIN_DIR +filename, './train2/truck/' +filename); 

5、訓練過程中可能遇到的問題
現在看來,萬事大吉:模型下載完成、數據也正確安置了(為此我一個文件夾一個文件夾地打開觀察),下面調用之前在DogVSCat中正確運行的代碼,訓練一段時間后發現錯誤:

Unable to create link (Name already exists)

進一步修改代碼,主要是文件的大小。因為我記得ResNet應該是有最小文件支持限制的,我改成了48*48,但是不行,resnet的限制應該在224,但是cifar10只有32,所以我將cifar10放大,並縮小數據集,然后是等待。

此外,還特別需要注意,文件初始化的時候這樣來做:

也就是test2下面還要有一個test目錄,作為預分類。
6、關於OS的總結
在目前的程序中,廣泛地使用到了os來操作文件系統,應該說很有效果,包括:
os.listdir(TEST_DIR)
返回的顯然是
/home /helu /cifar10 /test / 203688.png
/home /helu /cifar10 /test / 221824.png
/home /helu /cifar10 /test / 289334.png
/home /helu /cifar10 /test / 104194.png
/home /helu /cifar10 /test / 30977.png
這種帶后綴的完整目錄里面文件的地址

os.path.exists(dirname):

os.listdir() #不給參數默認輸出當前路徑下所有文件
os.listdir( '/home/python') #可以指定目錄
簡單的用來判斷,一個目錄下面的文件是否存在。

os.mkdir('test2/test')

創建一個新的目錄,正如其名字一樣。

 os.symlink(TRAIN_DIR+filename, './train2/airplane/'+filename) 

非常重要的,創建軟連接。
此外
shutil.rmtree(dirname)
這個應該是刪除一串文件的,並且進一步整合成這個函數,能夠強制刷新文件目錄。
def rmrf_mkdir(dirname) :
     if  os.path.exists(dirname) :
        shutil.rmtree(dirname)
     os.mkdir(dirname)

7、其它一些可以被復用的東西

def show_cifar10(idx) :
    airplane     = read_image(TRAIN_DIR +train_airplane[idx])
    automobile   = read_image(TRAIN_DIR +train_automobile[idx])
    bird         = read_image(TRAIN_DIR +train_bird[idx])
    cat         = read_image(TRAIN_DIR +train_cat[idx])
    deer         = read_image(TRAIN_DIR +train_deer[idx])
    dog         = read_image(TRAIN_DIR +train_dog[idx])
    frog         = read_image(TRAIN_DIR +train_frog[idx])
    horse       = read_image(TRAIN_DIR +train_horse[idx])
    ship         = read_image(TRAIN_DIR +train_ship[idx])
    truck       = read_image(TRAIN_DIR +train_truck[idx])
    pair = np.concatenate((airplane, automobile,bird,cat,deer,dog,frog,horse,ship,truck), axis = 1)
    plt.figure(figsize =( 10, 5))
    plt.imshow(pair)
    plt.show()
    
for idx in range( 0, 5) :
    show_cifar10(idx)

用來顯示已經保存到內存中數據的圖片。
def CNNFeatureExtract(MODEL, image_size, lambda_func = None) :
    width = image_size[ 0]                         #圖像寬
    height = image_size[ 1]                         #圖像高
    input_tensor = Input((height, width, 3))
    x = input_tensor
    if lambda_func :
        x = Lambda(lambda_func)(x)
    base_model = MODEL(input_tensor =x, weights = 'imagenet', include_top = False)     #這里全部使用no_top模型
    model = Model(base_model. input, GlobalAveragePooling2D()(base_model.output))   

    gen = ImageDataGenerator() #使用了generate,並且使用的是文件夾模式
    train_generator = gen.flow_from_directory( "train2", image_size, shuffle = False, batch_size = 16)
    test_generator   = gen.flow_from_directory( "test2", image_size, shuffle = False, batch_size = 16, class_mode = None)

    train = model.predict_generator(train_generator)
    test = model.predict_generator(test_generator)
    
    with h5py.File( "GoCifar10_%s.h5" %MODEL.func_name) as h :
        h.create_dataset( "train", data =train)
        h.create_dataset( "test", data =test) 
        h.create_dataset( "label", data =train_generator.classes)

強制的模型運算,幫助在dogsvscats上面進入10%,在cifar10上,我認為可以進入前20.

已經開始訓練了。目前的算法雖然不流程,但是可以運行,最重要的是可控的。在這個層次上,我們可以繼續前進。













免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM