我试图用一个非常简单的线性网络来解决多线性回归问题。该网络仅包含一个密集层作为其输出层,并且激活函数设置为线性。我通过将输入数据 X 乘以系统(权重)矩阵 A 来合成输出数据 Y: Y=AX 。X 和 A 都包含具有正态或均匀分布的随机数(无论如何都会出现问题)。在这种情况下,网络在 1000 个样本中仅 7 个 Epoch 就达到了 99% 以上的准确率,正如人们所期望的那样。
现在,如果我从 Y 合成 X,这一次具有统一的随机数,使用 A 的逆: X = inv(A).Y ,并尝试训练网络,经过 200 个 Epoch 后,准确率仅达到 94%。
即使系统矩阵(权重)完全相同,为什么这两种情况之间存在如此巨大的差异。唯一的区别与 X 和 Y 的随机分布有关。如果我被迫遵循第二种情况,我该如何提高我的网络的可训练性,以便它可以在几个 epoch 内进行训练。
我尝试了不同的优化器、初始化器和正则化,但它们没有帮助。
这是不太好收敛的版本的代码。为了获得我使用的第一个版本gen1
,Dataset.from_generator(gen2, ...)
而不是gen2
.
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import keras
N = 256
np.random.seed(0)
A = np.random.normal(0,.4,(N,N))
Ainv = np.linalg.inv(A)
import itertools
input_size = N
def gen1():
for i in itertools.count(1):
X = np.random.rand(N,1)-.5
Y = np.dot(A,X)
yield (X[:,0],Y[:,0])
def gen2():
for i in itertools.count(1):
Y = np.random.rand(N,1)-0.5
X = np.dot(Ainv,Y)
yield (X[:,0],Y[:,0])
dataset = tf.data.Dataset.from_generator(
gen2,
(tf.float64, tf.float64),
(tf.TensorShape([N]), tf.TensorShape([N])))
train_ds = dataset.take(950)
valid_ds = dataset.skip(950).take(50)
#train_ds = train_ds.shuffle(2000, reshuffle_each_iteration = True)
train_ds = train_ds.batch(1)
valid_ds = valid_ds.batch(1)
from keras.layers import Input, Dense
from keras.models import Model
from keras import backend
def rabs(y_t, y_p):
return backend.mean(backend.abs(y_p - y_t), axis=-1)/(tf.keras.backend.max(y_t) - tf.keras.backend.min(y_t))*100
inp = Input(shape=(input_size,))
out = Dense(N, activation='linear')(inp)
autoencoder = Model(inp, out)
#opt = tf.keras.optimizers.Adam(learning_rate=.0001)
opt = tf.keras.optimizers.SGD(learning_rate=.2, momentum=0.7)
autoencoder.compile(optimizer= opt,
loss=tf.keras.losses.MeanSquaredError(),metrics= [rabs])
autoencoder.summary()
autoen_model = autoencoder.fit(train_ds, validation_data = valid_ds, epochs = 200)
plt.plot(autoen_model.history['rabs'])
plt.plot(autoen_model.history['val_rabs'])
plt.title('Model Accuracy')
plt.ylabel('Relative Absolute Mean Error %')
plt.xlabel('Epoch')
plt.legend(['Training set', 'Validation set'], loc='upper left')
plt.show()
训练图
案例1:Y合成
案例2:X合成