Keras 使用 TimeDistributed 预训练 CNN
Keras pretrain CNN with TimeDistributed
这是我的问题,我想在 TimeDistributed 层中使用预训练 CNN 网络之一。但是我在实现它时遇到了一些问题。
这是我的模型:
def bnn_model(max_len):
# sequence length and resnet input size
x = Input(shape=(maxlen, 224, 224, 3))
base_model = ResNet50.ResNet50(weights='imagenet', include_top=False)
for layer in base_model.layers:
layer.trainable = False
som = TimeDistributed(base_model)(x)
#the ouput of the model is [1, 1, 2048], need to squeeze
som = Lambda(lambda x: K.squeeze(K.squeeze(x,2),2))(som)
bnn = Bidirectional(LSTM(300))(som)
bnn = Dropout(0.5)(bnn)
pred = Dense(1, activation='sigmoid')(bnn)
model = Model(input=x, output=pred)
model.compile(optimizer=Adam(lr=1.0e-5), loss="mse", metrics=["accuracy"])
return model
编译模型时没有错误。但是当我开始训练时,出现以下错误:
tensorflow/core/framework/op_kernel.cc:975] Invalid argument: You must feed a value for placeholder tensor 'input_2' with dtype float
[[Node: input_2 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
我检查过并确实发送了 float32,但对于 input1,input2 是预训练 Resnet 中存在的输入。
这里只是为了概览一下模型摘要。 (注意:很奇怪,它没有显示 Resnet 内部发生的事情,但没关系)
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
input_1 (InputLayer) (None, 179, 224, 224, 0
____________________________________________________________________________________________________
timedistributed_1 (TimeDistribut (None, 179, 1, 1, 204 23587712 input_1[0][0]
____________________________________________________________________________________________________
lambda_1 (Lambda) (None, 179, 2048) 0 timedistributed_1[0][0]
____________________________________________________________________________________________________
bidirectional_1 (Bidirectional) (None, 600) 5637600 lambda_1[0][0]
____________________________________________________________________________________________________
dropout_1 (Dropout) (None, 600) 0 bidirectional_1[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 1) 601 dropout_1[0][0]
====================================================================================================
Total params: 29,225,913
Trainable params: 5,638,201
Non-trainable params: 23,587,712
____________________________________________________________________________________________________
我猜我没有正确使用 TimeDistributed,而且我看到没有人尝试这样做。我希望有人能指导我。
编辑:
问题来自于 ResNet50.ResNet50(weights='imagenet', include_top=False)
在图表中创建自己的输入。
所以我想我需要做类似 ResNet50.ResNet50(weights='imagenet', input_tensor=x, include_top=False)
的事情,但我不知道如何将它与 TimeDistributed
相结合。
我试过了
base_model = Lambda(lambda x : ResNet50.ResNet50(weights='imagenet', input_tensor=x, include_top=False))
som = TimeDistributed(base_model)(in_ten)
但是不行。
我的快速解决方案有点难看。
我刚刚复制了 ResNet 的代码并将 TimeDistributed 添加到所有层,然后在我自定义的 ResNet 上从 "basic" ResNet 加载了权重。
注:
像这样分析图像序列确实需要占用大量的 gpu 内存。
我的简单解决方案很漂亮。
考虑到您使用的是来自 keras 的预训练网络,您也可以将其替换为您自己的预训练网络。
这是一个简单的解决方案::
model_vgg=keras.applications.VGG16(input_shape=(256, 256, 3),
include_top=False,
weights='imagenet')
model_vgg.trainable = False
model_vgg.summary()
如果你想使用任何中间层,否则将 'block2_pool' 替换为最后一层的名称::
intermediate_model= Model(inputs=model_vgg.input, outputs=model_vgg.get_layer('block2_pool').output)
intermediate_model.summary()
最后将其包裹在 TimeDistributed 层中
input_tensor = Input(shape=(time_steps,height, width, channels))
timeDistributed_layer = TimeDistributed( intermediate_model )(input_tensor)
现在你可以简单地做::
my_time_model = Model( inputs = input_tensor, outputs = timeDistributed_layer )
这是我的问题,我想在 TimeDistributed 层中使用预训练 CNN 网络之一。但是我在实现它时遇到了一些问题。
这是我的模型:
def bnn_model(max_len):
# sequence length and resnet input size
x = Input(shape=(maxlen, 224, 224, 3))
base_model = ResNet50.ResNet50(weights='imagenet', include_top=False)
for layer in base_model.layers:
layer.trainable = False
som = TimeDistributed(base_model)(x)
#the ouput of the model is [1, 1, 2048], need to squeeze
som = Lambda(lambda x: K.squeeze(K.squeeze(x,2),2))(som)
bnn = Bidirectional(LSTM(300))(som)
bnn = Dropout(0.5)(bnn)
pred = Dense(1, activation='sigmoid')(bnn)
model = Model(input=x, output=pred)
model.compile(optimizer=Adam(lr=1.0e-5), loss="mse", metrics=["accuracy"])
return model
编译模型时没有错误。但是当我开始训练时,出现以下错误:
tensorflow/core/framework/op_kernel.cc:975] Invalid argument: You must feed a value for placeholder tensor 'input_2' with dtype float
[[Node: input_2 = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
我检查过并确实发送了 float32,但对于 input1,input2 是预训练 Resnet 中存在的输入。
这里只是为了概览一下模型摘要。 (注意:很奇怪,它没有显示 Resnet 内部发生的事情,但没关系)
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
input_1 (InputLayer) (None, 179, 224, 224, 0
____________________________________________________________________________________________________
timedistributed_1 (TimeDistribut (None, 179, 1, 1, 204 23587712 input_1[0][0]
____________________________________________________________________________________________________
lambda_1 (Lambda) (None, 179, 2048) 0 timedistributed_1[0][0]
____________________________________________________________________________________________________
bidirectional_1 (Bidirectional) (None, 600) 5637600 lambda_1[0][0]
____________________________________________________________________________________________________
dropout_1 (Dropout) (None, 600) 0 bidirectional_1[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 1) 601 dropout_1[0][0]
====================================================================================================
Total params: 29,225,913
Trainable params: 5,638,201
Non-trainable params: 23,587,712
____________________________________________________________________________________________________
我猜我没有正确使用 TimeDistributed,而且我看到没有人尝试这样做。我希望有人能指导我。
编辑:
问题来自于 ResNet50.ResNet50(weights='imagenet', include_top=False)
在图表中创建自己的输入。
所以我想我需要做类似 ResNet50.ResNet50(weights='imagenet', input_tensor=x, include_top=False)
的事情,但我不知道如何将它与 TimeDistributed
相结合。
我试过了
base_model = Lambda(lambda x : ResNet50.ResNet50(weights='imagenet', input_tensor=x, include_top=False))
som = TimeDistributed(base_model)(in_ten)
但是不行。
我的快速解决方案有点难看。
我刚刚复制了 ResNet 的代码并将 TimeDistributed 添加到所有层,然后在我自定义的 ResNet 上从 "basic" ResNet 加载了权重。
注:
像这样分析图像序列确实需要占用大量的 gpu 内存。
我的简单解决方案很漂亮。
考虑到您使用的是来自 keras 的预训练网络,您也可以将其替换为您自己的预训练网络。
这是一个简单的解决方案::
model_vgg=keras.applications.VGG16(input_shape=(256, 256, 3),
include_top=False,
weights='imagenet')
model_vgg.trainable = False
model_vgg.summary()
如果你想使用任何中间层,否则将 'block2_pool' 替换为最后一层的名称::
intermediate_model= Model(inputs=model_vgg.input, outputs=model_vgg.get_layer('block2_pool').output)
intermediate_model.summary()
最后将其包裹在 TimeDistributed 层中
input_tensor = Input(shape=(time_steps,height, width, channels))
timeDistributed_layer = TimeDistributed( intermediate_model )(input_tensor)
现在你可以简单地做::
my_time_model = Model( inputs = input_tensor, outputs = timeDistributed_layer )