用keras建立擬合網路解決迴歸問題Regression
實現了正弦曲線的擬合,即regression問題。
建立的模型單輸入單輸出,兩個隱層分別為100、50個神經元。
在keras的官方文件中,給的例子多是關於分類的。因此在測試regression時,遇到了一些問題。總結來說,應注意以下幾個方面:
1)訓練資料需是矩陣型,這裡的輸入和輸出是1000*1,即1000個樣本;每個樣本得到一個輸出;
注意:訓練資料的生成非常關鍵,首先需要檢查輸入資料和輸出資料的維度匹配;
2)對資料進行規範化,這裡用到的是零均值單位方差的規範方法。規範化方法對於各種訓練模型很有講究,具體參照另一篇筆記:http://blog.csdn.net/csmqq/article/details/51461696;
3)輸出層的啟用函式選擇很重要,該擬合的輸出有正負值,因此選擇tanh比較合適;
4)regression問題中,訓練函式compile中的誤差函式通常選擇mean_squared_error。
5)值得注意的是,在訓練時,可以將測試資料的輸入和輸出繪製出來,這樣可以幫助除錯引數。
6)keras中實現迴歸問題,返回的準確率為0。
- # -*- coding: utf-8 -*-
- """
- Created on Mon May 16 13:34:30 2016
- @author: Michelle
- """
-
from keras.models import Sequential
- from keras.layers.core import Dense, Activation
- from keras.optimizers import SGD
- from keras.layers.advanced_activations import LeakyReLU
- from sklearn import preprocessing
- from keras.utils.visualize_plots import figures
- import matplotlib.pyplot as plt
- import numpy as np
-
#part1: train data
- #generate 100 numbers from -2pi to 2pi
- x_train = np.linspace(-2*np.pi, 2*np.pi, 1000) #array: [1000,]
- x_train = np.array(x_train).reshape((len(x_train), 1)) #reshape to matrix with [100,1]
- n=0.1*np.random.rand(len(x_train),1) #generate a matrix with size [len(x),1], value in (0,1),array: [1000,1]
- y_train=np.sin(x_train)+n
- #訓練資料集:零均值單位方差
- x_train = preprocessing.scale(x_train)
- scaler = preprocessing.StandardScaler().fit(x_train)
- y_train = scaler.transform(y_train)
- #part2: test data
- x_test = np.linspace(-5,5,2000)
- x_test = np.array(x_test).reshape((len(x_test), 1))
- y_test=np.sin(x_test)
- #零均值單位方差
- x_test = scaler.transform(x_test)
- #y_test = scaler.transform(y_test)
- ##plot testing data
- #fig, ax = plt.subplots()
- #ax.plot(x_test, y_test,'g')
- #prediction data
- x_prd = np.linspace(-3,3,101)
- x_prd = np.array(x_prd).reshape((len(x_prd), 1))
- x_prd = scaler.transform(x_prd)
- y_prd=np.sin(x_prd)
- #plot testing data
- fig, ax = plt.subplots()
- ax.plot(x_prd, y_prd,'r')
- #part3: create models, with 1hidden layers
- model = Sequential()
- model.add(Dense(100, init='uniform', input_dim=1))
- #model.add(Activation(LeakyReLU(alpha=0.01)))
- model.add(Activation('relu'))
- model.add(Dense(50))
- #model.add(Activation(LeakyReLU(alpha=0.1)))
- model.add(Activation('relu'))
- model.add(Dense(1))
- #model.add(Activation(LeakyReLU(alpha=0.01)))
- model.add(Activation('tanh'))
- #sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
- model.compile(loss='mean_squared_error', optimizer="rmsprop", metrics=["accuracy"])
- #model.compile(loss='mean_squared_error', optimizer=sgd, metrics=["accuracy"])
- #model.fit(x_train, y_train, nb_epoch=64, batch_size=20, verbose=0)
- hist = model.fit(x_test, y_test, batch_size=10, nb_epoch=100, shuffle=True,verbose=0,validation_split=0.2)
- #print(hist.history)
- score = model.evaluate(x_test, y_test, batch_size=10)
- out = model.predict(x_prd, batch_size=1)
- #plot prediction data
- ax.plot(x_prd, out, 'k--', lw=4)
- ax.set_xlabel('Measured')
- ax.set_ylabel('Predicted')
- plt.show()
- figures(hist)
虛線是預測值,紅色是輸入值;
繪製誤差值隨著迭代次數的曲線函式是Visualize_plots.py,
1)將其放在C:\Anaconda2\Lib\site-packages\keras\utils下面。
2)在使用時,需要新增這句話:from keras.utils.visualize_plots import figures,然後在程式中直接呼叫函式figures(hist)。
垓函式的實現程式碼為:
- # -*- coding: utf-8 -*-
- """
- Created on Sat May 21 22:26:24 2016
- @author: Shemmy
- """
- def figures(history,figure_name="plots"):
- """ method to visualize accuracies and loss vs epoch for training as well as testind data\n
- Argumets: history = an instance returned by model.fit method\n
- figure_name = a string representing file name to plots. By default it is set to "plots" \n
- Usage: hist = model.fit(X,y)\n figures(hist) """
- from keras.callbacks import History
- if isinstance(history,History):
- import matplotlib.pyplot as plt
- hist = history.history
- epoch = history.epoch
- acc = hist['acc']
- loss = hist['loss']
- val_loss = hist['val_loss']
- val_acc = hist['val_acc']
- plt.figure(1)
- plt.subplot(221)
- plt.plot(epoch,acc)
- plt.title("Training accuracy vs Epoch")
- plt.xlabel("Epoch")
- plt.ylabel("Accuracy")
- plt.subplot(222)
- plt.plot(epoch,loss)
- plt.title("Training loss vs Epoch")
- plt.xlabel("Epoch")
- plt.ylabel("Loss")
- plt.subplot(223)
- plt.plot(epoch,val_acc)
- plt.title("Validation Acc vs Epoch")
- plt.xlabel("Epoch")
- plt.ylabel("Validation Accuracy")
- plt.subplot(224)
- plt.plot(epoch,val_loss)
- plt.title("Validation loss vs Epoch")
- plt.xlabel("Epoch")
- plt.ylabel("Validation Loss")
- plt.tight_layout()
- plt.savefig(figure_name)
- else:
- print"Input Argument is not an instance of class History"
討論keras中實現擬合迴歸問題的帖子: https://github.com/fchollet/keras/issues/108