【问题标题】:Tensorflow Keras output styleTensorFlow Keras 输出风格
【发布时间】:2018-10-16 13:21:16
【问题描述】:

我在 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)

我认为这基本上意味着我将标签作为一个热向量提供。有了这条线,在这个非常简单的任务上,训练完全符合我的要求。所以,我的问题是:

  • 为什么这不适用于第一行而适用于第二行?
  • 我需要做什么才能将输出提供给 keras,而不是作为一个热向量?我不介意转换。只是我见过的一些例子——甚至是 MNIST——似乎在输入它们之前都没有将它们的标签转换为一个热点。这里有什么问题? keras 是否正在尝试以我不期望的方式转换我给它的数字/其他标签?如果是这样,它如何转换这些标签以便我可以正确预测响应?

【问题讨论】:

    标签: python tensorflow keras


    【解决方案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
    

    【讨论】:

    • 我唯一不太明白的是:在我原来的行中,它是如何解释均方误差的?数据有两个不同的维度:一个是四维的(输出),另一个是一维的(所需的标签)。我认为它会解释分类标签并将它们转换为一个热点,只是因为我不明白它还能如何计算诸如均方误差之类的东西。 (1,0,0,0) 和 3 之间的均方误差是多少?
    • 均方误差只处理输入和输出之间的“连续”函数,y = f(x)。这里没有一种热编码的概念,至少不是我以前见过的任何约定。另一方面,使用交叉熵损失,它确实具有分类数据的概念(即表示不同类别标签的整数)。仅针对这种类型的损失,keras 有我在回答中提到的sparse 版本,这样你就不用担心将标签号转换为一个热向量,并且在内部完成的效率更高。
    • 以下内容与您对上述内容的回答相切,这已经足够了。也许我不理解均方误差,但我仍然对它在计算什么感到困惑。网络的输出应该是一个向量,不是吗?我仍然对程序如何解释网络的矢量输出和提供的数字标签之间的平均误差感到困惑?我的问题清楚了吗?
    • 对于mse loss 它没有,它给出了一个错误。对于sparse categorical crossentropy,它会将inds 标签转换为内部第一个热标签。
    猜你喜欢
    • 2020-01-05
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2018-08-23
    相关资源
    最近更新 更多