keras 数据集学习笔记 3/3

2017-10-06  本文已影响1657人  gaoshine

keras 数据集的学习笔记 3/3

深度学习需要有大量的数据集供机器来学习,本次就学习如何定义自己的数据集。

  1. 各种常用的数据集
  2. 数据集如何使用
  3. 定义自己的数据集

虽然该数据的准备和预处理工作是一件非常费力的事情,但是最终的应用,我们还是要使用自己的数据集进行训练。
本次的内容总结和学习一下如何定义自己的数据集,并拿来训练。

1. 数据模拟生成的数据集

# 生成用于拟合的模拟数据,本次采用线性的二元一次方程 

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(1337)  # 随机种子,保证每次的数据的可重复行和一致性
from keras.models import Sequential
from keras.layers import Dense

# create some data
X = np.linspace(-1, 1, 1000) # 生成 -1到1的1000个随机数
np.random.shuffle(X)    # 打乱数据
Y = 0.5 * X + 2 + np.random.normal(0, 0.05, (1000, )) # Y数据随机扰动
# plot data
plt.scatter(X, Y)
plt.show()

output_1_0.png
# 数据集保存成csv格式文件
import pandas as pd  

save = pd.DataFrame({'Y_lbale':Y,'X_values':X})  
save.to_csv('mydata.csv',index=False,sep=',')  

查看目录,生成了 mydata.cvs文件,文件内容大致如下:

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
.....
.....

这次我们先生成了模拟数据,再把模拟数据保存成文件,作为训练数据集使用。
在我们收集大量的数据比较困难的情况下,使用模拟生成大量数据集的方式,无疑是个好办法。
当然,本次是一个线性的方程的模拟数据,实际使用中的更复杂的曲线,理论上可以采用更高次的方程拟合出来。

有了数据集文件,每次训练时候,可以直接调用这个文件,用于训练就可以了。

# 直接使用数据集,进行训练
%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()

output_4_0.png
# 以上数据集和生成的完全一样,下一步我们做一下数据的预处理工作
%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条数据,前800条数据用于训练
X_test, Y_test = X[800:], Y[800:]       # 后200条数据用于测试

# 经过预处理,我们发现已经是标准的  (X_train, y_train), (X_test, y_test) 数据集格式了

# 这个模型简单,我们搭建一个层就可以了

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]

经过300次训练 W=0.50460804 b=1.99811506 和原来的方程 Y = 0.5 * X + 2 中 W=0.5 b=2 已经很接近了

我们把测试数据做一下预测,并画成图,直观地感受一下。

# plotting the prediction
Y_pred = model.predict(X_test)
plt.scatter(X_test, Y_test)
plt.plot(X_test, Y_pred)
plt.show()
output_7_0.png

2. 直接整理数据集

我们的第一例数据是个线性的,比较简单,实际应用中更像股票数据,数据的起伏不定,对于这些数据怎么做成数据集呢?

  1. 收集整理数据
  2. 输入到excel中,格式一般就是标题,然后是一行行的数据
  3. 最好保存为CSV格式文件

以上数据集就可以使用了。 我们在Kaggle上经常看到这样格式的数据集。
我们这次选择铁路运量的数据预测(Railway traffic Prediction)
数据是200501到201610的铁路运量,数据格式如下:

时间,铁路客运量_当期值(万人)
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

(以上铁路客运量历史数据下载自 WTF Daily Blog) 铁路客运量历史数据

%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()
output_9_0.png

我们看到实际的数据一般是有整体趋势,局部有震荡,铁路运输量上反映出整体运量在升高,但又有旺季和淡季之分,这也符合现实世界的情况。
这个曲线如果想精确的预测每个月的客运量,显然不能使用线性的一次方程,需要N次的方程才可以拟合出合适的曲线。当然,还有另外一种思路,针对时序的输入,采用RNN是一种更好的模型,我们这次要要探讨数据集,这个模型在以后的笔记中再探讨。

3. 图像分类数据集

前面的数据集都是做数据预测的,现在我们来做一套图像分类的数据集,猫狗大战,通过大量的狗和猫的照片,训练机器识别出来猫和狗来,这是一个典型的二分图像分类
这份数据集来源于Kaggle,原数据集有12500只猫和12500只狗,我们只取了各个类的前1000张图片。另外我们还从各个类中取了400张额外图片用于测试。

cats_and_dogs

配置情况

我们的实验基于下面的配置

data/
    train/
        dogs/
            dog001.jpg
            dog002.jpg
            ...
        cats/
            cat001/jpg
            cat002.jpg
            
            ...
    validation/
        dogs/
            dog001.jpg
            dog002.jpg
            ...
        cats/
            cat001/jpg
            cat002.jpg
            ...

以上图片,我已经整理好,打包成文件放到百度网盘上,需要的可以下载。猫狗大战图片数据集

针对我们手头的数据集的确有点少,所以我们需要一些技巧,在小数据集的情况下提升训练水平。

数据预处理与数据提升

为了尽量利用我们有限的训练数据,我们将通过一系列随机变换堆数据进行提升,这样我们的模型将看不到任何两张完全相同的图片,这有利于我们抑制过拟合,使得模型的泛化能力更好。

在Keras中,这个步骤可以通过keras.preprocessing.image.ImageGenerator来实现,这个类使你可以:

然后我们开始准备数据,使用.flow_from_directory()来从我们的jpgs图片中直接产生数据和标签。

# 配置训练用图像生成气的参数,用于随机改变图像的大小、偏转、翻转、位移等等
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

# 配置测试用图像生成气的参数
# 只改变比例
test_datagen = ImageDataGenerator(rescale=1./255)

# 图像生成器根据参数配置,读取
# 目录下'data/train'的图像文件
# 批量生成数据集
train_generator = train_datagen.flow_from_directory(
        'data/train',  # 目标目录
        target_size=(150, 150),  # 所有图片大小转换为 150x150
        batch_size=32,
        class_mode='binary')  # 我们使用 binary_crossentropy loss 二分,只有是否2种

# 批量生成验证数据
validation_generator = test_datagen.flow_from_directory(
        'data/validation',
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

然后我们可以用这个生成器来训练网络了
(model的具体搭建在此省略了,本次主要是学习数据集。具体可参照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')  # 训练后,保存权重

图形的分类处理,以上的方法是一个好例子,我们以后再做图形识别分类的数据训练时候,可以借鉴上述的方法。

有关自定义的数据集,暂时写这些吧,其他的像是图片分类、物体识别、声音识别、文本生成等等 还有许多种,但是基本的方式也是一样的。

上一篇下一篇

猜你喜欢

热点阅读