【问题标题】:Super low accuracy for neural network model神经网络模型的超低精度
【发布时间】:2020-04-04 07:42:20
【问题描述】:

我遵循了使用代码交叉验证进行神经网络模型评估的教程:

# Multiclass Classification with the Iris Flowers Dataset 
import numpy 
import pandas 
from keras.models import Sequential 
from keras.layers import Dense 
from keras.wrappers.scikit_learn import KerasClassifier 
from keras.utils import np_utils 
from sklearn.model_selection import cross_val_score 
from sklearn.model_selection import KFold 
from sklearn.preprocessing import LabelEncoder 
from sklearn.pipeline import Pipeline 
# fix random seed for reproducibility 
seed = 7 
numpy.random.seed(seed) 
# load dataset 
dataframe = pandas.read_csv("/content/drive/My Drive/iris.data", header=None) 
dataset = dataframe.values 
X = dataset[:,0:4].astype(float) 
Y = dataset[:,4] 

# encode class values as integers 
encoder = LabelEncoder() 
encoder.fit(Y) 
encoded_Y = encoder.transform(Y) 

# convert integers to dummy variables (i.e. one hot encoded) 
dummy_y = np_utils.to_categorical(encoded_Y) 

# define baseline model 
def baseline_model():

# create model
  model = Sequential()
  model.add(Dense(4, input_dim=4, activation="relu", kernel_initializer="normal"))
  model.add(Dense(3, activation="sigmoid", kernel_initializer="normal"))

# Compile model
  model.compile(loss= 'categorical_crossentropy' , optimizer= 'adam' , metrics=[ 'accuracy' ])

  return model 
estimator = KerasClassifier(build_fn=baseline_model, nb_epoch=200, batch_size=5, verbose=0) 
kfold = KFold(n_splits=10, shuffle=True, random_state=seed) 
results = cross_val_score(estimator, X, dummy_y, cv=kfold) 
print("Accuracy: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))

准确度应该在95.33% (4.27%) 左右,但经过几次尝试我得到了~Accuracy: 34.00% (13.15%)。模型代码似乎完全相同。我按照指示从here 下载了数据。会出什么问题?谢谢

【问题讨论】:

    标签: python machine-learning keras neural-network cross-validation


    【解决方案1】:

    替换这个:

    model.add(Dense(4, input_dim=4, activation="relu", kernel_initializer="normal"))
    

    有了这个:

    model.add(Dense(16, activation="relu"))
    model.add(Dense(32, activation="relu"))
    

    然后,你的输出层为:

    model.add(Dense(3, activation="softmax", kernel_initializer="normal"))
    

    你的隐藏层微不足道,你的激活函数是错误的。对于 3 个以上的课程,它必须是 softmax

    完整工作代码:

    import numpy
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.wrappers.scikit_learn import KerasClassifier
    from keras.utils import np_utils
    from sklearn.model_selection import cross_val_score
    from sklearn.model_selection import KFold
    from sklearn.preprocessing import MinMaxScaler
    
    seed = 7
    numpy.random.seed(seed)
    
    from sklearn.datasets import load_iris
    
    X, encoded_Y = load_iris(return_X_y=True)
    mms = MinMaxScaler()
    X = mms.fit_transform(X)
    
    dummy_y = np_utils.to_categorical(encoded_Y)
    
    def baseline_model():
    
        model = Sequential()
        model.add(Dense(4, input_dim=4, activation="relu", kernel_initializer="normal"))
        model.add(Dense(8, activation="relu", kernel_initializer="normal"))
        model.add(Dense(3, activation="softmax", kernel_initializer="normal"))
    
        model.compile(loss= 'categorical_crossentropy' , optimizer='adam', metrics=[
            'accuracy' ])
    
        return model
    
    estimator = KerasClassifier(build_fn=baseline_model, epochs=200, verbose=0)
    kfold = KFold(n_splits=10, shuffle=True, random_state=seed)
    results = cross_val_score(estimator, X, dummy_y, cv=kfold)
    print(results)
    
    Out[5]: 
    array([0.60000002, 0.93333334, 1.        , 0.66666669, 0.80000001,
           1.        , 1.        , 0.93333334, 0.80000001, 0.86666667])
    

    【讨论】:

    • 感谢您的帮助。它略微提高到36.67% (15.28%),但不幸的是仍然很低..
    • 在密集之前尝试 CNN。
    • @NicolasGervais 谢谢。我得到了同样的结果。我不确定 10 个输出中有 2 个大约是 60%。这是否意味着 2/10 试验的准确度较低,表明模型性能可能不稳定?教程怎么可能做到95.33%
    • 性能有点不稳定,因为它是一个很小的数据集,变量很少。当您进行“折叠”时,您的数据集甚至更小。诚然,我并没有过多地使用超参数。我只是想让它工作。您可能希望降低优化器的学习率,使其不会徘徊在最小值附近。
    【解决方案2】:

    仅凭机会,您应该获得 33% 的准确率。

    如何改进代码:

    1. 规范化数据。
    from sklearn.preprocessing import StandardScaler, MinMaxScaler
    
    scaler = StandardScaler()
    X = scaler.fit_transform(X)
    
    1. 增加层中的神经元数量,
    2. 将输出的激活函数从 sigmoid 改为 softmax
    3. 使用categorical_crossentropy作为输出的损失,
    # define baseline model 
    def baseline_model():
    
    # create model
      model = Sequential()
      model.add(Dense(8, input_dim=4, activation="relu"))
      model.add(Dense(3, activation="softmax"))
    
    # Compile model
      model.compile(loss= 'categorical_crossentropy' , optimizer= 'adam' , metrics=[ 'accuracy' ])
    
      return model 
    
    1. nb_epoch(旧Keras)更改为epochs
    estimator = KerasClassifier(build_fn=baseline_model, epochs=50, batch_size=5, verbose=1) 
    

    这样,您将获得大约 90% 的准确率。如果你运行它超过 50 个 epoch,你最终会过度拟合你的模型,你甚至可以达到 100% 的准确率,但模型不能很好地泛化。

    请记住,全连接层并不总是最好的解决方案。

    【讨论】:

    • 感谢您的回答。请问如果我们使用测试数据来评估准确性怎么办?它还会过拟合吗?替换您建议的代码,同时保持其余部分不变,我得到了 92% 的准确率
    猜你喜欢
    • 1970-01-01
    • 2016-10-22
    • 2016-10-19
    • 2018-07-07
    • 2018-07-06
    • 2018-07-14
    • 2017-07-23
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多