在Keras中匯入測試資料的方法

2021-08-19 23:41:51 字數 4538 閱讀 7091

keras裡面有很多經典的資料集。當我們研究自己的模型的時候,只需要拿出其中與我們要研究的問題類似的資料集進行試驗就行了。比如之前提到的手寫數字識別的經典資料集mnist。就只需要一行**:

(x_train, y_train), (x_test, y_test) = mnist.load_data()
創造資料集是一件比較難的事情。尤其是要創造大量的、靠譜的資料集。通常來說,很多資料集只能通過大公司去收集,而不能自己創造。有的時候我們還是能夠自己創造資料集的。例如我們的ocr。我們只需要把字元進行變形就可以生成我們的資料集了。(當然,如果要考慮手寫的順序等問題,這就不夠了。)關於生成字元識別資料集。

考慮到keras的輸入資料是numpy、float型別,因此我們只需要把讀入,然後轉成numpy就行了。

首先,我們的目錄結構是這樣的:

./words

./0/ 0.png 1.png 2.png ...

/1/ 0.png 1.png 2.png ...

def read_image(imagename):

im = image.open(imagename).convert('l')

data = np.array(im)

return data

# 讀取在words裡面有幾個資料夾

text = os.listdir('./words')

# 把資料夾裡面的和其對應的資料夾的名字也就是對應的字

for textpath in text:

for fn in os.listdir(os.path.join('words', textpath)):

if fn.endswith('.png'):

fd = os.path.join('./words', textpath, fn)

接著我們把剛剛得到的images和labels也變成numpy型別。當然,labels首先要變成int型別。

x = np.array(images)

y = np.array(list(map(int, labels)))

最後,我們按三七分把這些分為訓練集和測試集。

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.30, random_state=30)

資料的匯入工作就完成了。這也只對於資料集比較小,對於大資料處理則不行。

若資料集比較大:原來,keras的訓練不僅僅有fit,還有fit_generator,也就是乙個乙個訓練。fit_generator的api如下:

fit_generator(self, generator, steps_per_epoch, epochs=1, verbose=1, callbacks=none, validation_data=none, validation_steps=none, class_weight=none, max_q_size=10, workers=1, pickle_safe=false, initial_epoch=0)
文件是這樣寫的:

函式的引數是:

steps_per_epoch:整數,當生成器返回steps_per_epoch次資料時計乙個epoch結束,執行下乙個epoch

epochs:整數,資料迭代的輪數

verbose:日誌顯示,0為不在標準輸出流輸出日誌資訊,1為輸出進度條記錄,2為每個epoch輸出一行記錄

validation_data:具有以下三種形式之一

validation_steps: 當validation_data為生成器時,本引數指定驗證集的生成器返回次數

class_weight:規定類別權重的字典,將類別對映為權重,常用於處理樣本不均衡問題。

sample_weight:權值的numpy array,用於在訓練時調整損失函式(僅用於訓練)。可以傳遞乙個1d的與樣本等長的向量用於對樣本進行1對1的加權,或者在面對時序資料時,傳遞乙個的形式為(samples,sequence_length)的矩陣來為每個時間步上的樣本賦不同的權。這種情況下請確定在編譯模型時新增了sample_weight_mode='temporal'。

workers:最大程序數

max_q_size:生成器佇列的最大容量

pickle_safe: 若為真,則使用基於程序的執行緒。由於該實現依賴多程序,不能傳遞non picklable(無法被pickle序列化)的引數到生成器中,因為無法輕易將它們傳入子程序中。

initial_epoch: 從該引數指定的epoch開始訓練,在繼續之前的訓練時有用。

這個裡面,只有前面六個是比較重要的,其他的預設就行了。甚至我們只需要前面三個就行了。steps_per_epoch和epochs都很好理解。這個generator,也就是生成器函式,才是問題的關鍵。

接下來就非常簡單了。在keras系列︱利用fit_generator最小化視訊記憶體占用比率/資料batch化這篇部落格裡面已經講得很清楚了。

裡面有個demo一般的生成器函式:

def

generate_batch_data_random

(x, y, batch_size):

"""逐步提取batch資料到視訊記憶體,降低對視訊記憶體的占用"""

ylen = len(y)

loopcount = ylen // batch_size

while (true):

i = randint(0,loopcount)

yield x[i * batch_size:(i + 1) * batch_size], y[i * batch_size:(i + 1) * batch_size]

這裡應該注意的有兩點,第一點就是資料必須是要打亂的,沒有規律的。第二點就是最後用的是yield。這也是python的乙個高階特性了。簡單地說,這就是乙個return。但是你每呼叫一次,它就返回一次,而不像其他函式一樣,return了就出去了。這樣就成為了乙個生成器。具體可以看廖雪峰的python教程

剩下的就很簡單了。我們甚至可以直接在這個生成器函式裡面寫生成的演算法。當然,考慮到io操作肯定比直接生成要快,直接生成肯定是不可取的。

當然,這不是最好的匯入資料的方法。keras還有更快的方法。在介紹這個方法之前,我需要先介紹keras的影象預處理的方法。

為了防止影象的過擬合,keras裡面自帶了生成器用來對影象進行一些簡單的操作,例如平移,旋轉,縮放等等。這樣我們就可以在有限的資料集上面生成無限的訓練樣本。這樣可以擴大訓練集的大小,防止影象的過擬合。具體的內容可以檢視生成器的文章。

關鍵問題不在於這個生成,而是這個生成器的方法裡面提供了乙個函式——flow_from_directory(directory)

這個函式的引數如下:

flow_from_directory(directory): 以資料夾路徑為引數,生成經過資料提公升/歸一化後的資料,在乙個無限迴圈中無限產生batch資料

我們的**可以這樣寫:

datagen = imagedatagenerator(...)

train_generator = datagen.flow_from_directory(

'./words',

target_size=(30, 30),

color_mode='grayscale',

batch_size=64)

model.fit_generator(train_generator, steps_per_epoch=500, epochs=50)

這樣我們就匯入了資料了。自此keras的簡單使用已經不成問題。

最後,我們需要注意,最後的匯入資料的時候,會自動搜尋裡面的資料夾,但是是按字典序排序的。這很自然。例如你的資料夾是分類問題,資料夾都是貓、狗、鼠這樣的漢字,它當然得按字典序排序。但是如果是像我們用0、1、2、3…這樣的數字,就容易讓人崩潰。因此我們需要注意在生成資料夾的時候,前面補0,即000、001、003、…、999。

import os

picture_name = os.listdir('./train_chunk2/')

for i in picture_name:

new_name=i

if len(i)==1:

new_name = '00'+i

elif len(i)==2:

new_name= '0'+i

os.rename('./train_chunk2/'+i, './train_chunk2/'+new_name)

測試資料的簡單匯入

有時候我們需要將吸入到文字的試驗資料,匯入到程式中進行繪製影象觀察分析,下面介紹乙個比較簡單的資料匯入的方法 from numpy import from pylab import x arange 0,5,0.2 y x x 寫入資料,使用with語法可以避免程式還在執行被突然關閉,文件還在記憶體...

Keras匯入Mnist資料集出錯解決方案

exception url fetch failure on none winerror 10060 由於連線方在一段時間後沒有正確答覆或連線的主機沒有反應,連線嘗試失敗。def load data loads the mnist dataset.arguments path path where ...

在SQL資料庫中匯入Excel

excel匯入sql儲存過程 簡單 create procedure import tablename varchar 100 filepath varchar 100 as exec insert into tablename select from opendatasource microsof...