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()