用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

展开阅读全文

没有更多推荐了,返回首页