Keras实现支持masking的Flatten层代码
不知道为什么,我总是需要实现某种骚操作,而这种骚操作往往是Keras不支持的。例如,我有一个padding过的矩阵,那么它一定是带masking的,然后我想要把它Flatten,再输入到Dense层。然而Keras的Flatten层不支持masking。
Keras原本Flatten的实现
class Flatten(Layer):
def __init__(self, **kwargs):
super(Flatten, self).__init__(**kwargs)
self.input_spec = InputSpec(min_ndim=3)
def compute_output_shape(self, input_shape):
if not all(input_shape[1:]):
raise ValueError('The shape of the input to "Flatten" '
'is not fully defined '
'(got ' + str(input_shape[1:]) + '. '
'Make sure to pass a complete "input_shape" '
'or "batch_input_shape" argument to the first '
'layer in your model.')
return (input_shape[0], np.prod(input_shape[1:]))
def call(self, inputs):
return K.batch_flatten(inputs)
自定义支持masking的实现
事实上,Keras层的mask有时候是需要参与运算的,比如Dense之类的,有时候则只是做某种变换然后传递给后面的层。Flatten属于后者,因为mask总是与input有相同的shape,所以我们要做的就是在compute_mask函数里对mask也做flatten。
from keras import backend as K
from keras.engine.topology import Layer
import tensorflow as tf
import numpy as np
class MyFlatten(Layer):
def __init__(self, **kwargs):
self.supports_masking = True
super(MyFlatten, self).__init__(**kwargs)
def compute_mask(self, inputs, mask=None):
if mask==None:
return mask
return K.batch_flatten(mask)
def call(self, inputs, mask=None):
return K.batch_flatten(inputs)
def compute_output_shape(self, input_shape):
return (input_shape[0], np.prod(input_shape[1:]))
正确性检验
from keras.layers import *
from keras.models import Model
from MyFlatten import MyFlatten
from MySumLayer import MySumLayer
from keras.initializers import ones
data = [[1,0,0,0],
[1,2,0,0],
[1,2,3,0],
[1,2,3,4]]
A = Input(shape=[4]) # None * 4
emb = Embedding(5, 3, mask_zero=True, embeddings_initializer=ones())(A) # None * 4 * 3
fla = MyFlatten()(emb) # None * 12
out = MySumLayer(axis=1)(fla) # None * 1
model = Model(inputs=[A], outputs=[out])
print model.predict(data)
输出:
[ 3. 6. 9. 12.]
补充知识:pytorch中的reshape()、view()、transpose()和flatten()
1、torch.reshape()
reshape()可以由torch.reshape(),也可由torch.Tensor.reshape()调用
其作用是在不改变tensor元素数目的情况下改变tensor的shape
import torch
import numpy as np
a = np.arange(24)
b = a.reshape(4,3,2)
print(np.shape(a))
print(b,np.shape(b))
'''结果
(24,)
[[[ 0 1]
[ 2 3]
[ 4 5]]
[[ 6 7]
[ 8 9]
[10 11]]
[[12 13]
[14 15]
[16 17]]
[[18 19]
[20 21]
[22 23]]] (4, 3, 2)
'''
2、view()
view()只可以由torch.Tensor.view()来调用
view()和reshape()在效果上是一样的,区别是view()只能操作contiguous的tensor,且view后的tensor和原tensor共享存储,reshape()对于是否contiuous的tensor都可以操作。
3、transpose()
torch.transpose(input, dim0, dim1) – Tensor
将输入数据input的第dim0维和dim1维进行交换
#官方例子
x = torch.randn(2, 3)
x
tensor([[ 0.9068, 1.8803, -0.5021],
[-0.6576, 0.6334, -0.8961]])
torch.transpose(x, 0, 1)
tensor([[ 0.9068, -0.6576],
[ 1.8803, 0.6334],
[-0.5021, -0.8961]])
4、flatten()
torch.flatten()的输入是tensor
torch.flatten(input, start_dim=0, end_dim=-1) → Tensor
其作用是将输入tensor的第start_dim维到end_dim维之间的数据“拉平”成一维tensor,
#官方例子
t = torch.tensor([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
torch.flatten(t)
tensor([1, 2, 3, 4, 5, 6, 7, 8])
torch.flatten(t, start_dim=1)
tensor([[1, 2, 3, 4],
[5, 6, 7, 8]])
torch.nn.Flatten()可以理解为一种网络结构,类似Conv2d、Linear。一般放在卷积层和全连接层之间,将卷积层输出“拉平”成一维,
m = torch.nn.Sequential(
torch.nn.Conv2d(1, 32, 5, 1, 1),
torch.nn.Flatten(),
torch.nn.Linear(160,10))
m
Sequential(
(0): Conv2d(1, 32, kernel_size=(5, 5), stride=(1, 1), padding=(1, 1))
(1): Flatten()
(2): Linear(in_features=160, out_features=10, bias=True)
)
以上这篇Keras实现支持masking的Flatten层代码就是小编分享给大家的全部内容了,希望能给大家一个参考。
- MySQL中xtrabackup备份恢复全攻略(r12笔记第11天)
- 分享一次Linux任务计划crontab不执行的问题排查过程
- MySQL 5.6, 5.7并行复制测试(r12笔记第9天)
- MySQL 5.6, 5.7并行复制测试(二)(r12笔记第10天)
- MySQL主从报错解决:Failed to initialize the master info structure
- 使用pt工具检测MySQL主从延迟(r12笔记第7天)
- WordPress发布/更新文章、提交/审核评论自动清理VeryCloud缓存
- MySQL中的binlog和redo浅析(r12笔记第5天)
- WordPress发布/更新文章、提交/审核评论自动清理腾讯云CDN缓存
- 使用sysbench压力测试MySQL(一)(r11笔记第3天)
- 分享一下php7和其他php多版本共存的配置教程
- 使用sysbench压力测试MySQL(二)
- 使用sysbench压力测试MySQL(三)(r12笔记第6天)
- 解决IE响应式的解决方案css3-mediaqueries.js不生效问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- JAVA实现UTC时间转换成北京时间
- JDK8 LocalDateTime转换成时间戳
- Grafana创建zabbix自定义template(模板)
- 一条SQL引发的“血案”:
- Grafana安装配置Elasticsearch插件
- Elasticsearch升级踩坑记之使用snapshot备份数据
- RabbitMQ的安装及集群搭建方法
- CentOs7搭建rabbitmq集群
- Rabbitmq haproxy keepalived ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN.
- IDEA maven+spring mvc简单项目
- 程序员用python给了女友一个七夕惊喜!
- 微信小程序开发实战(21):发起HTTPS请求
- 打破国外垄断,开发中国人自己的编程语言(2):使用监听器实现计算器
- 自定义你的github主页
- nginx配置ssl证书实现https