比如已知一個數學模型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階的多項式都可以用這個方法。


推薦閱讀:
相關文章