神经网络模型没有提高准确性。缩放问题还是模型问题?
Neural Network model not improving accuracy. Scaling problem or model problem?
我正在尝试创建一个简单的神经网络,看看它是如何工作的。
二度方程的形式为(x-x1)*(x-x2)=0,重新排列后会变成ax^2+bx+c=0,其中a=1, b=-2*x1*x2,c=x1*x2。我想创建一个神经网络,其中输入为 (a,b),输出为 (x1,x2)。
为此,我创建了 2 个创建数据的函数,并将它们存储在名为输入和输出的矩阵中。
我创建了一个具有 2x2x2 层(包括输入和输出)的神经网络,并对其进行了测试,结果很糟糕,即使在调整之后也是如此。
我想我遇到的问题是关于数据的,因为神经网络工作并吐出结果,但它不是很好。
我不知道问题出在哪里,但我的猜测是它与数据缩放有关。我试图在不缩放的情况下引入数据,但我得到了同样糟糕的结果。
我的想法是我提供了足够的训练,所以权重和偏差是这样的,只要提供任何输入数据,结果就会非常接近所需的输出。
这是整个程序的代码
import keras
from keras import backend as K
from keras.models import Sequential
from keras.models import load_model
from keras.layers import Dense, Activation
from keras.layers.core import Dense
from keras.optimizers import SGD
from keras.metrics import categorical_crossentropy
from sklearn.metrics import confusion_matrix
import itertools
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
from random import randint
from sklearn.preprocessing import MinMaxScaler
import numpy as np
def abc(x1, x2):
b=-2*x1*x2
c=x1*x2
sol=[b,c]
return sol
a=10
b=10
c=a*b
def Nx2(N, M):
matrix=[]
n = N+ 1
m= M + 1
for i in range(1,n):
for j in range(1,m):
temp=[i,j]
matrix.append(temp)
final_matrix = np.array(matrix)
return final_matrix
output=Nx2(a, b)
# print(output)
input=[]
for i in range(0,c):
temp2=abc(output[i,0],output[i,1])
input.append(temp2)
input=np.array(input)
print(input)
train_labels = output
train_samples = input
scaler = MinMaxScaler(feature_range=(0,1))
scaled_train_samples = scaler.fit_transform((train_samples).reshape(-1,1))
scaled_train_samples=scaled_train_samples.reshape(-1,2)
scaler = MinMaxScaler(feature_range=(0,1))
scaled_train_labels = scaler.fit_transform((train_labels).reshape(-1,1))
scaled_train_labels=scaled_train_labels.reshape(-1,2)
print(scaled_train_samples)
print(scaled_train_labels)
model = Sequential([
Dense(2, input_shape=(2,), activation='sigmoid'),
Dense(2, activation='sigmoid'),
])
print(model.weights)
model.compile(SGD(lr=0.01), loss='mean_squared_error', metrics=['accuracy'])
model.fit(scaled_train_labels, scaled_train_labels, validation_split=0.2, batch_size=10, epochs=20, shuffle=True, verbose=2)
print(model.summary())
print(model.weights)
这些是我得到的结果。
Epoch 1/20
- 0s - loss: 0.1456 - accuracy: 0.5500 - val_loss: 0.3715 - val_accuracy: 0.0500 Epoch 2/20
- 0s - loss: 0.1449 - accuracy: 0.5500 - val_loss: 0.3704 - val_accuracy: 0.0500 Epoch 3/20
- 0s - loss: 0.1443 - accuracy: 0.5500 - val_loss: 0.3692 - val_accuracy: 0.0500 Epoch 4/20
- 0s - loss: 0.1437 - accuracy: 0.5500 - val_loss: 0.3681 - val_accuracy: 0.0500 Epoch 5/20
- 0s - loss: 0.1431 - accuracy: 0.5500 - val_loss: 0.3670 - val_accuracy: 0.0500 Epoch 6/20
- 0s - loss: 0.1425 - accuracy: 0.5500 - val_loss: 0.3658 - val_accuracy: 0.0500 Epoch 7/20
- 0s - loss: 0.1419 - accuracy: 0.5500 - val_loss: 0.3647 - val_accuracy: 0.0500 Epoch 8/20
- 0s - loss: 0.1413 - accuracy: 0.5500 - val_loss: 0.3636 - val_accuracy: 0.0500 Epoch 9/20
- 0s - loss: 0.1407 - accuracy: 0.5500 - val_loss: 0.3625 - val_accuracy: 0.0500 Epoch 10/20
- 0s - loss: 0.1401 - accuracy: 0.5500 - val_loss: 0.3613 - val_accuracy: 0.0500 Epoch 11/20
- 0s - loss: 0.1395 - accuracy: 0.5500 - val_loss: 0.3602 - val_accuracy: 0.0500 Epoch 12/20
- 0s - loss: 0.1389 - accuracy: 0.5500 - val_loss: 0.3591 - val_accuracy: 0.0500 Epoch 13/20
- 0s - loss: 0.1383 - accuracy: 0.5500 - val_loss: 0.3580 - val_accuracy: 0.0500 Epoch 14/20
- 0s - loss: 0.1377 - accuracy: 0.5500 - val_loss: 0.3568 - val_accuracy: 0.0500 Epoch 15/20
- 0s - loss: 0.1372 - accuracy: 0.5500 - val_loss: 0.3557 - val_accuracy: 0.0500 Epoch 16/20
- 0s - loss: 0.1366 - accuracy: 0.5500 - val_loss: 0.3546 - val_accuracy: 0.0500 Epoch 17/20
- 0s - loss: 0.1360 - accuracy: 0.5500 - val_loss: 0.3535 - val_accuracy: 0.0500 Epoch 18/20
- 0s - loss: 0.1354 - accuracy: 0.5500 - val_loss: 0.3524 - val_accuracy: 0.0500 Epoch 19/20
- 0s - loss: 0.1348 - accuracy: 0.5500 - val_loss: 0.3513 - val_accuracy: 0.0500 Epoch 20/20
- 0s - loss: 0.1342 - accuracy: 0.5500 - val_loss: 0.3502 - val_accuracy: 0.0500
有人能指出我正确的方向吗?
谢谢
您的代码存在几个问题:
你正在使用准确度来解决回归问题,这是没有意义的(准确度仅适用于分类问题).你应该只用损失来监控模型的性能,这里是 MSE(出于同样的原因,你不需要导入 confusion_matrix
或 categorical_crossentropy
)。
您错误地为最后一层使用了 sigmoid
激活;在回归问题中,这应该是 linear
(或留空,因为 linear
是默认的 Keras 激活)。
您应该对中间层使用 relu
激活,而不是 sigmoid
。
你的模型看起来太简单了,不清楚为什么你觉得只能使用 2 节点层(你应该 而不是 ,当然除外对于输出一个)。
总而言之,这里是一个起点:
model = Sequential([
Dense(30, input_shape=(2,), activation='relu'),
# Dense(10, activation='relu'), # uncomment for experimentation
Dense(2, activation='linear'),
])
model.compile(SGD(lr=0.01), loss='mean_squared_error')
但这里的暗号是实验...
最后但并非最不重要的一点是,您的 model.fit()
中似乎有错字(您传递了两次标签,而不是样本)- 请务必也修复此问题。
我正在尝试创建一个简单的神经网络,看看它是如何工作的。
二度方程的形式为(x-x1)*(x-x2)=0,重新排列后会变成ax^2+bx+c=0,其中a=1, b=-2*x1*x2,c=x1*x2。我想创建一个神经网络,其中输入为 (a,b),输出为 (x1,x2)。
为此,我创建了 2 个创建数据的函数,并将它们存储在名为输入和输出的矩阵中。
我创建了一个具有 2x2x2 层(包括输入和输出)的神经网络,并对其进行了测试,结果很糟糕,即使在调整之后也是如此。
我想我遇到的问题是关于数据的,因为神经网络工作并吐出结果,但它不是很好。
我不知道问题出在哪里,但我的猜测是它与数据缩放有关。我试图在不缩放的情况下引入数据,但我得到了同样糟糕的结果。
我的想法是我提供了足够的训练,所以权重和偏差是这样的,只要提供任何输入数据,结果就会非常接近所需的输出。
这是整个程序的代码
import keras
from keras import backend as K
from keras.models import Sequential
from keras.models import load_model
from keras.layers import Dense, Activation
from keras.layers.core import Dense
from keras.optimizers import SGD
from keras.metrics import categorical_crossentropy
from sklearn.metrics import confusion_matrix
import itertools
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
from random import randint
from sklearn.preprocessing import MinMaxScaler
import numpy as np
def abc(x1, x2):
b=-2*x1*x2
c=x1*x2
sol=[b,c]
return sol
a=10
b=10
c=a*b
def Nx2(N, M):
matrix=[]
n = N+ 1
m= M + 1
for i in range(1,n):
for j in range(1,m):
temp=[i,j]
matrix.append(temp)
final_matrix = np.array(matrix)
return final_matrix
output=Nx2(a, b)
# print(output)
input=[]
for i in range(0,c):
temp2=abc(output[i,0],output[i,1])
input.append(temp2)
input=np.array(input)
print(input)
train_labels = output
train_samples = input
scaler = MinMaxScaler(feature_range=(0,1))
scaled_train_samples = scaler.fit_transform((train_samples).reshape(-1,1))
scaled_train_samples=scaled_train_samples.reshape(-1,2)
scaler = MinMaxScaler(feature_range=(0,1))
scaled_train_labels = scaler.fit_transform((train_labels).reshape(-1,1))
scaled_train_labels=scaled_train_labels.reshape(-1,2)
print(scaled_train_samples)
print(scaled_train_labels)
model = Sequential([
Dense(2, input_shape=(2,), activation='sigmoid'),
Dense(2, activation='sigmoid'),
])
print(model.weights)
model.compile(SGD(lr=0.01), loss='mean_squared_error', metrics=['accuracy'])
model.fit(scaled_train_labels, scaled_train_labels, validation_split=0.2, batch_size=10, epochs=20, shuffle=True, verbose=2)
print(model.summary())
print(model.weights)
这些是我得到的结果。
Epoch 1/20
- 0s - loss: 0.1456 - accuracy: 0.5500 - val_loss: 0.3715 - val_accuracy: 0.0500 Epoch 2/20
- 0s - loss: 0.1449 - accuracy: 0.5500 - val_loss: 0.3704 - val_accuracy: 0.0500 Epoch 3/20
- 0s - loss: 0.1443 - accuracy: 0.5500 - val_loss: 0.3692 - val_accuracy: 0.0500 Epoch 4/20
- 0s - loss: 0.1437 - accuracy: 0.5500 - val_loss: 0.3681 - val_accuracy: 0.0500 Epoch 5/20
- 0s - loss: 0.1431 - accuracy: 0.5500 - val_loss: 0.3670 - val_accuracy: 0.0500 Epoch 6/20
- 0s - loss: 0.1425 - accuracy: 0.5500 - val_loss: 0.3658 - val_accuracy: 0.0500 Epoch 7/20
- 0s - loss: 0.1419 - accuracy: 0.5500 - val_loss: 0.3647 - val_accuracy: 0.0500 Epoch 8/20
- 0s - loss: 0.1413 - accuracy: 0.5500 - val_loss: 0.3636 - val_accuracy: 0.0500 Epoch 9/20
- 0s - loss: 0.1407 - accuracy: 0.5500 - val_loss: 0.3625 - val_accuracy: 0.0500 Epoch 10/20
- 0s - loss: 0.1401 - accuracy: 0.5500 - val_loss: 0.3613 - val_accuracy: 0.0500 Epoch 11/20
- 0s - loss: 0.1395 - accuracy: 0.5500 - val_loss: 0.3602 - val_accuracy: 0.0500 Epoch 12/20
- 0s - loss: 0.1389 - accuracy: 0.5500 - val_loss: 0.3591 - val_accuracy: 0.0500 Epoch 13/20
- 0s - loss: 0.1383 - accuracy: 0.5500 - val_loss: 0.3580 - val_accuracy: 0.0500 Epoch 14/20
- 0s - loss: 0.1377 - accuracy: 0.5500 - val_loss: 0.3568 - val_accuracy: 0.0500 Epoch 15/20
- 0s - loss: 0.1372 - accuracy: 0.5500 - val_loss: 0.3557 - val_accuracy: 0.0500 Epoch 16/20
- 0s - loss: 0.1366 - accuracy: 0.5500 - val_loss: 0.3546 - val_accuracy: 0.0500 Epoch 17/20
- 0s - loss: 0.1360 - accuracy: 0.5500 - val_loss: 0.3535 - val_accuracy: 0.0500 Epoch 18/20
- 0s - loss: 0.1354 - accuracy: 0.5500 - val_loss: 0.3524 - val_accuracy: 0.0500 Epoch 19/20
- 0s - loss: 0.1348 - accuracy: 0.5500 - val_loss: 0.3513 - val_accuracy: 0.0500 Epoch 20/20
- 0s - loss: 0.1342 - accuracy: 0.5500 - val_loss: 0.3502 - val_accuracy: 0.0500
有人能指出我正确的方向吗?
谢谢
您的代码存在几个问题:
你正在使用准确度来解决回归问题,这是没有意义的(准确度仅适用于分类问题).你应该只用损失来监控模型的性能,这里是 MSE(出于同样的原因,你不需要导入
confusion_matrix
或categorical_crossentropy
)。您错误地为最后一层使用了
sigmoid
激活;在回归问题中,这应该是linear
(或留空,因为linear
是默认的 Keras 激活)。您应该对中间层使用
relu
激活,而不是sigmoid
。你的模型看起来太简单了,不清楚为什么你觉得只能使用 2 节点层(你应该 而不是 ,当然除外对于输出一个)。
总而言之,这里是一个起点:
model = Sequential([
Dense(30, input_shape=(2,), activation='relu'),
# Dense(10, activation='relu'), # uncomment for experimentation
Dense(2, activation='linear'),
])
model.compile(SGD(lr=0.01), loss='mean_squared_error')
但这里的暗号是实验...
最后但并非最不重要的一点是,您的 model.fit()
中似乎有错字(您传递了两次标签,而不是样本)- 请务必也修复此问题。