[英]How to predict unseen data from trained multi-label text classification model?
首先我想说我对机器学习完全陌生,并且仍在学习这些东西是如何工作的。 我正在将评论分类为多个标签,并通过参考此代码构建了一个多标签文本分类器。
model 被训练为将评论分类为 9 个标签,model 分别预测每个 label 的值。 到目前为止,我如何训练 model 以及如何测试 model 如下。 我没有包括文本处理部分,否则它将是一个冗长的代码。
这是 model 和这里使用的一样
#bert text model
class TEXT_MODEL(tf.keras.Model):
def __init__(self,
vocabulary_size,
embedding_dimensions=128,
cnn_filters=50,
dnn_units=512,
model_output_classes=2,
dropout_rate=0.1,
training=False,
name="text_model"):
super(TEXT_MODEL, self).__init__(name=name)
self.embedding = layers.Embedding(vocabulary_size,
embedding_dimensions)
self.cnn_layer1 = layers.Conv1D(filters=cnn_filters,
kernel_size=2,
padding="valid",
activation="relu")
self.cnn_layer2 = layers.Conv1D(filters=cnn_filters,
kernel_size=3,
padding="valid",
activation="relu")
self.cnn_layer3 = layers.Conv1D(filters=cnn_filters,
kernel_size=4,
padding="valid",
activation="relu")
self.pool = layers.GlobalMaxPool1D()
self.dense_1 = layers.Dense(units=dnn_units, activation="relu")
self.dropout = layers.Dropout(rate=dropout_rate)
if model_output_classes == 2:
self.last_dense = layers.Dense(units=1,
activation="sigmoid")
else:
self.last_dense = layers.Dense(units=model_output_classes,
activation="softmax")
def call(self, inputs, training):
l = self.embedding(inputs)
l_1 = self.cnn_layer1(l)
l_1 = self.pool(l_1)
l_2 = self.cnn_layer2(l)
l_2 = self.pool(l_2)
l_3 = self.cnn_layer3(l)
l_3 = self.pool(l_3)
concatenated = tf.concat([l_1, l_2, l_3], axis=-1) # (batch_size, 3 * cnn_filters)
concatenated = self.dense_1(concatenated)
concatenated = self.dropout(concatenated, training)
model_output = self.last_dense(concatenated)
return model_output
这就是我将我的标记化评论传递到 model 并对其进行训练并最终对其进行测试的方式
whole_predictions = []
whole_real_predictions = []
whole_threshold_predictions = []
one=0
#predict for each label individualy
for i in range(len(y_train[0])):
print("\n" + str(i)+"\'th label prediction started")
count_zero=0
count_one=0
new_label=[]
new_tokenized_data_train=[]
label = column(y_train,i)
count_one=sum(label)
print("count_one",count_one)
for k in range(len(label)):
if count_zero< count_one and label[k]==0:
new_label.append(0)
new_tokenized_data_train.append(X_train[k])
count_zero=count_zero+1
if label[k]==1:
new_label.append(1)
new_tokenized_data_train.append(X_train[k])
print("count_zero",count_zero)
print()
data_with_len = [[value,new_label[j],len(value)]
for j,value in enumerate(new_tokenized_data_train)]
data_with_len.sort(key=lambda x: x[2])
sorted_data_labels = [(data_lab[0], data_lab[1]) for data_lab in data_with_len]
processed_dataset = tf.data.Dataset.from_generator(lambda: sorted_data_labels, output_types=(tf.int32, tf.int32))
BATCH_SIZE = 32
batched_dataset = processed_dataset.padded_batch(BATCH_SIZE, padded_shapes=((None, ), ()))
TOTAL_BATCHES = math.ceil(len(sorted_data_labels) / BATCH_SIZE)
TEST_BATCHES = TOTAL_BATCHES // TOTAL_BATCHES
batched_dataset.shuffle(TOTAL_BATCHES)
test_data = batched_dataset.take(TEST_BATCHES)
train_data = batched_dataset.skip(TEST_BATCHES)
VOCAB_LENGTH = len(tokenizer.vocab)
EMB_DIM = 260
CNN_FILTERS = 50
DNN_UNITS = 256
OUTPUT_CLASSES = 2
DROPOUT_RATE = 0.2
NB_EPOCHS = 6
text_model = TEXT_MODEL(vocabulary_size=VOCAB_LENGTH,
embedding_dimensions=EMB_DIM,
cnn_filters=CNN_FILTERS,
dnn_units=DNN_UNITS,
model_output_classes=OUTPUT_CLASSES,
dropout_rate=DROPOUT_RATE)
if OUTPUT_CLASSES == 2:
text_model.compile(loss="binary_crossentropy",
optimizer="adam",
metrics=["acc"])
else:
text_model.compile(loss="sparse_categorical_crossentropy",
optimizer="adam",
metrics=["sparse_categorical_acc"])
text_model.fit(train_data, epochs=NB_EPOCHS)
self_label_predictions = []
self_threshold_predictions = []
self_label_real_values = []
print("Predicting " + str(i) + "th label...")
for e,item in enumerate(X_test):
if e%2==0:
progress(e,len(X_test))
res = text_model.predict([item])
self_label_real_values.append(res[0][0])
if res[0][0] > 0.93:
self_threshold_predictions.append(res[0][0])
else :
self_threshold_predictions.append(0.0)
whole_threshold_predictions.append(self_threshold_predictions)
whole_real_predictions.append(self_label_real_values)
whole_threshold_predictions = list(map(list, zip(*whole_threshold_predictions)))
whole_real_predictions = list(map(list, zip(*whole_real_predictions)))
现在我需要使用这个Text_model
来预测看不见的数据。 所以我研究了类似的案例,他们提到我需要保存和加载 model 并且在训练 model 时必须以类似的方式传递数据。 现在,我尝试了 go 与相同的 model 是 Text_model 和代码如下。
user=pd.read_csv("Noodlesam.csv")
user=user.dropna()
user['Trimmed text'] = user['Trimmed text'].astype(str).apply(text_cleaner)
input=user['Trimmed text'].tolist()
def tokenized_input(data):
return tokenizer.convert_tokens_to_ids(tokenizer.tokenize(data))
tokenized_input = [tokenized_input(data) for data in input]
print(len(tokenized_input))
new_whole_threshold_predictions=[]
new_whole_real_predictions=[]
new_self_threshold_predictions = []
new_self_label_real_values = []
for q,item1 in enumerate(tokenized_input):
if q%2==0:
progress(q,len(tokenized_input))
res = text_model.predict([item1])
new_self_label_real_values.append(res[0][0])
if res[0][0] > 0.93:
new_self_threshold_predictions.append(1.0)
else :
new_self_threshold_predictions.append(0.0)
new_whole_threshold_predictions.append(new_self_threshold_predictions)
new_whole_real_predictions.append(new_self_label_real_values)
new_whole_threshold_predictions = list(map(list, zip(*new_whole_threshold_predictions)))
new_whole_real_predictions = list(map(list, zip(*new_whole_real_predictions)))
但这给了我 output 仅用于 9 个标签中的一个 label。 在前面的代码中我很理解,训练数据已经适合 model 内部for k in range(len(label)):
loop 这意味着 9 次。 从这一点来看,我不明白这个 model 是如何工作的,我需要知道如何将这个 model 用于看不见的数据。
我认为这解释了我的问题,任何帮助将不胜感激
如果我理解正确的话。 您可以通过设置 model 的 output 和OUTPUT_CLASSES = 2
来训练 model。 在此条件下,使其对 output 层使用 sigmoid。
if model_output_classes == 2:
self.last_dense = layers.Dense(units=1,
activation="sigmoid")
else:
self.last_dense = layers.Dense(units=model_output_classes,
activation="softmax")
这意味着您将仅获得一个 label,其概率范围为 0 到 1。您可以通过将此变量编辑为您的 label 的数量来解决此问题,以将 softmax 用于 Z78E6221F6393D1356681DB398F14CEDZ 层。 Softmax 会给你一个超过标签的概率。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.