【问题标题】:inconsistent results between Keras and MLPClassifier sklearnKeras 和 MLPClassifier sklearn 之间的结果不一致
【发布时间】:2017-10-22 11:32:58
【问题描述】:

我一直在阅读 Keras 文档来构建我自己的 MLP 网络来实现 MLP 反向传播。我熟悉 sklearn 中的 MLPClassifier,但我想学习 Keras 进行深度学习。以下是第一次尝试。该网络有 3 层,1 个输入(特征=64),1 个输出和 1 个隐藏层。总数为(64,64,1)。输入是numpy 矩阵X 的125K 样本(64 暗淡),y 是一维numpy 二进制类(1,-1):

# Keras imports
from keras.models import Sequential
from sklearn.model_selection import train_test_split
from keras.layers import Dense, Dropout, Activation
from keras.initializers import RandomNormal, VarianceScaling, RandomUniform
from keras.optimizers import SGD, Adam, Nadam, RMSprop

# System imports
import sys
import os
import numpy as np
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'


def train_model(X, y, num_streams, num_stages):

    '''
    STEP1: Initialize the Model
    '''

    tr_X, ts_X, tr_y, ts_y = train_test_split(X, y, train_size=.8)
    model = initialize_model(num_streams, num_stages)

    '''
    STEP2: Train the Model
    '''
    model.compile(loss='binary_crossentropy',
                  optimizer=Adam(lr=1e-3),
                  metrics=['accuracy'])
    model.fit(tr_X, tr_y,
              validation_data=(ts_X, ts_y),
              epochs=3,
              batch_size=200)


def initialize_model(num_streams, num_stages):

    model = Sequential()
    hidden_units = 2 ** (num_streams + 1)
    # init = VarianceScaling(scale=5.0, mode='fan_in', distribution='normal')
    init_bound1 = np.sqrt(3.5 / ((num_stages + 1) + num_stages))
    init_bound2 = np.sqrt(3.5 / ((num_stages + 1) + hidden_units))
    init_bound3 = np.sqrt(3.5 / (hidden_units + 1))
    # drop_out = np.random.uniform(0, 1, 3)

    # This is the input layer (that's why you have to state input_dim value)
    model.add(Dense(num_stages,
                    input_dim=num_stages,
                    activation='relu',
                    kernel_initializer=RandomUniform(minval=-init_bound1, maxval=init_bound1)))

    model.add(Dense(hidden_units,
                    activation='relu',
                    kernel_initializer=RandomUniform(minval=-init_bound2, maxval=init_bound2)))

    # model.add(Dropout(drop_out[1]))

    # This is the output layer
    model.add(Dense(1,
                    activation='sigmoid',
                    kernel_initializer=RandomUniform(minval=-init_bound3, maxval=init_bound3)))

    return model

问题是我在使用MLPClassifier sklearn 时使用相同的数据集Xy 获得了99% 的准确率。但是,Keras 的准确性很差,如下所示:

Train on 100000 samples, validate on 25000 samples
Epoch 1/3
100000/100000 [==============================] - 1s - loss: -0.5358 - acc: 0.0022 - val_loss: -0.7322 - val_acc: 0.0000e+00
Epoch 2/3
100000/100000 [==============================] - 1s - loss: -0.6353 - acc: 0.0000e+00 - val_loss: -0.7385 - val_acc: 0.0000e+00
Epoch 3/3
100000/100000 [==============================] - 1s - loss: -0.7720 - acc: 9.0000e-05 - val_loss: -0.9474 - val_acc: 5.2000e-04

我不明白为什么?我在这里错过了什么吗?任何帮助表示赞赏。

【问题讨论】:

    标签: neural-network deep-learning keras


    【解决方案1】:

    我认为问题在于您使用的是 sigmoid 输出层(绑定到 [0, 1])但您的类是 (1, -1),您需要更改输出值或使用 tanh .

    此外,keras 层的默认参数可能与 sklearn 不同,请务必查看文档中的参数。

    最后一件事,对于kernel_initializer 试试glorot_uniform,这是一个很好的默认值。

    【讨论】:

      【解决方案2】:

      通过在训练模型之前将您的标记数据转换为一个热代码来检查。

      如需详细了解为何使用一个热门代码,请查看https://machinelearningmastery.com/why-one-hot-encode-data-in-machine-learning/

      【讨论】:

      • 不是这样的,这是一个二分类问题
      猜你喜欢
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      • 2016-06-15
      • 1970-01-01
      • 2020-10-06
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      相关资源
      最近更新 更多