目标

要做的事情非常简单,就是用Keras去拟合函数y=x(1x)(a0+a1x+a2x2)y=x(1-x)(a_0+a_1x+a_2x^2)并求其系数a0,a1,a2a_0,a_1,a_2。数据已经给你了,放在csv文件中,没有header,两列多行,很轻易就能读进来。

乍一看,神经网络逼近能力强,随便搭个网络都行。但请注意,我最后想要的不是训练出来的网络,而是要得到这个表达式系数(其实也就是这个表达式)。

网络结构

细细思考一下,脑子中浮现如下一个结构来实现这个公式的全模拟。
keras入门实例:非线性拟合求拟合系数

实现代码

实现y=x(1x)(a0+a1x+a2x2)y=x(1-x)(a_0+a_1x+a_2x^2)求系数的一个网络的代码可以写成下面这样。当然,这里的多项式a0+a1x+a2x2a_0+a_1x+a_2x^2可再添项变成更高次。

import keras
from keras.layers import Input, Dense, Lambda,concatenate,dot
from keras.models import Model
from keras import backend as K
import tensorflow as tf
import numpy as np
Using TensorFlow backend.
# 搭建网络,这部分返回一个张量
inputs = Input(shape=(1,))
x = inputs
#x = concatenate([inputs, inputs**2], axis=1)########################一般的层操作都要改成Lambda表达式,以便操作的结果还是layer
x = Lambda(lambda inputs:concatenate([inputs, inputs**2], axis=1))(inputs)
#print(x.shape)
x = Dense(1,activation='linear')(x)
inputs_1 = Lambda(lambda x:1-x)(inputs);#########################一般的层操作都要改成Lambda表达式,以便操作的结果还是layer
x = dot(inputs= [x,inputs], axes=1)
x = dot(inputs= [x,inputs_1], axes=1)
predictions = x;
# 搭建模型
model = Model(inputs=inputs, outputs=predictions)
# # 导入单个数据
# import numpy as np
# import os
# import os
# csvs = os.listdir("data")
# csv = csvs[1]
# print("data//"+csv)
# f=open("data//"+csv,"rb")
# data_raw=np.loadtxt(f,delimiter=',',skiprows=0)
# f.close()
# data=np.append(data,np.array(data_raw))
# data.shape
# np.array(data_raw)
# 导入csv数据,并拼接成一个数据data
import numpy as np
import os
import os
csvs = os.listdir("data")
data = np.empty(shape=[0, 2])
for csv in csvs:
    f=open("data//"+csv,"rb")
    data_raw=np.loadtxt(f,delimiter=',',skiprows=0)
    f.close()
    data=np.concatenate((data,np.array(data_raw)),axis=0);
data[:,1] = abs(data[:,1]);
x_input = data[:,0];
y_input = data[:,1];

# # 生成数据,用于测试和调试
# x = np.linspace(0, 1, 1000);
# x2 = x**2;
# y=x*(1-x)*(1+2*x+3*x2)
# #print(y);
# x_input = x#np.array([x,x2]).T;
# #x_input.shape
# y_input = y;
# 这部分编译和训练模型
model.compile(optimizer='adam',
              loss='mean_squared_error',
              metrics=['mean_absolute_percentage_error'])
#model.fit(x_input, y_input, epochs=5, batch_size=32)  # 开始训练
model.train_on_batch(x_input, y_input) # 返回损失值和你选定的指标值,向量的话就是均值
[0.066422775, 10530.196]
# # 评估和预测,保持完整性而已
# loss_and_metrics = model.evaluate(x_input, y_input, batch_size=128)
# predicted = model.predict(x_input, batch_size=128)
# 得到权重,这是我们想要的,输出为每一层的W和b
weights = np.array(model.get_weights())
print(weights)
[array([[ 0.28180382],
       [-0.6509848 ]], dtype=float32)
 array([0.00074411], dtype=float32)]
# 可视化:【Tips】依赖 pydot-ng 和 graphviz,命令行输入pip install pydot-ng & brew install graphviz
#from keras.utils.visualize_util import plot
from keras.utils.vis_utils import plot_model
plot_model(model, to_file='model.png')

以上的注释都比较清楚了,就不再分块地解释代码了。需要注意的是,要记得使用Lambda层,以避开天坑

两个模板

下面两个模板是从官方文档上拷贝出来的,放在这里,意在当你要搭建一个比较简单的网络是,可以直接将模板拷进去,稍微改改网络结构,损失函数,评估函数什么的,就能用了。

序列式模板
模块导入
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import SGD
搭一个模型
model = Sequential()
model.add(Dense(units=64, input_dim=100))
model.add(Activation("relu"))
model.add(Dense(units=10))
model.add(Activation("softmax"))
编译
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])

#或者

model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True))

训练
model.fit(x_train, y_train, epochs=5, batch_size=32)

# 或者

model.train_on_batch(x_batch, y_batch)
评估和预测
loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
classes = model.predict(x_test, batch_size=128)
函数式模板
from keras.layers import Input, Dense
from keras.models import Model

# This returns a tensor
inputs = Input(shape=(784,))

# a layer instance is callable on a tensor, and returns a tensor
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)

# This creates a model that includes
# the Input layer and three Dense layers
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(data, labels)  # starts training
可选项

**函数:https://keras-cn.readthedocs.io/en/latest/legacy/other/activations/

  • softmax
  • softplus
  • softsign
  • relu
  • tanh
  • sigmoid
  • hard_sigmoid
  • linear

优化器:https://keras-cn.readthedocs.io/en/latest/legacy/other/optimizers/

  • SGD
  • RMSprop
  • Adagrad
  • Adadelta
  • Adam
  • Adamax
  • Nadam

损失函数:https://keras-cn.readthedocs.io/en/latest/legacy/other/objectives/

  • mean_squared_error或mse

  • mean_absolute_error或mae

  • mean_absolute_percentage_error或mape

  • mean_squared_logarithmic_error或msle

  • squared_hinge

  • hinge

  • binary_crossentropy(亦称作对数损失,logloss)

  • categorical_crossentropy:亦称作多类的对数损失,注意使用该目标函数时,需要将标签转化为形如(nb_samples, nb_classes)的二值序列

  • sparse_categorical_crossentrop:如上,但接受稀疏标签。注意,使用该函数时仍然需要你的标签与输出值的维度相同,你可能需要在标签数据上增加一个维度:np.expand_dims(y,-1)

  • kullback_leibler_divergence:从预测值概率分布Q到真值概率分布P的信息增益,用以度量两个分布的差异.

  • poisson:即(predictions - targets * log(predictions))的均值

  • cosine_proximity:即预测值与真实标签的余弦距离平均值的相反数

评估函数:https://keras-cn.readthedocs.io/en/latest/legacy/other/metrics/

  • binary_accuracy:对二分类问题,计算在所有预测值上的平均正确率
  • categorical_accuracy:对多分类问题,计算再所有预测值上的平均正确率
  • sparse_categorical_accuracy:与categorical_accuracy相同,在对稀疏的目标值预测时有用
  • top_k_categorical_accracy: 计算top-k正确率,当预测值的前k个值中存在目标类别即认为预测正确
  • mean_squared_error:计算预测值与真值的均方差
  • mean_absolute_error:计算预测值与真值的平均绝对误差
  • mean_absolute_percentage_error:计算预测值与真值的平均绝对误差率
  • mean_squared_logarithmic_error:计算预测值与真值的平均指数误差
  • hinge:计算预测值与真值的hinge loss
  • squared_hinge:计算预测值与真值的平方hinge loss
  • categorical_crossentropy:计算预测值与真值的多类交叉熵(输入值为二值矩阵,而不是向量)
  • sparse_categorical_crossentropy:与多类交叉熵相同,适用于稀疏情况
  • binary_crossentropy:计算预测值与真值的交叉熵
  • poisson:计算预测值与真值的泊松函数值
  • cosine_proximity:计算预测值与真值的余弦相似性
  • matthews_correlation:计算预测值与真值的马氏距离
  • precision:计算精确度,注意percision跟accuracy是不同的。percision用于评价多标签分类中有多少个选中的项是正确的
  • recall:召回率,计算多标签分类中有多少正确的项被选中
  • fbeta_score:计算F值,即召回率与准确率的加权调和平均,该函数在多标签分类(一个样本有多个标签)时有用,如果只使用准确率作为度量,模型只要把所有输入分类为"所有类别"就可以获得完美的准确率,为了避免这种情况,度量指标应该对错误的选择进行惩罚. F-beta分值(0到1之间)通过准确率和召回率的加权调和平均来更好的度量.当beta为1时,该指标等价于F-measure,beta<1时,模型选对正确的标签更加重要,而beta>1时,模型对选错标签有更大的惩罚.
  • fmeasure:计算f-measure,即percision和recall的调和平均

没解释的顾名思义,一目了然,不再解释,可以参考官方文档。

参考

https://keras-cn.readthedocs.io/en/latest