Keras—embedding嵌入层的使用

2023-10-27

最近在工作中进行了NLP的内容,使用的还是Keras中embedding的词嵌入来做的。

Keras中embedding层做一下介绍。

中文文档地址:https://keras.io/zh/layers/embeddings/

参数如下:

 其中参数重点有input_dim,output_dim,非必选参数input_length.

初始化方法参数设置后面会单独总结一下。

demo使用预训练(使用百度百科(word2vec)的语料库)参考

embedding使用的demo参考:

def create_embedding(word_index, num_words, word2vec_model):
    embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))
    for word, i in word_index.items():
        try:
            embedding_vector = word2vec_model[word]
            embedding_matrix[i] = embedding_vector
        except:
            continue
    return embedding_matrix

#word_index:词典(统计词转换为索引)
#num_word:词典长度+1
#word2vec_model:词向量的model

加载词向量model的方法:

def pre_load_embedding_model(model_file):
    # model = gensim.models.Word2Vec.load(model_file)
    # model = gensim.models.Word2Vec.load(model_file,binary=True)
    model = gensim.models.KeyedVectors.load_word2vec_format(model_file)
    return model

model中Embedding层的设置(注意参数,Input层的输入,初始化方法):

 embedding_matrix = create_embedding(word_index, num_words, word2vec_model)

 embedding_layer = Embedding(num_words,
                                EMBEDDING_DIM,
                                embeddings_initializer=Constant(embedding_matrix),
                                input_length=MAX_SEQUENCE_LENGTH,
                                trainable=False)
 sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32')
 embedded_sequences = embedding_layer(sequence_input)

embedding层的初始化设置

keras embeding设置初始值的两种方式

随机初始化Embedding

from keras.models import Sequential
from keras.layers import Embedding
import numpy as np

model = Sequential()
model.add(Embedding(1000, 64, input_length=10))
# the model will take as input an integer matrix of size (batch, input_length).
# the largest integer (i.e. word index) in the input should be no larger than 999 (vocabulary size).
# now model.output_shape == (None, 10, 64), where None is the batch dimension.

input_array = np.random.randint(1000, size=(32, 10))

model.compile('rmsprop', 'mse')
output_array = model.predict(input_array)
print(output_array)
assert output_array.shape == (32, 10, 64)

使用weights参数指明embedding初始值

import numpy as np

import keras

m = keras.models.Sequential()
"""
可以通过weights参数指定初始的weights参数

因为Embedding层是不可导的 
梯度东流至此回,所以把embedding放在中间层是没有意义的,emebedding只能作为第一层

注意weights到embeddings的绑定过程很复杂,weights是一个列表
"""
embedding = keras.layers.Embedding(input_dim=3, output_dim=2, input_length=1, weights=[np.arange(3 * 2).reshape((3, 2))], mask_zero=True)
m.add(embedding)  # 一旦add,就会自动调用embedding的build函数,
print(keras.backend.get_value(embedding.embeddings))
m.compile(keras.optimizers.RMSprop(), keras.losses.mse)
print(m.predict([1, 2, 2, 1, 2, 0]))
print(m.get_layer(index=0).get_weights())
print(keras.backend.get_value(embedding.embeddings))

给embedding设置初始值的第二种方式:使用initializer

import numpy as np

import keras

m = keras.models.Sequential()
"""
可以通过weights参数指定初始的weights参数

因为Embedding层是不可导的 
梯度东流至此回,所以把embedding放在中间层是没有意义的,emebedding只能作为第一层


给embedding设置权值的第二种方式,使用constant_initializer 
"""
embedding = keras.layers.Embedding(input_dim=3, output_dim=2, input_length=1, embeddings_initializer=keras.initializers.constant(np.arange(3 * 2, dtype=np.float32).reshape((3, 2))))
m.add(embedding)
print(keras.backend.get_value(embedding.embeddings))
m.compile(keras.optimizers.RMSprop(), keras.losses.mse)
print(m.predict([1, 2, 2, 1, 2]))
print(m.get_layer(index=0).get_weights())
print(keras.backend.get_value(embedding.embeddings))

关键的难点在于理清weights是怎么传入到embedding.embeddings张量里面去的。

Embedding是一个层,继承自Layer,Layer有weights参数,weights参数是一个list,里面的元素都是numpy数组。在调用Layer的构造函数的时候,weights参数就被存储到了_initial_weights变量
basic_layer.py 之Layer类

        if 'weights' in kwargs:
            self._initial_weights = kwargs['weights']
        else:
            self._initial_weights = None

当把Embedding层添加到模型中、跟模型的上一层进行拼接的时候,会调用layer(上一层)函数,此处layer是Embedding实例,Embedding是一个继承了Layer的类,Embedding类没有重写__call__()方法,Layer实现了__call__()方法。父类Layer的__call__方法调用子类的call()方法来获取结果。所以最终调用的是Layer.__call__()。在这个方法中,会自动检测该层是否build过(根据self.built布尔变量)。

Layer.__call__函数非常重要。

    def __call__(self, inputs, **kwargs):
        """Wrapper around self.call(), for handling internal references.

        If a Keras tensor is passed:
            - We call self._add_inbound_node().
            - If necessary, we `build` the layer to match
                the _keras_shape of the input(s).
            - We update the _keras_shape of every input tensor with
                its new shape (obtained via self.compute_output_shape).
                This is done as part of _add_inbound_node().
            - We update the _keras_history of the output tensor(s)
                with the current layer.
                This is done as part of _add_inbound_node().

        # Arguments
            inputs: Can be a tensor or list/tuple of tensors.
            **kwargs: Additional keyword arguments to be passed to `call()`.

        # Returns
            Output of the layer's `call` method.

        # Raises
            ValueError: in case the layer is missing shape information
                for its `build` call.
        """
        if isinstance(inputs, list):
            inputs = inputs[:]
        with K.name_scope(self.name):
            # Handle laying building (weight creating, input spec locking).
            if not self.built:#如果未曾build,那就要先执行build再调用call函数
                # Raise exceptions in case the input is not compatible
                # with the input_spec specified in the layer constructor.
                self.assert_input_compatibility(inputs)

                # Collect input shapes to build layer.
                input_shapes = []
                for x_elem in to_list(inputs):
                    if hasattr(x_elem, '_keras_shape'):
                        input_shapes.append(x_elem._keras_shape)
                    elif hasattr(K, 'int_shape'):
                        input_shapes.append(K.int_shape(x_elem))
                    else:
                        raise ValueError('You tried to call layer "' +
                                         self.name +
                                         '". This layer has no information'
                                         ' about its expected input shape, '
                                         'and thus cannot be built. '
                                         'You can build it manually via: '
                                         '`layer.build(batch_input_shape)`')
                self.build(unpack_singleton(input_shapes))
                self.built = True#这句话其实有些多余,因为self.build函数已经把built置为True了

                # Load weights that were specified at layer instantiation.
                if self._initial_weights is not None:#如果传入了weights,把weights参数赋值到每个变量,此处会覆盖上面的self.build函数中的赋值。
                    self.set_weights(self._initial_weights)

            # Raise exceptions in case the input is not compatible
            # with the input_spec set at build time.
            self.assert_input_compatibility(inputs)

            # Handle mask propagation.
            previous_mask = _collect_previous_mask(inputs)
            user_kwargs = copy.copy(kwargs)
            if not is_all_none(previous_mask):
                # The previous layer generated a mask.
                if has_arg(self.call, 'mask'):
                    if 'mask' not in kwargs:
                        # If mask is explicitly passed to __call__,
                        # we should override the default mask.
                        kwargs['mask'] = previous_mask
            # Handle automatic shape inference (only useful for Theano).
            input_shape = _collect_input_shape(inputs)

            # Actually call the layer,
            # collecting output(s), mask(s), and shape(s).
            output = self.call(inputs, **kwargs)
            output_mask = self.compute_mask(inputs, previous_mask)

            # If the layer returns tensors from its inputs, unmodified,
            # we copy them to avoid loss of tensor metadata.
            output_ls = to_list(output)
            inputs_ls = to_list(inputs)
            output_ls_copy = []
            for x in output_ls:
                if x in inputs_ls:
                    x = K.identity(x)
                output_ls_copy.append(x)
            output = unpack_singleton(output_ls_copy)

            # Inferring the output shape is only relevant for Theano.
            if all([s is not None
                    for s in to_list(input_shape)]):
                output_shape = self.compute_output_shape(input_shape)
            else:
                if isinstance(input_shape, list):
                    output_shape = [None for _ in input_shape]
                else:
                    output_shape = None

            if (not isinstance(output_mask, (list, tuple)) and
                    len(output_ls) > 1):
                # Augment the mask to match the length of the output.
                output_mask = [output_mask] * len(output_ls)

            # Add an inbound node to the layer, so that it keeps track
            # of the call and of all new variables created during the call.
            # This also updates the layer history of the output tensor(s).
            # If the input tensor(s) had not previous Keras history,
            # this does nothing.
            self._add_inbound_node(input_tensors=inputs,
                                   output_tensors=output,
                                   input_masks=previous_mask,
                                   output_masks=output_mask,
                                   input_shapes=input_shape,
                                   output_shapes=output_shape,
                                   arguments=user_kwargs)

            # Apply activity regularizer if any:
            if (hasattr(self, 'activity_regularizer') and
                    self.activity_regularizer is not None):
                with K.name_scope('activity_regularizer'):
                    regularization_losses = [
                        self.activity_regularizer(x)
                        for x in to_list(output)]
                self.add_loss(regularization_losses,
                              inputs=to_list(inputs))
        return output

如果没有build过,会自动调用Embedding类的build()函数。Embedding.build()这个函数并不会去管weights,如果它使用的initializer没有传入,self.embeddings_initializer会变成随机初始化。如果传入了,那么在这一步就能够把weights初始化好。如果同时传入embeddings_initializer和weights参数,那么weights参数稍后会把Embedding#embeddings覆盖掉。

embedding.py Embedding类的build函数


    def build(self, input_shape):
        self.embeddings = self.add_weight(
            shape=(self.input_dim, self.output_dim),
            initializer=self.embeddings_initializer,
            name='embeddings',
            regularizer=self.embeddings_regularizer,
            constraint=self.embeddings_constraint,
            dtype=self.dtype)
        self.built = True

综上,在keras中,使用weights给Layer的变量赋值是一个比较通用的方法,但是不够直观。keras鼓励多多使用明确的initializer,而尽量不要触碰weights。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Keras—embedding嵌入层的使用 的相关文章

随机推荐

  • go语言配置

    1 Go语言的环境变量 与Java等编程语言一样 安装Go语言开发环境需要设置全局的操作系统环境变量 除非是用包管理工具直接安装 主要的系统级别的环境变量有两个 1 GOROOT 表示Go语言环境在计算机上的安装位置 它的值可以是任意的位置
  • memcached 高可用工具 memcached-ha

    MemcachedHA 包装一种memcached client 使系统达到对memcached的高可用控制 日本人开发的 项目地址 http sourceforge jp projects memcached ha 1 数据多点备份 主从
  • k8s--基础--22.9--storageclass--类型--Quobyte

    k8s 基础 22 9 storageclass 类型 Quobyte 1 介绍 1 1 案例 apiVersion storage k8s io v1 kind StorageClass metadata name slow provis
  • 云原生之使用Docker部署caddy网站服务器

    云原生之使用Docker部署caddy网站服务器 一 Caddy介绍 1 Caddy简介 2 Caddy特点 二 检查本地环境 1 检查操作系统版本 2 检查docker状态 三 下载caddy镜像 四 部署caddy应用 1 创建数据目录
  • kuka程序备份_KUKA机器人更改机器人名称及备份还原数据

    大家好 继之前发过的图文消息 连续好多期都是用视频讲解了 毕竟我觉得实际演示和语言沟通才是信息交流最通畅的方式 然而后台的播放数据并不好 半个小时的视频平均播放时长才十分钟 可能是视频太长了 我不是败给我自己 我是败给了这个时代 因为D音
  • 网络基础入门

    文章目录 一 网络的背景 独立模式 计算机之间相互独立 网络互联 多台计算机连接在一起 完成数据共享 局域网LAN和广域网WAN 二 网络在哪里 三 认识协议 四 OSI七层模型 五 TCP IP 四层模型 六 网络传输基本流程 七 数据包
  • mysqldump对mysql数据库的影响

    对于想入门或者初级 中级mysql数据库运维人员 了解mysqldump对mysql数据库的影响 是非常必要的 当执行mysqldump命令之后 mysql后台执行了什么 下面就带大家看看 在这里使用general log进行分析 1 首先
  • sql计算留存率

    文章目录 什么是留存率 案例1 案例2 案例3 案例4 参考 什么是留存率 留存用户是指用户在APP产生行为后 在固定的第N日继续访问或使用APP的用户 留存率是指用户在一段时间后或固定的间隔后产生留存用户的比例 用户留存率有很多种 新客留
  • 查看Linux服务器内存情况

    查看Linux服务器内存情况 一 free命令 二 top命令 总结 一 free命令 free命令用于显示内存的使用情况 包括实体内存 虚拟的交换文件内存 共享内存区段 以及系统核心使用的缓冲区等 语法 free bkmotV s lt
  • Redis 三台服务器搭建三主三从详细步骤

    1 需要三台服务器 如 服务器A B C 2 在三台服务器上安装gcc 执行如下命令 yum install gcc 3 验证是否安装好gcc gcc v 如果出现如下信息 代表已安装好 如果防火墙是开启状态 需要防火墙开通端口 永久开放如
  • CVPR 2023

    论文题目 Accelerated Coordinate Encoding Learning to Relocalize in Minutes using RGB and Poses 在公众号 3D视觉工坊 后台回复 原论文 可获取对应论文p
  • 血压计算法

    1 1 动脉平均压的计算 动脉平均压 MAP 是血压波 P t 形在一个周期内的积分除以周期T 其定义如下 均压反映了动脉血压的数值和波形 从试波法原理的两条基本原则 振荡波包络线呈现出近似抛物线的形态 脉搏振荡波振幅最大对应的袖带压力为平
  • 109,有序链表转换为二叉搜索树

    给定一个单链表 其中的元素按升序排序 将其转换为高度平衡的二叉搜索树 本题中 一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 示例 给定的有序链表 10 3 0 5 9 一个可能的答案是 0 3 9 10
  • css 小记

    新的 CSS 伪类函数 is 和 where is 旧的写法 h1 gt b h2 gt b h3 gt b h4 gt b h5 gt b h6 gt b color hotpink 新的写法 伪类 is is h1 h2 h3 h4 h
  • RSA算法多种生成公私钥的方式

    前言 在实际项目开发中常常需要用到非对称性加密算法生成公私钥应用于加密与认证 服务器间ssh免密等 关于非对称性加密算法生成公私钥等笔者之前有发表过一篇有趣的文章 感兴趣的朋友可以去了解下 生成公私钥的方式有很多 本文以RSA算法为例来讨论
  • 基于Matlab的跨孔CT胖射线追踪算法(二)

    基于Matlab的跨孔CT胖射线追踪算法 二 CT技术是一种无损的工程物探检测技术 因其方法简单 分辨率高 理论上更可靠 结果更直观 被广泛的应用于各种工程 胖射线追踪是CT技术的一种正演算法 本文的代码和示意图 供学习借鉴 1 文章目录
  • Java——JavaDoc生成文档

    JavaDoc javadoc命令是用来生成自己的APi文档 参数信息 author 作者名 version 版本号 since 致命需要最早使用的jdk版本 param 参数名 return 返回值情况 throws 异常抛出情况 用一段
  • pyecharts折线图上symbol(小圆圈)颜色的修改方法

    本人刚接触pyecharts 尝试做k线与指标图 但遇到不少困难 虽然pyecharts虽在展现上令人舒畅 但使用起来并不能像echarts那么完善 比如k线的颜色目前就改不了 我是在尝试了各种方法后 才在GitHub上找到了作者的回答 此
  • 截图 识别指定位置文字

    def tu browser get screenshot as file 1 png img Image open 1 png bo 图片左边到元素左边的距离 图片上面到元素上边的距离 图片左边到元素最右边的距离 图片上面到元素最下边的距
  • Keras—embedding嵌入层的使用

    最近在工作中进行了NLP的内容 使用的还是Keras中embedding的词嵌入来做的 Keras中embedding层做一下介绍 中文文档地址 https keras io zh layers embeddings 参数如下 其中参数重点