Keras Layer 的 call(x) 和 input_shape
今天用Keras编程的时候发现一个问题,
···
input_layer = K.layers.Input(shape=(10,))
x = K.layers.Dense(20)(input_layer)
x = K.layers.Dense(20)(x)
···
以上写法是可行的,但是以下写法却不行
L = K.layers.Dense(20)
y = L(input_layer)
y = L(y)
前两个表达式正常,到了第3个表达式y=L(y)
的时候就报input_shape
错误。百思不得其解,按照Python编程的原则,一切皆对象
L = K.layers.Dense(20)
L(x)
和
K.layers.Dense(20)(x)
有何不同?
一番尝试,发现奥妙在于Keras Layers的设计。看一下官方的对于自定义Layer的说明,
call(x)
: this is where the layer's logic lives. Unless you want your layer to support masking, you only have to care about the first argument passed to call: the input tensor.
也就是说,当layer的call
method被调用时,layer才实际存在,此时将传入input_shape。如果call
没有被调用,此时layer中并没有input_shape的信息。
举例说明,
L = K.layers.Dense(20)
L.input_shape
此时编译器报错`AttributeError: The layer has never been called and thus has no defined input shape. 再看以下代码,
L = K.layers.Dense(20)
y = L(input_layer)
L.input_shape
此时编译器不报错,输出(None, 10)
。照理说第二段代码并没有对L
做任何操作,只是将L(input_layer)
赋给了y
,但是此时L
确获得了input_shape
这个参数。
结合call(x)
的定义,一开始遇到的问题也就明白了。表达式y = L(input_layer)
调用了L
的call
method,此时L
这个layer才正式被初始化,其input_shape也根据传入的input_layer
被赋值 。因此,此时的L
其实已经跟表达式K.layers.Dense(20)
不一样了,后者未被调用,input_shape
不存在。
以下这段代码之所以报input_shape错误,就是因为y = L(input_layer)
使得L
的input_shape被初始化为(10,)
。因次当第三个表达式y=L(y)
中y
被传入L
时,由于y
的shape并不是(10,)
,而是(20,)
,与L
中input_shape的值不一致,编译器报错。
L = K.layers.Dense(20)
y = L(input_layer)
y = L(y)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决