为什么以下代码运行两次克层?
import numpy as np
from keras.applications import vgg19
from keras import backend as K
from keras.layers import Input, Lambda
import tensorflow as tf
from keras.models import Model
def gram_layer(y):
print('Using Gram Layer')
# assert K.ndim(y) == 4
print(y.shape, 'y.shape')
# a = y.get_shape()[1].value
# b = y.get_shape()[2].value
# c = y.get_shape()[3].value
# print(a, b, c)
# x = K.squeeze(y, axis=0)
# features = K.batch_flatten(K.permute_dimensions(x, (2, 0, 1)))
# features_nomean = features - K.mean(features, axis=0, keepdims=True)
# gram = K.dot(features_nomean, K.transpose(features_nomean)) / (a * b * c)
print('exiting Gram')
# return x
return y
In = K.placeholder((1, 256, 256, 3))
model = vgg19.VGG19(input_tensor = In, weights='imagenet', include_top=False)
for layer in model.layers:
if layer.name == 'block1_conv1':
print(layer.name)
print(layer.output.shape)
outputs = (Lambda(gram_layer))(layer.output)
调试信息:
block1_conv1
(1, 256, 256, 64)
Using Gram Layer
(1, 256, 256, 64) y.shape
exiting Gram
Using Gram Layer
(?, ?, ?, 64) y.shape
exiting Gram
调试信息包含两个"使用革兰氏层",这意味着该层运行两次,并且第二次失败,但奇怪的是仅被称为一次。
任何想法怎么了?
ps:我意识到问题在于for循环部分,如果最后一行
outputs = (Lambda(gram_layer))(layer.output)
被替换为
outputs = (Lambda(gram_layer))(In)
调试信息如
block1_conv1
(1, 256, 256, 64)
Using Gram Layer
(1, 256, 256, 3) y.shape
exiting Gram
Using Gram Layer
(?, ?, ?, 3) y.shape
exiting Gram
如果最后5行被替换为
outputs = (Lambda(gram_layer))(In)
然后调试信息
Using Gram Layer
(1, 256, 256, 3) y.shape
exiting Gram
Using Gram Layer
(1, 256, 256, 3) y.shape
exiting Gram
它仍然运行两次,但形状推断是正确的。这是一个错误吗?还是我应该在github报告?
不确定为什么您的功能被称为两次,但是看到这一点并不少见。首先在汇编过程中被称为
似乎以"无"值重塑的问题。这不支持。
您可以用" -1"而不是没有重塑,但是在重塑中只能有一个" -1"。
建议1:
您所有的重塑代码都可以替换为:x = K.squeeze(y,axis=0)
警告:
,但这在凯拉斯(Keras)非常不寻常。axis=0
尺寸是批处理大小。此代码只能使用batch_size = 1
运行良好。(要么您的代码和我的建议)。
建议2:
如果您要使用batch_flatten
,为什么要重塑?您在batch_flatten()
之前进行的任何重塑都是毫无意义的,除非您真的是要平坦的最后两个维度并具有(256,768)
张量。
建议3:
如果您想要a
的实际值,b
,c
对于计算,则需要获得其张量值而不是其配置值:
shp = K.shape(y)
a = shp[1] #maybe you need shp[1:2], depending on whether you get an error in the division line
b = shp[2]
c = shp[3]
建议4:
使用占位符很奇怪。那不是卡拉斯的方式。
您应该简单地创建模型并告诉它您想要的形状:
model = vgg19.VGG19(input_shape = (256,256,64), weights='imagenet', include_top=False)
如果您确实要执行1个大小为1,则可以创建输入张量:
inputTensor = Input(batch_shape=(1,256,256,64)
output = model(inputTensor)
model = Model(inputTensor, output)