Boo*_*oom 5 machine-learning neural-network scikit-learn keras tensorflow
我正在学习深度学习,keras并试图将结果(准确性)与机器学习算法 ( sklearn) (即random forest,k_neighbors)进行比较
看来keras我得到了最糟糕的结果。我正在处理简单的分类问题:iris dataset
我的 keras 代码如下:
samples = datasets.load_iris()
X = samples.data
y = samples.target
df = pd.DataFrame(data=X)
df.columns = samples.feature_names
df['Target'] = y
# prepare data
X = df[df.columns[:-1]]
y = df[df.columns[-1]]
# hot encoding
encoder = LabelEncoder()
y1 = encoder.fit_transform(y)
y = pd.get_dummies(y1).values
# split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3)
# build model
model = Sequential()
model.add(Dense(1000, activation='tanh', input_shape = ((df.shape[1]-1),)))
model.add(Dense(500, activation='tanh'))
model.add(Dense(250, activation='tanh'))
model.add(Dense(125, activation='tanh'))
model.add(Dense(64, activation='tanh'))
model.add(Dense(32, activation='tanh'))
model.add(Dense(9, activation='tanh'))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train)
score, acc = model.evaluate(X_test, y_test, verbose=0)
#results:
#score = 0.77
#acc = 0.711
Run Code Online (Sandbox Code Playgroud)
我已经厌倦了添加层和/或更改每层的单元数和/或更改激活函数(to relu),结果似乎不高于 0.85。
使用 sklearnrandom forest或k_neighbors我得到的结果(在同一数据集上)高于 0.95。
我错过了什么?
随着sklearn我做一点努力,取得了良好的效果,并与keras我有很多升级,但不如sklearn结果。这是为什么 ?
我怎样才能得到相同的结果keras?
des*_*aut 11
简而言之,您需要:
详细:
这里的第一个问题是,现在我们从不使用activation='tanh'中间网络层。在此类问题中,我们实际上总是使用activation='relu'.
第二个问题是你已经建立了一个相当大的 Keras 模型,很可能你的训练集中只有 100 个虹膜样本,你的数据太少,无法有效地训练如此大的模型。尝试大幅减少层数和每层节点数。开始更简单。
当我们拥有大量数据时,大型神经网络确实会蓬勃发展,但在像这里这样的小型数据集的情况下,与更简单的算法(如 RF 或 k-nn)相比,它们的表现力和灵活性可能会成为不利因素。
第三个问题是,与基于树的模型(如随机森林)相比,神经网络通常需要对数据进行归一化,而您不需要这样做。事实是 knn 也需要归一化数据,但在这种特殊情况下,由于所有虹膜特征都在同一尺度上,因此不会对性能产生负面影响。
最后但并非最不重要的一点是,您似乎只在一个时期内运行 Keras 模型(如果您未在 中指定任何内容,则为默认值model.fit);这在某种程度上相当于用一棵树构建一个随机森林(顺便说一句,它仍然比单个决策树好得多)。
总而言之,在您的代码中进行以下更改:
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
model = Sequential()
model.add(Dense(150, activation='relu', input_shape = ((df.shape[1]-1),)))
model.add(Dense(150, activation='relu'))
model.add(Dense(y.shape[1], activation='softmax'))
model.fit(X_train, y_train, epochs=100)
Run Code Online (Sandbox Code Playgroud)
和其他一切一样,我们得到:
score, acc = model.evaluate(X_test, y_test, verbose=0)
acc
# 0.9333333373069763
Run Code Online (Sandbox Code Playgroud)
我们可以做得更好:使用稍微多一些的训练数据并将它们分层,即
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size = 0.20, # a few more samples for training
stratify=y)
Run Code Online (Sandbox Code Playgroud)
使用相同的模型和训练时期,您可以在测试集中获得1.0的完美准确率:
score, acc = model.evaluate(X_test, y_test, verbose=0)
acc
# 1.0
Run Code Online (Sandbox Code Playgroud)
(由于此类实验中默认强加的一些随机性,细节可能会有所不同)。
| 归档时间: |
|
| 查看次数: |
2460 次 |
| 最近记录: |