keras 數(shù)據(jù)集的學習筆記 3/3
深度學習需要有大量的數(shù)據(jù)集供機器來學習馅闽,本次就學習如何定義自己的數(shù)據(jù)集谣光。
- 各種常用的數(shù)據(jù)集
- 數(shù)據(jù)集如何使用
- 定義自己的數(shù)據(jù)集
雖然該數(shù)據(jù)的準備和預處理工作是一件非常費力的事情虏肾,但是最終的應用,我們還是要使用自己的數(shù)據(jù)集進行訓練。
本次的內(nèi)容總結和學習一下如何定義自己的數(shù)據(jù)集哎垦,并拿來訓練镜雨。
1. 數(shù)據(jù)模擬生成的數(shù)據(jù)集
# 生成用于擬合的模擬數(shù)據(jù)嫂侍,本次采用線性的二元一次方程
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(1337) # 隨機種子,保證每次的數(shù)據(jù)的可重復行和一致性
from keras.models import Sequential
from keras.layers import Dense
# create some data
X = np.linspace(-1, 1, 1000) # 生成 -1到1的1000個隨機數(shù)
np.random.shuffle(X) # 打亂數(shù)據(jù)
Y = 0.5 * X + 2 + np.random.normal(0, 0.05, (1000, )) # Y數(shù)據(jù)隨機擾動
# plot data
plt.scatter(X, Y)
plt.show()
# 數(shù)據(jù)集保存成csv格式文件
import pandas as pd
save = pd.DataFrame({'Y_lbale':Y,'X_values':X})
save.to_csv('mydata.csv',index=False,sep=',')
查看目錄荚坞,生成了 mydata.cvs文件挑宠,文件內(nèi)容大致如下:
X_values,Y_lbale
0.9559559559559558,2.4611472908040004
-0.96996996996997,1.5800108238723558
-0.8878878878878879,1.5441473485192092
0.6036036036036037,2.4042039720326818
0.49549549549549554,2.2283205464053752
0.6236236236236237,2.257678071872533
-0.7697697697697697,1.6140242420137656
0.6916916916916918,2.347125069451855
-0.08508508508508505,1.9078236562355713
-0.4814814814814815,1.807135359838545
-0.22522522522522526,1.8580416208459054
.....
.....
這次我們先生成了模擬數(shù)據(jù),再把模擬數(shù)據(jù)保存成文件颓影,作為訓練數(shù)據(jù)集使用各淀。
在我們收集大量的數(shù)據(jù)比較困難的情況下,使用模擬生成大量數(shù)據(jù)集的方式诡挂,無疑是個好辦法碎浇。
當然,本次是一個線性的方程的模擬數(shù)據(jù)璃俗,實際使用中的更復雜的曲線奴璃,理論上可以采用更高次的方程擬合出來。
有了數(shù)據(jù)集文件城豁,每次訓練時候溺健,可以直接調(diào)用這個文件,用于訓練就可以了钮蛛。
# 直接使用數(shù)據(jù)集鞭缭,進行訓練
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
df = pd.read_csv('mydata.csv')
Y = np.array(df['Y_lbale'])
X = np.array(df['X_values'])
# plot data
plt.scatter(X, Y)
plt.show()
# 以上數(shù)據(jù)集和生成的完全一樣,下一步我們做一下數(shù)據(jù)的預處理工作
%matplotlib inline
from keras.models import Sequential
from keras.layers import Dense, Activation
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
import pandas as pd
import matplotlib.pyplot as plt
X_train, Y_train = X[:800], Y[:800] # 一共1000條數(shù)據(jù),前800條數(shù)據(jù)用于訓練
X_test, Y_test = X[800:], Y[800:] # 后200條數(shù)據(jù)用于測試
# 經(jīng)過預處理魏颓,我們發(fā)現(xiàn)已經(jīng)是標準的 (X_train, y_train), (X_test, y_test) 數(shù)據(jù)集格式了
# 這個模型簡單岭辣,我們搭建一個層就可以了
model = Sequential()
model.add(Dense(1,input_dim=1))
model.compile(loss='mse', optimizer='sgd')
print(model.summary())
SVG(model_to_dot(model,show_shapes=True).create(prog='dot', format='svg'))
model.fit(X_train, Y_train, epochs=300, batch_size=40,validation_data=(X_test, Y_test))
# test
print('\nTesting ------------')
W, b = model.layers[0].get_weights()
print('Weights=', W, '\nbiases=', b)
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_5 (Dense) (None, 1) 2
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0
_________________________________________________________________
None
Train on 800 samples, validate on 200 samples
Epoch 1/300
800/800 [==============================] - 0s - loss: 2.8850 - val_loss: 1.9322
Epoch 2/300
800/800 [==============================] - 0s - loss: 1.3227 - val_loss: 0.9019
Epoch 3/300
800/800 [==============================] - 0s - loss: 0.6181 - val_loss: 0.4313
Epoch 4/300
800/800 [==============================] - 0s - loss: 0.2979 - val_loss: 0.2139
Epoch 5/300
800/800 [==============================] - 0s - loss: 0.1503 - val_loss: 0.1112
Epoch 297/300
800/800 [==============================] - 0s - loss: 0.0025 - val_loss: 0.0020
Epoch 298/300
800/800 [==============================] - 0s - loss: 0.0025 - val_loss: 0.0020
Epoch 299/300
800/800 [==============================] - 0s - loss: 0.0025 - val_loss: 0.0020
Epoch 300/300
800/800 [==============================] - 0s - loss: 0.0025 - val_loss: 0.0020
Testing ------------
Weights= [[ 0.50460804]]
biases= [ 1.99811506]
經(jīng)過300次訓練 W=0.50460804 b=1.99811506 和原來的方程 Y = 0.5 * X + 2 中 W=0.5 b=2 已經(jīng)很接近了
我們把測試數(shù)據(jù)做一下預測,并畫成圖甸饱,直觀地感受一下沦童。
# plotting the prediction
Y_pred = model.predict(X_test)
plt.scatter(X_test, Y_test)
plt.plot(X_test, Y_pred)
plt.show()
2. 直接整理數(shù)據(jù)集
我們的第一例數(shù)據(jù)是個線性的,比較簡單叹话,實際應用中更像股票數(shù)據(jù)偷遗,數(shù)據(jù)的起伏不定,對于這些數(shù)據(jù)怎么做成數(shù)據(jù)集呢驼壶?
- 收集整理數(shù)據(jù)
- 輸入到excel中氏豌,格式一般就是標題,然后是一行行的數(shù)據(jù)
- 最好保存為CSV格式文件
以上數(shù)據(jù)集就可以使用了热凹。 我們在Kaggle上經(jīng)潮么看到這樣格式的數(shù)據(jù)集泪电。
我們這次選擇鐵路運量的數(shù)據(jù)預測(Railway traffic Prediction)
數(shù)據(jù)是200501到201610的鐵路運量,數(shù)據(jù)格式如下:
時間,鐵路客運量_當期值(萬人)
2005年1月,9300
2005年2月,10600
2005年3月,9300
2005年4月,9100
2005年5月,9700
2005年6月,8600
...
...
...
2016年5月,22886
2016年6月,23200
2016年7月,26818
2016年8月,28007
2016年9月,23918
2016年10月,25001
(以上鐵路客運量歷史數(shù)據(jù)下載自 WTF Daily Blog) 鐵路客運量歷史數(shù)據(jù)
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
df = pd.read_csv('traffic.csv')
datas = np.array(df['鐵路客運量_當期值(萬人)'])
# plot data
plt.plot(datas)
plt.show()
我們看到實際的數(shù)據(jù)一般是有整體趨勢纪铺,局部有震蕩相速,鐵路運輸量上反映出整體運量在升高,但又有旺季和淡季之分鲜锚,這也符合現(xiàn)實世界的情況突诬。
這個曲線如果想精確的預測每個月的客運量,顯然不能使用線性的一次方程芜繁,需要N次的方程才可以擬合出合適的曲線旺隙。當然,還有另外一種思路浆洗,針對時序的輸入催束,采用RNN是一種更好的模型集峦,我們這次要要探討數(shù)據(jù)集伏社,這個模型在以后的筆記中再探討。
3. 圖像分類數(shù)據(jù)集
前面的數(shù)據(jù)集都是做數(shù)據(jù)預測的塔淤,現(xiàn)在我們來做一套圖像分類的數(shù)據(jù)集摘昌,貓狗大戰(zhàn),通過大量的狗和貓的照片高蜂,訓練機器識別出來貓和狗來聪黎,這是一個典型的二分圖像分類
這份數(shù)據(jù)集來源于Kaggle,原數(shù)據(jù)集有12500只貓和12500只狗备恤,我們只取了各個類的前1000張圖片稿饰。另外我們還從各個類中取了400張額外圖片用于測試。
配置情況
我們的實驗基于下面的配置
2000張訓練圖片構成的數(shù)據(jù)集露泊,一共兩個類別喉镰,每類1000張
數(shù)據(jù)集按照下面的形式存放
data/
train/
dogs/
dog001.jpg
dog002.jpg
...
cats/
cat001/jpg
cat002.jpg
...
validation/
dogs/
dog001.jpg
dog002.jpg
...
cats/
cat001/jpg
cat002.jpg
...
以上圖片,我已經(jīng)整理好惭笑,打包成文件放到百度網(wǎng)盤上侣姆,需要的可以下載。貓狗大戰(zhàn)圖片數(shù)據(jù)集
針對我們手頭的數(shù)據(jù)集的確有點少沉噩,所以我們需要一些技巧捺宗,在小數(shù)據(jù)集的情況下提升訓練水平。
數(shù)據(jù)預處理與數(shù)據(jù)提升
為了盡量利用我們有限的訓練數(shù)據(jù)川蒙,我們將通過一系列隨機變換堆數(shù)據(jù)進行提升蚜厉,這樣我們的模型將看不到任何兩張完全相同的圖片,這有利于我們抑制過擬合畜眨,使得模型的泛化能力更好弯囊。
在Keras中痰哨,這個步驟可以通過keras.preprocessing.image.ImageGenerator
來實現(xiàn),這個類使你可以:
在訓練過程中匾嘱,設置要施行的隨機變換
通過
.flow
或.flow_from_directory(directory)
方法實例化一個針對圖像batch的生成器斤斧,這些生成器可以被用作keras模型相關方法的輸入,如fit_generator
霎烙,evaluate_generator
和predict_generator
然后我們開始準備數(shù)據(jù)撬讽,使用.flow_from_directory()
來從我們的jpgs圖片中直接產(chǎn)生數(shù)據(jù)和標簽。
# 配置訓練用圖像生成氣的參數(shù)悬垃,用于隨機改變圖像的大小游昼、偏轉(zhuǎn)、翻轉(zhuǎn)尝蠕、位移等等
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# 配置測試用圖像生成氣的參數(shù)
# 只改變比例
test_datagen = ImageDataGenerator(rescale=1./255)
# 圖像生成器根據(jù)參數(shù)配置烘豌,讀取
# 目錄下'data/train'的圖像文件
# 批量生成數(shù)據(jù)集
train_generator = train_datagen.flow_from_directory(
'data/train', # 目標目錄
target_size=(150, 150), # 所有圖片大小轉(zhuǎn)換為 150x150
batch_size=32,
class_mode='binary') # 我們使用 binary_crossentropy loss 二分,只有是否2種
# 批量生成驗證數(shù)據(jù)
validation_generator = test_datagen.flow_from_directory(
'data/validation',
target_size=(150, 150),
batch_size=32,
class_mode='binary')
然后我們可以用這個生成器來訓練網(wǎng)絡了
(model的具體搭建在此省略了看彼,本次主要是學習數(shù)據(jù)集廊佩。具體可參照Building powerful image classification models using very little data)
model.fit_generator(
train_generator,
steps_per_epoch=2000,
epochs=50,
validation_data=validation_generator,
validation_steps=800)
model.save_weights('first_try.h5') # 訓練后,保存權重
圖形的分類處理标锄,以上的方法是一個好例子料皇,我們以后再做圖形識別分類的數(shù)據(jù)訓練時候,可以借鑒上述的方法。