5

我想使用多層神經網絡來預測第n個平方。神經網絡預測第n平方

我有一個包含第一99個平方

1 1 
2 4 
3 9 
4 16 
5 25 
... 
98 9604 
99 9801 

這以下訓練數據是代碼:

import numpy as np 
import neurolab as nl 

# Load input data 
text = np.loadtxt('data_sq.txt') 

# Separate it into datapoints and labels 
data = text[:, :1] 
labels = text[:, 1:] 

# Define a multilayer neural network with 2 hidden layers; 
# First hidden layer consists of 10 neurons 
# Second hidden layer consists of 6 neurons 
# Output layer consists of 1 neuron 
nn = nl.net.newff([[0, 99]], [10, 6, 1]) 

# Train the neural network 
error_progress = nn.train(data, labels, epochs=2000, show=10, goal=0.01) 

# Run the classifier on test datapoints 
print('\nTest results:') 
data_test = [[100], [101]] 
for item in data_test: 
    print(item, '-->', nn.sim([item])[0]) 

哪兩個第100和第101個正方形打印1:

Test results: 
[100] --> [ 1.] 
[101] --> [ 1.] 

這樣做的正確方法是什麼?

+0

什麼是文本變量的數據格式? –

+1

你確定神經網絡應該能夠做到這一點嗎?在我的經驗中,神經網絡並不擅長數學推理。 – Seanny123

+0

@ Seanny123我不知道。我也試圖找到這個 - 如果這對神經網絡或AI來說是一個很好的問題。如果不是NN,線性分類器是否合適? – gammay

回答

2

檢查neurolab的文檔 - newff默認情況下在所有神經元中創建NN與sigmoid傳遞函數。乙狀結腸的值總是在(-1; 1)範圍內,所以你的輸出永遠不會離開這個範圍。

第二方陣(4)已經不在此範圍內,因此您的代碼完全不符合你的問題。使用其他功能(我建議SoftPlus or ReLU

嘗試。它們在前饋網絡中工作得非常好,可以進行反向傳播訓練(因爲它們可以在整個域中導出),並且具有範圍爲(0, ∞)的值,就像你需要的一樣。

另外:newff的第一個參數定義了輸入數據的範圍 - 您使用的是與所有訓練數據匹配的[0,99],但與測試時嘗試的值不匹配(因爲100和101大於99)。將此值更改爲更大的值,因此您測試的值不是「特殊的」(意思是「在範圍末尾」) - 我會提出類似[-300, 300]的東西。

此外,正如評論由Seanny123說,我不認爲這會在所有的工作,但目前的設置我可以肯定的說。祝你好運。如果你成功了,讓我知道(例如在評論中)。

最後,但並非最不重要 - 你試圖做的是外推(找出值超出該範圍的基礎上值一定範圍內的)。 NN更適合插值(根據該範圍內的樣本計算出範圍內的值),因爲它們可以推廣用於訓練的數據。嘗試教它的正方形,例如每3平方(如1,16,49,...),然後通過詢問其餘的正方形(例如要求2或8的平方)進行測試。

+0

跟着你和Seanny123的建議,我實現了網絡。你可以在我的答案中看到結果。 –

+0

不錯。我想知道如果你已經教過數字並在相同範圍內進行奇數測試會發生什麼。我猜你會接近完美的比賽,但是很確定地看到這一點很好。 –

+1

我檢查並更新了我對這個案例的回答。這場比賽確實非常好。 –

2

繼菲利普Malczak的和Seanny123的建議和意見,我在tensorflow實現的神經網絡來檢查當我們試圖教它來預測(和插值)的2次方會發生什麼。

訓練對連續間隔

我訓練網絡上的區間[-7,7-](以300點此區間內,使之連續的),然後測試了它在區間[ - 30,30]。激活函數是ReLu,網絡有3個隱藏層,每個隱藏層的大小爲50個。時期= 500。結果如下圖所示。因此,基本上,在(和也接近)區間[-7,7]內,該擬合是相當完美的,然後它在外部或多或少呈線性延伸。很高興看到至少在最初時,網絡輸出的斜率試圖「匹配」x^2的斜率。如果我們提高了測試的時間間隔,這兩個圖表分歧頗多,作爲一個可以在下面的圖中看到:

enter image description here

在偶數培訓

最後,如果不是我訓練網絡在間隔[-100,100]的所有偶數集合中,並將其應用於此間隔中的所有整數集合(偶數和奇數),我得到:enter image description here

當訓練網絡以生成圖像以上,我把時代增加到2500到獲得更好的準確性。其餘參數保持不變。因此,似乎在訓練間隔內「插入」工作得相當好(可能除了0附近的區域,其中擬合稍差)。

這裏是我使用的第一個數字代碼:

import tensorflow as tf 
import matplotlib.pyplot as plt 
import numpy as np 
from tensorflow.python.framework.ops import reset_default_graph 

#preparing training data 
train_x=np.linspace(-7,7,300).reshape(-1,1) 
train_y=train_x**2 

#setting network features 
dimensions=[50,50,50,1] 
epochs=500 
batch_size=5 

reset_default_graph() 
X=tf.placeholder(tf.float32, shape=[None,1]) 
Y=tf.placeholder(tf.float32, shape=[None,1]) 

weights=[] 
biases=[] 
n_inputs=1 

#initializing variables 
for i,n_outputs in enumerate(dimensions): 
    with tf.variable_scope("layer_{}".format(i)): 
     w=tf.get_variable(name="W",shape=[n_inputs,n_outputs],initializer=tf.random_normal_initializer(mean=0.0,stddev=0.02,seed=42)) 
     b=tf.get_variable(name="b",initializer=tf.zeros_initializer(shape=[n_outputs])) 
     weights.append(w) 
     biases.append(b) 
     n_inputs=n_outputs 

def forward_pass(X,weights,biases): 
    h=X 
    for i in range(len(weights)): 
     h=tf.add(tf.matmul(h,weights[i]),biases[i]) 
     h=tf.nn.relu(h) 
    return h 

output_layer=forward_pass(X,weights,biases) 
cost=tf.reduce_mean(tf.squared_difference(output_layer,Y),1) 
cost=tf.reduce_sum(cost) 
optimizer=tf.train.AdamOptimizer(learning_rate=0.01).minimize(cost) 


with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 
    #train the network 
    for i in range(epochs): 
     idx=np.arange(len(train_x)) 
     np.random.shuffle(idx) 
     for j in range(len(train_x)//batch_size): 
      cur_idx=idx[batch_size*j:(batch_size+1)*j] 
      sess.run(optimizer,feed_dict={X:train_x[cur_idx],Y:train_y[cur_idx]}) 
     #current_cost=sess.run(cost,feed_dict={X:train_x,Y:train_y}) 
     #print(current_cost) 
    #apply the network on the test data 
    test_x=np.linspace(-30,30,300) 
    network_output=sess.run(output_layer,feed_dict={X:test_x.reshape(-1,1)})  



plt.plot(test_x,test_x**2,color='r',label='y=x^2') 
plt.plot(test_x,network_output,color='b',label='network output') 
plt.legend(loc='center') 
plt.show()