初学者神经网络

时间:2018-12-02 14:52:51

标签: python tensorflow keras neural-network deep-learning

我愿意使用Keras在python中创建一个神经网络,它可以告诉数字是偶数还是奇数。我知道这可以通过多种方式完成,而使用NN来解决这个问题实在是太过分了,但我出于教育目的却想这么做。

我遇到了一个问题:我的模型的准确度约为50%,这意味着它无法判断数字是偶数还是奇数。

我将向您详细说明我所经历的步骤,希望我们可以一起找到解决方案:)

第一步创建数据和标签: 基本上我的数据是从0到99(二进制)的数字,标签是0(奇数)和1(偶数)

# creating a model

model = Sequential()
model.add(Dense(1, input_dim=8, kernel_initializer='uniform', activation='relu'))
model.add(Dense(2, kernel_initializer='uniform', activation='relu'))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))

然后,我将创建模型thas由3层组成。 -第1层(输入):一个神经元,采用任何大小为8的numpy数组(8位整数表示) -第2层(隐藏):两个神经元 -第3层(输出):一个神经元

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

然后我正在使用binary_cross_entropy作为损失函数来训练模型,因为我想要对整数进行二进制分类:

#training
model.fit(data, labels, epochs=10, batch_size=2)

#evaluate the model
scores = model.evaluate(data, labels)
print("\n%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))

然后我要训练模型并对其进行评估:

{{1}}

那是我因为50%的准确性而迷失的地方。

我认为我错过了有关NN或Keras实施的知识,所以将不胜感激。

感谢您阅读

edit:我根据Stefan Falk的评论修改了我的代码

2 个答案:

答案 0 :(得分:1)

以下内容使我对测试集的准确性为100%:

import numpy as np
from tensorflow.contrib.learn.python.learn.estimators._sklearn import train_test_split
from tensorflow.python.keras import Sequential
from tensorflow.python.keras.layers import Dense

# Number of samples (digits from 0 to N-1)
N = 10000
# Input size depends on the number of digits
input_size = int(np.log2(N)) + 1

# Generate data
y = list()
X = list()

for i in range(N):
    binary_string = np.binary_repr(i, input_size)
    array = np.zeros(input_size)
    for j, binary in enumerate(binary_string):
        array[j] = int(binary)
    X.append(array)
    y.append(int(i % 2 == 0))

X = np.asarray(X)
y = np.asarray(y)

# Make train/test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1)

# Create the model
model = Sequential()
model.add(Dense(2, kernel_initializer='uniform', activation='relu'))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))

model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])

# Train
model.fit(X_train, y_train, epochs=3, batch_size=10)

# Evaluate    
print("Evaluating model:")
scores = model.evaluate(X_test, y_test)
print("\n%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))

为什么效果这么好?

您的问题非常简单。网络只需要知道第一位是否设置为(1)(0)。为此,您实际上不需要隐藏层或任何非诽谤性。该问题可以通过简单的线性回归来解决。

model = Sequential()
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))

也可以做。此外,关于feature engineering的主题,

X = [v % 2 for v in range(N)]

也足够。您会发现在这种情况下,Xy的内容相同。


也许尝试non-linear example such as XOR。请注意,这里没有测试集,因为没有可以概括的内容,也没有任何“看不见的”数据可能会使网络感到惊讶。

import numpy as np
from tensorflow.python.keras import Sequential
from tensorflow.python.keras.layers import Dense

X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])

model = Sequential()
model.add(Dense(5, input_dim=2, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

model.fit(X, y, batch_size=1, nb_epoch=1000)

print(model.predict_proba(X))

print(model.predict_proba(X) > 0.5)

看看this link,然后看一下示例。

答案 1 :(得分:-2)

尝试通过以下几点改进网络:

  1. 使用'glorot_uniform'作为内核初始化程序
  2. 在整个网络中使用S型信号,而不是relu。
  3. 除了输入层之外,在所有层上都使用Sigmoid。
  4. 尝试将Adam优化器的学习率降低到0.001。
  5. 使用均方误差或'mse'损失函数。