我想遵循卷积神经网络(CNN)方法here . 但是,github中的这段代码使用了Pytorch,而我使用的是Keras .
我想重现方框6,7和8,其中下载了来自ImageNet上的VGG-16的预训练权重,并用于使CNN更快地收敛 .
特别地,存在一个部分(框8),其中从VGG-16下载并跳过权重,其在 SegNet
(CNN模型)中没有对应物 . 在我的工作中,我使用名为 U-Net
的CNN模型而不是 Segnet
. 我正在使用的 U-Net
Keras代码可以找到here .
我是Keras的新手,非常感谢Keras代码中有关如何下载和跳过与我的 U-Net
型号无对应的VGG权重的任何见解 .
2 回答
此解决方案草图如下所示:
weights='imagenet'
标志加载ImageNet权重:如果您不想花时间查找每个图层的索引,可以使用图层构造函数中的
name='some_name'
参数为相关图层指定名称,然后按如下方式访问权重:资料来源:
Loading VGG
Getting weights from layer(FChollet是Keras的创造者)
Getting and setting weights
干杯
您正在寻址的技术称为 "Transfer Learning" - 当使用不同数据集上的预训练模型作为模型的一部分作为更好收敛的起点时 . 它背后的直觉很简单:我们假设在对如此庞大且丰富的数据集进行训练之后,该模型的卷积核将学习有用的表示 .
在您的特定情况下,您希望在底部堆叠
VGG16
权重,在顶部堆叠解卷积块 . 我会一步一步地指出你是Keras
的新手 . 此答案按照分步教程进行组织,并将为您提供在您自己的代码中使用的小片段 .装载重量
在您链接到上面的
PyTorch
代码中,首先定义模型,然后才复制权重 . 我发现这种方法很丰富,因为它包含许多不必要的代码 . 在这里,我们首先加载VGG16
,然后将其他图层堆叠在顶部 .使用底部的VGG16定义U-Net计算图
如前一段所述,您无需定义模型并复制权重 . 只需在
vgg_model
上堆叠其他图层:我想强调一下,我们在本段中所做的只是定义
U-Net
的计算图 . 此代码专门为VGG16
编写,但您可以根据需要对其他体系结构进行修改 .创建模型
在上一步之后,我们得到了一个计算图(我假设您使用
Tensorflow
后端为Keras
. 如果您使用Theano
,我建议您切换到Tensorflow
,因为此框架现已达到成熟状态) . 现在,我们需要做以下事情:在此计算图之上创建模型
冻结底层,因为您不想破坏预先训练过的砝码
“我感到困惑”
假设你是
Keras
的新手和一般的深度学习(正如你在问题中所承认的那样),我建议阅读以下文章以进一步了解Keras上的 Fine Tuning 和 Transfer Learning 的过程:How CNNs see the world - 一篇很棒的短文,让您直观地了解转会学习背后的肮脏魔力 .
Building powerful image classification models using very little data - 这个将为您提供有关如何调整学习率和冻结层的更多信息 .
当您学习框架时,文档是您最好的朋友 . 幸运的是,
Keras
有一个令人难以置信的documentation .问答
是的,它与here相同,只是跳过连接层的名称不同(例如
block1_conv2
而不是conv1
)我们不会离开或抛出VGG网络中的任何图层 .
VGG16
网络架构和U-Net
(最高conv5
)的底层架构非常相似 . 实际上,它们由以下格式的5
块组成:Here是一个更好的可视化 . 因此,
VGG16
与U-Net
的底部之间的唯一区别是VGG16
的每个块包含多个卷积层而不是一个 . 这就是为什么,将conv3
连接到conv6
的替代方法是将block3_conv3
连接到conv6
.U-Net
架构保持不变,只是在底部有更多的卷积层 .我们不会把它们排除在外 . 我丢弃的唯一汇集层是
block5_pool
(这是VGG16
底部的最后一层) - 因为在原始U-Net
(参见code)中,似乎底部的最后一个卷积块后面没有池化层(我们有conv5
但没有pool5
) . 我保留了VGG16
的所有层次 .正如我在上面的问题中所解释的那样,我们不会丢弃任何池化层 . 但是,您需要堆叠不同类型的池化层而不是默认
VGG16
中使用的简单MaxPooling2D
,因为SegNet
保留了最大索引 . 这可以通过tf.nn.max_pool_with_argmax并使用replacing middle layers of Keras model的技巧来实现(我赢得了't cover the detailed information in this answer to keep it clean). The replacement is harmless and doesn' t需要重新训练,因为合并图层不包含任何训练过的权重 .这是一个更浅的U-Net . 原始问题中的一个在底部有5个卷积块(
conv1
-conv5
),而后者只有3个 . 根据数据选择需要多少个块(例如,对于简单数据,您可能只想使用2个单元格) -3块,而灰质或组织分割可能需要5个块以获得更好的质量 . 请参阅this链接以了解卷积内核"see" .有趣 . 这是一个不正确的实现,并不等同于您发布的Pytorch代码 . 我在该存储库中打开了issue .
一般来说是 . 将卷积内核视为“特征”:第一层检测小边缘和颜色 . 以下图层将这些边和颜色组合成更复杂的检测,如“黄线”或“蓝色圆圈” . 然后,上卷积层基于下层的检测将更抽象的形状检测为“眼睛”,“鼻子”等 . 因此,替换底层(而上层取决于底部表示)是不合逻辑的 .