【问题标题】:Keras - Trying to get 'logits' - one layer before the softmax activation functionKeras - 试图获得'logits' - 在softmax激活函数之前的一层
【发布时间】:2022-02-14 12:19:36
【问题描述】:

我正在尝试从我的 Keras CNN 分类器中提取“logits”。 我在这里尝试了建议的方法:link.

首先我创建了两个模型来检查实现:

  1. create_CNN_MNIST 返回 softmax 概率的 CNN 分类器。
  2. create_CNN_MNIST_logits CNN 具有与 (1) 中相同的层,但在最后一层略有扭曲 - 将激活函数更改为线性以返回 logits。

两个模型都输入了相同的 MNIST 训练和测试数据。然后我在 logits 上应用了 softmax,我得到了来自 softmax CNN 的不同输出。

我在我的代码中找不到问题。也许您可以帮助建议另一种从模型中提取“logits”的方法?

代码:

def softmax(x):
    """Compute softmax values for each sets of scores in x."""
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum(axis=0)

def create_CNN_MNIST_logits() :
    model = Sequential()
    model.add(Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_uniform', input_shape=(28, 28, 1)))
    model.add(MaxPooling2D((2, 2)))
    model.add(Flatten())
    model.add(Dense(100, activation='relu', kernel_initializer='he_uniform'))
    model.add(Dense(10, activation='linear'))
    # compile model
    opt = SGD(learning_rate=0.01, momentum=0.9)
    
    def my_sparse_categorical_crossentropy(y_true, y_pred):
        return keras.losses.categorical_crossentropy(y_true, y_pred, from_logits=True)
    
    model.compile(optimizer=opt, loss=my_sparse_categorical_crossentropy, metrics=['accuracy'])
    return model

def create_CNN_MNIST() :
    model = Sequential()
    model.add(Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_uniform', input_shape=(28, 28, 1)))
    model.add(MaxPooling2D((2, 2)))
    model.add(Flatten())
    model.add(Dense(100, activation='relu', kernel_initializer='he_uniform'))
    model.add(Dense(10, activation='softmax'))
    # compile model
    opt = SGD(learning_rate=0.01, momentum=0.9)
    model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
    return model

# load data
X_train = np.load('./data/X_train.npy')
X_test = np.load('./data/X_test.npy')
y_train = np.load('./data/y_train.npy')
y_test = np.load('./data/y_test.npy')


#create models
model_softmax = create_CNN_MNIST()
model_logits = create_CNN_MNIST_logits()


pixels = 28
channels = 1
num_labels = 10

# Reshaping to format which CNN expects (batch, height, width, channels)
trainX_cnn = X_train.reshape(X_train.shape[0], pixels, pixels, channels).astype('float32')
testX_cnn = X_test.reshape(X_test.shape[0], pixels, pixels, channels).astype('float32')

# Normalize images from 0-255 to 0-1
trainX_cnn /= 255
testX_cnn /= 255

train_y_cnn = utils.to_categorical(y_train, num_labels)
test_y_cnn = utils.to_categorical(y_test, num_labels)


#train the models:
model_logits.fit(trainX_cnn, train_y_cnn, validation_split=0.2, epochs=10,
                          batch_size=32)
model_softmax.fit(trainX_cnn, train_y_cnn, validation_split=0.2, epochs=10,
                          batch_size=32)

在评估阶段,我会在 logits 上做 softmax 以检查它是否与常规模型相同:

#predict
y_pred_softmax = model_softmax.predict(testX_cnn)
y_pred_logits = model_logits.predict(testX_cnn)

#apply softmax on the logits to get the same result of regular CNN
y_pred_logits_activated = softmax(y_pred_logits)

现在我在 y_pred_logits_activatedy_pred_softmax 中得到不同的值,导致测试集的准确度不同。

【问题讨论】:

    标签: tensorflow machine-learning keras deep-learning conv-neural-network


    【解决方案1】:

    您的模型可能正在接受不同的训练,请确保在两个 fit 命令之前设置种子,以便它们初始化相同的权重并具有相同的 train/val 拆分。另外,softmax 是否可能不正确:

    def softmax(x):
        """Compute softmax values for each sets of scores in x."""
        e_x = np.exp(x) 
        return e_x / e_x.sum(axis=1)
    

    这在数值上相当于减去最大值 (https://stackoverflow.com/a/34969389/10475762),如果矩阵的形状为 [batch, outputs],则轴应为 1。

    【讨论】:

      猜你喜欢
      • 2021-03-19
      • 2020-09-12
      • 2018-02-07
      • 2021-03-23
      • 2018-06-27
      • 2018-01-11
      • 2020-02-13
      • 1970-01-01
      • 2019-04-16
      相关资源
      最近更新 更多