APP下载

一文带你深入了解机器视角下的文字阅读

消息来源:baojiabao.com 作者: 发布时间:2024-05-19

报价宝综合消息一文带你深入了解机器视角下的文字阅读

全文共3608字,预计学习时长10分钟或更长

图片来源:Paweł Durczok/ Unsplash

为了视觉化机器阅读文字的方式,本文将构建一个热图来识别文字模型“读取”的位置,并以此确定文字中提到的咖啡是浅焙还是深焙。

多年来,我们在计算机视觉任务中不断发展着卷积神经网络(CNN),这给以下领域都带来了极大的提升:

· 增加了模型的鲁棒性

· 视觉化并减小模型偏差

· 更好地理解对抗性影象如何改变深度学习模型的输出

既然更好的模型理解已经带来了这么明显的好处,为什么还没有在自然语言处理(NLP)领域对模型的可解释性给予相同的重视呢?

上述图片是神经网络认为的哑铃的样子。注意,在本例中,模型并没有把人的胳膊和哑铃分开,因此该模型没有完全参透哑铃的大致形态。(图片由Google人工智能部落格提供)

视觉化CNN聚焦位置

本文将把用于理解基于视觉的CNN聚焦位置的技术同样运用到文字的识别中,然后建立一个热量图,显示CNN在输入文字特定区域的聚焦位置,以便进行分类。

在这个GPT-2, BERT, ELMo等模型高度发展的时代,CNN已经有点跟不上潮流了。但是CNN在现实应用中仍然有很好的表现,且不像一些先进模型一样具有体积大、推断时间长、内存占用大的缺点。

预测咖啡的焙制方式:

为了给大家演示这个例子,首先建立一个普通分类器,通过其描述来推测咖啡究竟是浅焙还是深焙。

资料集里包含了许多对咖啡的评价。我们将尝试用下面这张表中对咖啡的盲品记录来推测样本咖啡究竟是浅焙还是深焙。

下面是在Keras中构建CNN并对资料进行训练的程式码:

X = df.blind_assesment.values

y = df.y.values

tokenizer = Tokenizer(num_words=4000)

tokenizer.fit_on_texts(X)

X = tokenizer.texts_to_sequences(X)

vocab_size = len(tokenizer.word_index) + 1 # Adding 1 because of reserved 0 index

maxlen = 200

embedding_dim = 50

X = pad_sequences(X, padding='post', maxlen=maxlen)

sequence_input = layers.Input(shape=(maxlen,), dtype='int32')embedded_sequences = layers.Embedding(vocab_size, embedding_dim, input_length=maxlen)(sequence_input)

l_cov1 = layers.Conv1D(317, 3, activation='relu')(embedded_sequences)

l_pool1 = layers.MaxPooling1D(2)(l_cov1)

l_cov2 = layers.Conv1D(317, 1, activation='relu')(l_pool1)

l_cov3 = layers.Conv1D(317, 2, activation='relu')(l_cov2)

l_pool3 = layers.GlobalMaxPooling1D()(l_cov3) # global max pooling

l_bnorm = layers.BatchNormalization()(l_pool3)

l_dense = layers.Dense(128, activation='relu')(l_pool3)

preds = layers.Dense(1, activation='sigmoid',name='preds')(l_dense)

model = Model(sequence_input, outputs=preds)

model.compile(optimizer='adam',

loss='binary_crossentropy',

metrics=['accuracy'])

model.summary()

model.fit(X, y, epochs=3, validation_split=0.1, batch_size=10)

如果在Keras中的模型和这个看起来有点不一样,那是因为Keras用的是函式式应用程序程式设计界面(https://keras.io/getting-started/functional-api-guide/)。这个程式码训练并适应模型,在验证资料上训练的精度在75%-80%左右。关于CNN文字分类器构建的文章还有很多,在此不对其进行深入阐述。本文将重点关注如何解释该分类器所做的预测。

建立启用图:

使用Keras既快捷又简单,只需要几行程式码。

1. 得到模型预测和CNN最终输出层。

可以在Keras里使用model.summary()函式来获得模型结构的细分。图表中conv1d_45是模型中CNN最终层的名称。

下面的程式码不仅可以得出预测的类别,还能得出CNN的最终层:

class_idx = np.argmax(y_pred[0]) #not needed in this case as only two classes

class_output = model.output[:, class_idx]

last_conv_layer = model.get_layer("conv1d_45")

2.根据特征图计算出输出类别,并将所有梯度汇集在一起。

这个虽然听起来复杂,但其实使用Keras后端函式只需要几行程式码:

grads = K.gradients(class_output, last_conv_layer.output)[0]

pooled_grads = K.mean(grads)

iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]])

pooled_grads_value, conv_layer_output_value = iterate([Xtst])

3. 对特征对映求取平均值,并将其归一化(正则化)到0与1之间。

heatmap = np.mean(conv_layer_output_value, axis=-1)

heatmap = np.maximum(heatmap,0)

heatmap /= np.max(heatmap)#normalise values in the prediction

现在根据CNN最终层输出形状的维度得到的预测类别,得到一个启用热图。接下来就只需要根据初始输入的资讯长度(单词数)重新调整(拉伸)其大小,以了解究竟是哪些单词触发了神经网络。

用超文字标记语言(HTML)视觉化输出结果

在最终预测中加入一些基础的超文字标记语言能够建立一个非常有效的使用者界面,同时增加了理解模型如何做出预测的能力。

norm_len = maxlen/last_conv_layer.output_shape[1] # find the ratio of the text vs the conv layer length

html = ""

if y_pred[0]>0.5:

pred = 'light'

else:

pred = 'dark'

html += "Based on the description, the model believes that this is a {} coffee roast. ".format(pred)

html += "

Confidence: {:.0f}%

".format(abs(((y_pred[0][0]*100)-50)*2))

for j,i in enumerate(tokenizer.sequences_to_texts(Xtst)[0].split()):

html += "{} ".format(heatmap[math.floor(j/norm_len)]*255,heatmap[math.floor(j/norm_len)]-0.3,i)

HTML(html)

此超文字标记语言程式码段在Google Colab上给出了以下输出结果:

从这里可以看到这个模型已经“读懂”了这段文字,并识别出文字中描述的咖啡有着“野草莓”的味道,且带有一点“甜味”和“新鲜的酸味”,因此模型肯定的(正确的)将其判定为浅焙咖啡。

总之,本文阐述了如何轻松地突出显示模型通过“阅读”作出预测(分类)的区域。这对以下方面都有重要意义:

1. 对模型进行基本除错和合理性检测。

2.更好地理解为什么模型会对训练样本进行错误分类。

3.检测可能存在的模型偏差。

程式码传送门:

https://colab.research.google.com/drive/1taIt9A9tsENJTYh3eK0ZuUyRIdrHeNty

留言 点赞 关注

我们一起分享AI学习与发展的干货

欢迎关注全平台AI垂类自媒体 “读芯术”

2019-10-02 17:55:00

相关文章