如何在 pytorch 中逐步发展神经网络?
How to progressively grow a neural network in pytorch?
我正在尝试制作一个渐进式自动编码器,并且我想了几种在训练期间发展我的网络的方法。但是,我总是停留在这一部分,我不知道更改输入(编码器)和输出(解码器)通道是否会影响我的网络。请参阅下面的示例。
X = torch.randn( 8, 1, 4, 4,) # A batch of 8 grayscale images of 4x4 pixels in size
Encoder = nn.Sequential( Conv2D( 1, 16, 3, 1, 1 ), nn.ReLU() ) # starting setup 16 3x3 kernels
如果我从网络打印上述权重,我将得到大小为 [ 1, 16, 3, 3 ],16 个内核,每个大小为 3x3
如果我想扩大网络,我需要保存这些权重,因为希望它已经在那些 4x4 图像输入上训练有素。
X = torch.randn( 8, 1, 8, 8) # increase the image size from 4x4 to 8x8
...
new_model = nn.Sequential()
then do...
# copy the previous layer and its weights from the original encoder
# BTW My issue starts here.
# Add/grow the new_model with new layers concat with the old layer, also modify the input channela so they can link correctly
# Final result would be like something below.
new_model = nn.Sequential( Conv2D( **1**, 8, 3, 1, 1 ), nn.ReLU(), Conv2D( **8**, 16, 3, 1, 1 ), nn.ReLU() )
Encoder = new_model
# Repeat process
一切看起来都不错,但是因为我改变了输入通道,权重的大小也发生了变化,这是我已经坚持了一段时间的问题。您可以通过 运行,
简单地检查一下
foo_1 = nn.Conv2d(1, 1, 3, 1, 1) # You can think this as the starting Conv2D from the starting encoder
foo_2 = nn.Conv2d(3, 1, 3, 1, 1) # You can think this as the modfiied starting Conv2D with an outer layer outputting 3 channels connecting to it
print(foo_1.weight.size()) # torch.Size([1, 1, 3, 3])
print(foo_2.weight.size()) # torch.Size([1, 3, 3, 3])
最初,我认为 foo_1 和 foo_2 都具有相同的权重大小,因为两者都只使用一个 3x3 内核,但事实并非如此。我希望你现在能看到我的困境,在 x 个时期之后我需要增加另一个卷积并且我必须弄乱输入大小才能正确地制作新层链但是如果我改变输入大小权重的形状是不同的并且我不知道粘贴旧状态如何工作。
我一直在研究 pytorch 和 IMO 中的 pro gan 实现,它们不容易阅读。我如何建立更多关于如何正确逐步发展您的网络的机构?
通过渐进式自动编码器,我假设您指的是 Pioneer Networks: Progressively Growing Generative Autoencoder which referred Progressive Growing of GANs for Improved Quality, Stability, and Variation.
首先,不要使用nn.Sequential
。它非常适合建模简单直接的网络结构,这里绝对不是这样。您应该使用简单的 nn.Conv2d
、F.ReLU
模块而不是构建 nn.Sequential
对象。
其次,这不是真正的实施,而是理论。您不能神奇地将卷积层从接受 1 个通道转换为 8 个通道。有很多方法可以 扩展 你的卷积过滤器,比如附加随机权重,但我认为这不是你想要的。
从第二篇论文(是GAN,但思路是一样的)看,没有展开任何filter。相反,过滤器在整个训练过程中保持其形状。也就是说,您将拥有
Conv2D(8, 16, 3, 1, 1)
从一开始(假设你只有这两层)。一个明显的问题出现了——你的灰度图像是单通道输入,但你的卷积在训练的第一阶段需要 8 通道输入。在第二篇论文中,它使用额外的 1x1 卷积层来映射 RGB <-> 特征图。在你的情况下,那将是
Conv2D(1, 8, 1)
它将 1 通道输入映射到 8 通道输出。这可以在你完成第一阶段后扔掉。
还有其他技术,例如逐渐淡化使用论文中所述的权重项。我建议你读一读,尤其是第二本。
我正在尝试制作一个渐进式自动编码器,并且我想了几种在训练期间发展我的网络的方法。但是,我总是停留在这一部分,我不知道更改输入(编码器)和输出(解码器)通道是否会影响我的网络。请参阅下面的示例。
X = torch.randn( 8, 1, 4, 4,) # A batch of 8 grayscale images of 4x4 pixels in size
Encoder = nn.Sequential( Conv2D( 1, 16, 3, 1, 1 ), nn.ReLU() ) # starting setup 16 3x3 kernels
如果我从网络打印上述权重,我将得到大小为 [ 1, 16, 3, 3 ],16 个内核,每个大小为 3x3 如果我想扩大网络,我需要保存这些权重,因为希望它已经在那些 4x4 图像输入上训练有素。
X = torch.randn( 8, 1, 8, 8) # increase the image size from 4x4 to 8x8
...
new_model = nn.Sequential()
then do...
# copy the previous layer and its weights from the original encoder
# BTW My issue starts here.
# Add/grow the new_model with new layers concat with the old layer, also modify the input channela so they can link correctly
# Final result would be like something below.
new_model = nn.Sequential( Conv2D( **1**, 8, 3, 1, 1 ), nn.ReLU(), Conv2D( **8**, 16, 3, 1, 1 ), nn.ReLU() )
Encoder = new_model
# Repeat process
一切看起来都不错,但是因为我改变了输入通道,权重的大小也发生了变化,这是我已经坚持了一段时间的问题。您可以通过 运行,
简单地检查一下foo_1 = nn.Conv2d(1, 1, 3, 1, 1) # You can think this as the starting Conv2D from the starting encoder
foo_2 = nn.Conv2d(3, 1, 3, 1, 1) # You can think this as the modfiied starting Conv2D with an outer layer outputting 3 channels connecting to it
print(foo_1.weight.size()) # torch.Size([1, 1, 3, 3])
print(foo_2.weight.size()) # torch.Size([1, 3, 3, 3])
最初,我认为 foo_1 和 foo_2 都具有相同的权重大小,因为两者都只使用一个 3x3 内核,但事实并非如此。我希望你现在能看到我的困境,在 x 个时期之后我需要增加另一个卷积并且我必须弄乱输入大小才能正确地制作新层链但是如果我改变输入大小权重的形状是不同的并且我不知道粘贴旧状态如何工作。
我一直在研究 pytorch 和 IMO 中的 pro gan 实现,它们不容易阅读。我如何建立更多关于如何正确逐步发展您的网络的机构?
通过渐进式自动编码器,我假设您指的是 Pioneer Networks: Progressively Growing Generative Autoencoder which referred Progressive Growing of GANs for Improved Quality, Stability, and Variation.
首先,不要使用nn.Sequential
。它非常适合建模简单直接的网络结构,这里绝对不是这样。您应该使用简单的 nn.Conv2d
、F.ReLU
模块而不是构建 nn.Sequential
对象。
其次,这不是真正的实施,而是理论。您不能神奇地将卷积层从接受 1 个通道转换为 8 个通道。有很多方法可以 扩展 你的卷积过滤器,比如附加随机权重,但我认为这不是你想要的。
从第二篇论文(是GAN,但思路是一样的)看,没有展开任何filter。相反,过滤器在整个训练过程中保持其形状。也就是说,您将拥有
Conv2D(8, 16, 3, 1, 1)
从一开始(假设你只有这两层)。一个明显的问题出现了——你的灰度图像是单通道输入,但你的卷积在训练的第一阶段需要 8 通道输入。在第二篇论文中,它使用额外的 1x1 卷积层来映射 RGB <-> 特征图。在你的情况下,那将是
Conv2D(1, 8, 1)
它将 1 通道输入映射到 8 通道输出。这可以在你完成第一阶段后扔掉。
还有其他技术,例如逐渐淡化使用论文中所述的权重项。我建议你读一读,尤其是第二本。