在Keras中创建虚拟模型时遇到了一件奇怪的事情。由于现在不重要的原因,我决定尝试训练一组权重以使其成为单位矩阵。我的代码如下:
import tensorflow as tf
from tensorflow import keras
import numpy as np
tfe = tf.contrib.eager
tf.enable_eager_execution()
i4 = np.eye(4)
inds = np.random.randint(0,4,size=2000)
data = i4[inds]
model = keras.Sequential([keras.layers.Dense(4, kernel_regularizer=
keras.regularizers.l2(.001), kernel_initializer='zeros')])
model.compile(optimizer=tf.train.AdamOptimizer(.001), loss= 'mse', metrics = ['accuracy'])
model.fit(data,inds, epochs=50)
这确实是一个非常简单的任务。我将最后一行更改为
model.fit(data, data, epochs =50)
从本质上讲,这意味着我正在将标签作为一种热门矢量进行馈送。通过这条线,培训完全可以完成我想要的这项非常简单的任务。所以,我的问题是:
答案 0 :(得分:1)
您使用的模型正在尝试最小化均方误差。因此,很明显,第二行是可行的方法:
model.fit(data, data, epochs=50)
因为要学习单位矩阵,所以我们应该有:x =y
,因此数据既是输入也是输出。
为什么这不起作用:
model.fit(data, inds, epochs=50)
好吧,在这种情况下,您的网络输出大小为4(密集层),但是您给它的输出大小为1(inds)。您应该得到一个错误...
如何在不使用一个热向量作为输出向量的情况下做到这一点:
一种方法是使用稀疏的分类交叉熵损失,例如:
i4 = np.eye(4)
inds = np.random.randint(0,4,size=32)
data = i4[inds]
model = keras.Sequential([keras.layers.Dense(4, kernel_initializer='zeros', activation='softmax')])
model.compile(optimizer=tf.train.AdamOptimizer(.001), loss= 'sparse_categorical_crossentropy', metrics = ['accuracy'])
model.fit(data, inds, epochs=50)
然后您会看到模型非常准确地适合inds
:
In [4]: np.argmax(model.predict(data), axis=1)
Out[4]:
array([3, 1, 1, 3, 0, 3, 2, 0, 2, 1, 0, 2, 0, 0, 1, 2, 3, 2, 3, 0, 3, 2,
1, 2, 3, 3, 3, 1, 0, 1, 2, 0])
In [5]: inds
Out[5]:
array([3, 1, 1, 3, 0, 3, 2, 0, 2, 1, 0, 2, 0, 0, 1, 2, 3, 2, 3, 0, 3, 2,
1, 2, 3, 3, 3, 1, 0, 1, 2, 0])
和火车精度:
In [6]: np.mean(np.argmax(model.predict(data), axis=1) == inds)
Out[6]: 1.0