比如已知一个数学模型y=ax**2+bx+c,假设已经训练完成。现在测试集有很多对x,y(x,y是很长的一维数组,二者一一对应),每对x,y数据都对应一个abc,现在要预测这些测试集所有x,y对应的abc。

这个用神经网路能做吗?如果能,用什么结构比较好?我用了BP神经网路,做出的结果非常差。

我有一个想法,如果用CNN结构,训练集为二次函数的曲线图片,通过曲线形状识别参数。(当然,图片格式一定要统一)


看到这个问题我首先想到的是贝叶斯方法求解 [公式] 。假设 [公式] ,这是个先验分布,余下的你要做的就是求解这个分布。

如果用神经网路也可以,只需reparametrize即可,令 [公式] (这两个函数都是神经网实现的,单隐层网路就够了),然后采样得到a,b,c并最小化 [公式] ,怎么采样和梯度传播请参考VAE或CVAE。

希望有帮助。


额,为什么答案大部分都说知道是二次形式呢?神经网路的训练集不是只有输入输出,不给你关于函数的任何信息么?难道题主意思是给你一堆输入输出,且已知函数形式,然后求解参数么?这,咳咳,你给我一个100次幂的我也能逼近,只要你给我说被逼近函数是100次幂( ′???`)

以下原回答:

因为是二次多项式,应该是无法逼近的,因为神经网路是类似于wx+b的形式,所以不逼近系数,只逼近结果的话,是阔以的,增大隐层维度,相对于用多个wx+b也就是多段函数逼近


这是很简单的呀,用liner regression就可以。其他回答怎么说不可以呢,这么简单的问题,都用不到神经网路。当然,使用神经网路也是没问题的。记得你的x_train中要包含x的平方这个feature。

随便写了一段代码,直接拷贝运行一下,应该就能明白了。

import numpy as np

np.random.seed(1337) # for reproducibility
from keras.models import Sequential
from keras.layers import Dense
import matplotlib.pyplot as plt # 可视化模块

def feature_normalize(X, *args):
X = np.mat(X)
m, n = X.shape
if len(args) == 2:
mu, sigma = args
else:
mu = np.mean(X, 0)
sigma = np.std(X, axis=0, ddof=1) # 这里有坑,记得加ddof参数
for i in range(n):
X[:, i] = (X[:, i] - mu[0, i]) / sigma[0, i]
return X, mu, sigma

# create some data
X = np.linspace(-10, 10, 200)
np.random.shuffle(X) # randomize the data
# 这里产生ax^2+bx+c,随意修改系数,然后对比程序运行结果。
Y = 34 * X * X + 12 * X + 3 + np.random.normal(0, 0.05, (200,))
# plot data
plt.scatter(X, Y)
plt.show()
t = X * X
X = np.array([X, t]).T

X_train, Y_train = X[:160], Y[:160] # train 前 160 data points
X_test, Y_test = X[160:], Y[160:] # test 后 40 data points
X_train, mu, sigma = feature_normalize(X_train)
X_test, mu, sigma = feature_normalize(X_test, mu, sigma)
model = Sequential()
model.add(Dense(1, input_dim=2))

# choose loss function and optimizing method
model.compile(loss=mse, optimizer=sgd)

# training
print(Training -----------)
for step in range(301):
cost = model.train_on_batch(X_train, Y_train)
if step % 100 == 0:
print(train cost: , cost)

# test
print(
Testing ------------)
cost = model.evaluate(X_test, Y_test, batch_size=40)
print(test cost:, cost)
W, b = model.layers[0].get_weights()

# plotting the prediction
Y_pred = model.predict(X_test)
disx = X_test[:, 0] * sigma[0, 0] + mu[0, 0]

plt.scatter(disx.getA().ravel(), Y_pred)
plt.show()

result = np.multiply(W.T, (2 / (sigma + mu)))
a = result[0, 1]
b = result[0, 0] / 2
print("最后得到二次函数的系数:a=" + str(a) + , b= + str(b))


「现在测试集有很多对x,y(x,y是很长的一维数组,二者一一对应),每对x,y数据都对应一个abc,现在要预测这些测试集所有x,y对应的abc」

信息不足以预测,所以,这么训练当然非常差了

比如说,我给你一堆 A4 纸扫描件,上面用楷体列印著7言绝句,你训练神经网路,让它识别是那篇,这个任务大概不难

我把 A4 纸全剪碎了,每片上面一个楷体字,让你训练神经网路,判断这个字属于哪一首诗

这要能训练出来,才见鬼了呢


我觉得不能,符合给定输入输出的函数有无数个,产生数据的函数只是其中准确性最高的一个,计算机演算法不可能恰巧找到这一个。


题主提问的表达有误导性。

From x to y, 可以看作为一个单输入单输出,且隐层是由三个神经元组成的神经网路,神经元激励函数分别为x^2,x,和1,而a,b和c则是weights。您所以可以用BP迭代演算法把weights算出来(这是最蠢的方法),最简单的是直接用最小二乘,你把数据输入输出全部用矩阵表示出来,然后用矩阵的伪逆就可以直接把weights找出来了。

总结:题主需要找weights,因为是一个单隐层的神经网路,在有限数据下,用矩阵伪逆求解得到的是全局最优解。任意n阶的多项式都可以用这个方法。


推荐阅读:
相关文章