我正试图在python中创建一个程序,该程序使用机器学习来预测数字的平方根。我列出了我在我的程序中所做的一切:-
- 创建了一个包含数字及其平方的csv文件
- 将csv中的数据提取为合适的变量(X存储正方形,y存储数字(
- 使用sklearn的StandardScaler缩放数据
- 构建了具有两个隐藏层的人工神经网络,每个隐藏层有6个单元(没有激活函数(
- 使用SGD作为优化器,使用均方误差作为损失函数来编译ANN
- 训练模型。损失约0.063
- 尝试过预测,但结果是另一回事
我的实际代码:-
import numpy as np
import tensorflow as tf
import pandas as pd
df = pd.read_csv('CSV/SQUARE-ROOT.csv')
X = df.iloc[:, 1].values
X = X.reshape(-1, 1)
y = df.iloc[:, 0].values
y = y.reshape(-1, 1)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.2)
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_test_sc = sc.fit_transform(X_test)
X_train_sc = sc.fit_transform(X_train)
sc1 = StandardScaler()
y_test_sc1 = sc1.fit_transform(y_test)
y_train_sc1 = sc1.fit_transform(y_train)
ann = tf.keras.models.Sequential()
ann.add(tf.keras.layers.Dense(units=6))
ann.add(tf.keras.layers.Dense(units=6))
ann.add(tf.keras.layers.Dense(units=1))
ann.compile(optimizer='SGD', loss=tf.keras.losses.MeanSquaredError())
ann.fit(x = X_train_sc, y = y_train_sc1, batch_size=5, epochs = 100)
print(sc.inverse_transform(ann.predict(sc.fit_transform([[144]]))))
输出:-array([[143.99747]], dtype=float32)
输出不应该是12吗?为什么它给了我错误的结果?
我还附上了我用来训练我的模型的csv文件:SQUARE-ROOT.csv
TL;DR:您确实需要这些非线性。
它不起作用的原因可能是几个原因中的一个(或组合(,如输入数据范围不好、数据有缺陷、安装过度/不足等。
然而,在这种特定情况下,您构建的模型实际上无法学习您试图近似的函数,因为不具有非线性使其成为纯线性模型,无法准确地近似非线性函数。
Dense
层实现如下:
x_res = activ_func(w*x + b)
其中x
是层输入,w
是权重,b
是偏置向量,activ_func
是激活函数(如果定义了一个(。
然后,你的模型在数学上变成了(我对三个密集层使用索引1到3(:
pred = w3 * (w2 * ( w1 * x + b1 ) + b2 ) + b3
= w3*w2*w1*x + w3*w2*b1 + w3*b2 + b3
正如您所看到的,生成的模型仍然是线性的。添加激活函数,您的模式也可以学习非线性函数。从那里,对超参数进行实验,看看模型的性能是如何变化的。
您的代码不起作用的原因是您将fit_transform
应用于测试集,这是错误的。您可以通过将fit_transform(test)
替换为transform(test)
来修复它。虽然我不认为StandardScaler
是必要的,但请尝试这个:
import numpy as np
import tensorflow as tf
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
N = 10000
X = np.arange(1, N).reshape(-1, 1)
y = np.sqrt(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.2)
sc = StandardScaler()
X_train_sc = sc.fit_transform(X_train)
#X_test_sc = sc.fit_transform(X_test) # wrong!!!
X_test_sc = sc.transform(X_test)
sc1 = StandardScaler()
y_train_sc1 = sc1.fit_transform(y_train)
#y_test_sc1 = sc1.fit_transform(y_test) # wrong!!!
y_test_sc1 = sc1.transform(y_test)
ann = tf.keras.models.Sequential()
ann.add(tf.keras.layers.Dense(units=32, activation='relu')) # you have 10000 data, maybe you need a little deeper network
ann.add(tf.keras.layers.Dense(units=32, activation='relu'))
ann.add(tf.keras.layers.Dense(units=32, activation='relu'))
ann.add(tf.keras.layers.Dense(units=1))
ann.compile(optimizer='SGD', loss='MSE')
ann.fit(x=X_train_sc, y=y_train_sc1, batch_size=32, epochs=100, validation_data=(X_test_sc, y_test_sc1))
#print(sc.inverse_transform(ann.predict(sc.fit_transform([[144]])))) # wrong!!!
print(sc1.inverse_transform(ann.predict(sc.transform([[144]]))))