如何解决神经网络的最后一层应包含多少个神经元?
我使用以下代码将电影评论分为三类(负数为-1,中性数为0和1为正数)。但是,对于三类分类问题,最后一层中只有一个输出神经元是真的吗?
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,test_labels))
ValueError: logits and labels must have the same shape ((None,2) vs (None,1))
解决方法
如果要在3个类别之间进行分类,则应该有3个神经元。
此外,假设所有观测值仅在一个类中,则应在最后一层使用'softmax'
激活。
接下来,您应该使用'sparse_categorical_crossentropy'
,因为您输入的内容不是一次性编码的。目标[0,1],[0,1,0],[1,0]
是可选的,您也可以拥有[1,2,0]
。
最后,您的目标应该是[0,2]
而不是[-1,1]
,因此建议您在标签上加1。
test_labels = df_test['Sentiment'].values + 1
如果标签是[-1,1]
而不是[0,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,2]
,它将起作用:
<tf.Tensor: shape=(),dtype=float32,numpy=1.1918503>
,
简短答案:
一个热编码您的火车标签,并使用分类交叉熵作为损失函数。
原因:
- 您的logit形状为(n,2),但标签形状为(n,1)。
- 如果您使用交叉熵(除非是稀疏的),则您的logit和标签的形状应为(n,3)。
解决方案:
- 一个热编码火车标签,您会得到火车标签形状(n,3)
- 将分类交叉熵与具有3个输出的最终密集神经元一起使用,则将得到logits形状(n,3)
您的模型将在此之后开始学习。
,您有3个课程-> num_classes = 3 您的最后一层应如下所示:
tf.keras.layers.Dense(num_classes,activation = 'sigmoid'),
您将收到一个具有3个概率的np.array作为输出。此外,由于您没有解决二进制问题,因此应将类更改为categorical_crossentropy。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。