簡體   English   中英

神經網絡的最后一層應該有多少個神經元?

[英]How many neurons should be in the last layer of the neural network?

我使用以下代碼將電影評論分為三類(負面為 -1,中性為 0,1 為正面)。 但是對於三類分類問題,最后一層真的只有一個 output 神經元嗎?

import tensorflow as tf
import numpy as np
import pandas as pd
import numpy as K

csvfilename_train = 'train(cleaned).csv'
csvfilename_test = 'test(cleaned).csv'

# Read .csv files as pandas dataframes
df_train = pd.read_csv(csvfilename_train)
df_test = pd.read_csv(csvfilename_test)

train_sentences  = df_train['Comment'].values
test_sentences  = df_test['Comment'].values

# Extract labels from dataframes
train_labels = df_train['Sentiment'].values
test_labels = df_test['Sentiment'].values

vocab_size = 10000
embedding_dim = 16
max_length = 30
trunc_type = 'post'
oov_tok = '<OOV>'

from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

tokenizer = Tokenizer(num_words = vocab_size, oov_token = oov_tok)
tokenizer.fit_on_texts(train_sentences)
word_index = tokenizer.word_index
sequences = tokenizer.texts_to_sequences(train_sentences)
padded = pad_sequences(sequences, maxlen = max_length, truncating = trunc_type)

test_sequences = tokenizer.texts_to_sequences(test_sentences)
test_padded = pad_sequences(test_sequences, maxlen = max_length)

model = tf.keras.Sequential([
    tf.keras.layers.Embedding(vocab_size, embedding_dim, input_length = max_length),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(6, activation = 'relu'),
    tf.keras.layers.Dense(1, activation = 'sigmoid'),
])
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics = ['accuracy'])

num_epochs = 10
model.fit(padded, train_labels, epochs = num_epochs, validation_data = (test_padded, test_labels))

當我將tf.keras.layers.Dense(1, activation = 'sigmoid')更改為tf.keras.layers.Dense(2, activation = 'sigmoid')時,它給了我以下錯誤

---> 10 model.fit(padded, train_labels, epochs = num_epochs, validation_data = (test_padded,test_labels))
     ValueError: logits and labels must have the same shape ((None, 2) vs (None, 1))

如果您在 3 個類別之間進行分類,您應該有 3 個神經元。

此外,您應該為最后一層使用'softmax'激活,假設所有觀察都在一個 class 中。

接下來,您應該使用'sparse_categorical_crossentropy'因為您的輸入不是一次性編碼的。 [0,0,1], [0,1,0], [1,0,0]等目標是可選的,您也可以有[1, 2, 0, 1, 2, 1, 0]

最后,您的目標應該是[0, 1, 2]而不是[-1, 0, 1]所以我建議您在標簽中添加 1。

test_labels = df_test['Sentiment'].values + 1

如果標簽是[-1, 0, 1]而不是[0, 1, 2]會發生這種情況:

import tensorflow as tf

sparse_entropy = tf.losses.SparseCategoricalCrossentropy()

a = tf.convert_to_tensor([[-1., 0., 1.]]) #+ 1
b = tf.convert_to_tensor([[.4, .2, .4], [.1, .7, .2], [.8, .1, .1]])

sparse_entropy(a, b)
nan

如果您取消注釋+1 ,它將標簽轉換為[0, 1, 2] ,它可以工作:

<tf.Tensor: shape=(), dtype=float32, numpy=1.1918503>

簡短的回答:

一個熱編碼您的火車標簽並使用分類交叉熵作為損失 function。

原因:

  1. 您的 logits 具有形狀 (n,2),但標簽具有 (n,1)。
  2. 如果您使用交叉熵(除非它是稀疏的),您的 logits 和標簽應該是形狀 (n,3)。

解決方案:

  1. 對火車標簽進行一次熱編碼,您將獲得火車標簽形狀 (n,3)
  2. 使用具有 3 個輸出的最終密集神經元的分類交叉熵,然后您將獲得 logits shape(n,3)

您的 model 將在此之后開始學習。

你有 3 個類 -> num_classes=3 你的最后一層應該是這樣的:

tf.keras.layers.Dense(num_classes, activation = 'sigmoid'),

您將收到一個具有 3 個概率的 np.array,即 output。 此外,您應該將 class 更改為 categorical_crossentropy,因為您沒有解決二進制問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM