神经网络和二元分类指南

Enl*_*nky 3 python machine-learning neural-network keras

我有以下数据 (X) 存储在 numpy 数组中:

array([[ 0.82737724, -0.5924806 ,  0.43279337, ...,  0.91896631,
        -0.28188124,  0.58595414],
       [-1.56610693,  0.63878901,  0.43279337, ...,  1.28262456,
         1.16154512, -1.9423032 ],
       [ 0.82737724, -0.2846632 , -0.4745452 , ...,  1.64628282,
        -0.28188124,  0.58595414],
       ...,
       [ 0.82737724,  0.        ,  0.43279337, ...,  1.67617254,
        -0.28188124,  0.58595414],
       [-1.56610693, -0.2846632 , -0.4745452 , ..., -1.64656796,
         0.27001707, -1.9423032 ],
       [ 0.82737724,  0.17706291, -0.4745452 , ...,  0.63501397,
        -0.28188124, -0.67817453]])
Run Code Online (Sandbox Code Playgroud)

该数组要大得多,并且它被输入到这个神经网络中:

def base_model1():
    input_dim = X.shape[1]
    output_dim = 1
    model = Sequential()
    model.add(Dense(10, input_dim= input_dim,kernel_initializer ='normal', activation= 'tanh'))
    model.add(Dense(1, input_dim = 100, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['MeanSquaredError',
        'AUC',])
    
    return model
NN_clf = KerasClassifier(build_fn=base_model1, epochs=100, verbose=1)
NN_clf._estimator_type = "classifier"
trained = NN_clf.fit(X,y.values.reshape(-1,1))
Run Code Online (Sandbox Code Playgroud)

Y 是二进制 1 和 0。其中1表示会乘坐出租车,0表示不会乘坐出租车。

predictions1 = trained.model.predict(X_test, verbose=1)
predictions1[:5]
array([[0.09048176],
       [0.34411064],
       [0.08842686],
       [0.0986585 ],
       [0.58971184]], dtype=float32)
Run Code Online (Sandbox Code Playgroud)

我的问题源于这里,如果 Sigmoid 是执行二元分类或这些概率输出的激活层?因为我期待 1 和 0,所以我最终假设这些是概率输出,我创建了以下内容:

blank = []
for i in pd.DataFrame(predictions1)[0].to_list():
    if i > .50:
        blank.append(1)
    else:
        blank.append(0)
Run Code Online (Sandbox Code Playgroud)

我的大部分困惑在于二元分类神经网络如何处理它们,以及如何获得 1 和 0。

M.I*_*nat 7

当您将一些input用于预测的信息传递给二元分类器(sigmoid最后一层中的激活)时,它将为您提供矩阵,其中每一行代表这些输入的概率class 1。在你的情况下:

predictions1 = trained.model.predict(X_test, verbose=1)
predictions1[:5]
array([[0.09048176],
       [0.34411064],
       [0.08842686],
       [0.0986585 ],
       [0.58971184]],
Run Code Online (Sandbox Code Playgroud)

X_test[:5]这里,每个分数代表每个样本成为 的可能性class 1。从这一点来看,为了获得类标签(例如10),默认情况下 API 使用0.5阈值来考虑每个分数属于class 1class 0;更具体地说,分数大于0.5被认为的class 1。但当然,我们可以调整阈值。这是一个虚拟示例

import tensorflow as tf
import numpy as np  

img = tf.random.normal([20, 32], 0, 1, tf.float32)
tar = np.random.randint(2, size=(20, 1))

model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(10, input_dim = 32, 
                       kernel_initializer ='normal', activation= 'relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
Run Code Online (Sandbox Code Playgroud)
model.compile(loss='binary_crossentropy', 
              optimizer='adam', metrics=['accuracy'])
model.fit(img, tar, epochs=5, verbose=2)

Epoch 1/5
1/1 - 0s - loss: 0.7058 - accuracy: 0.5500
Epoch 2/5
1/1 - 0s - loss: 0.6961 - accuracy: 0.5500
Epoch 3/5
1/1 - 0s - loss: 0.6869 - accuracy: 0.5500
Epoch 4/5
1/1 - 0s - loss: 0.6779 - accuracy: 0.6000
Epoch 5/5
1/1 - 0s - loss: 0.6692 - accuracy: 0.6000
Run Code Online (Sandbox Code Playgroud)

概率

y_pred = model.predict(img)
print(y_pred.shape)
y_pred[:10]

(20, 1)
array([[0.5317636 ],
       [0.4592613 ],
       [0.5876541 ],
       [0.47071406],
       [0.56284094],
       [0.5025074 ],
       [0.46471453],
       [0.38649547],
       [0.43361676],
       [0.4667967 ]], dtype=float32)
Run Code Online (Sandbox Code Playgroud)

类别标签

(model.predict(img) > 0.5).astype("int32")
array([[1],
       [0],
       [1],
       [0],
       [1],
       [1],
       [0],
       [0],
       [0],
       [0],
       [0],
....
....
Run Code Online (Sandbox Code Playgroud)