【发布时间】:2021-05-28 23:22:16
【问题描述】:
我有兴趣在 PyTorch 中同时训练 CNN 模型和简单的线性前馈模型,并在训练后向 CNN 层和神经元添加更多过滤器——线性模型层和输出(例如从二元分类到多类分类)。通过添加它们,我的具体意思是保持训练的权重不变,并将随机初始化的权重添加到新的传入权重。
【问题讨论】:
标签: python neural-network pytorch
我有兴趣在 PyTorch 中同时训练 CNN 模型和简单的线性前馈模型,并在训练后向 CNN 层和神经元添加更多过滤器——线性模型层和输出(例如从二元分类到多类分类)。通过添加它们,我的具体意思是保持训练的权重不变,并将随机初始化的权重添加到新的传入权重。
【问题讨论】:
标签: python neural-network pytorch
这个有点棘手,需要slice(有关slice 的更多信息,请参阅this answer,但它应该是直观的)。还有this answer 用于切片技巧。解释请看cmets:
import torch
def expand(
original: torch.nn.Module,
*args,
**kwargs
# Add other arguments if needed, like different stride
# They won't change weights shape, but may change behaviour
):
new = type(original)(*args, **kwargs)
new_weight_shape = torch.tensor(new.weight.shape)
new_bias_shape = torch.tensor(new.bias.shape)
original_weight_shape = torch.tensor(original.weight.shape)
original_bias_shape = torch.tensor(original.bias.shape)
# I assume bias and weight exist, if not, do some checks
# Also quick check, that new layer is "larger" than original
assert torch.all(new_weight_shape >= original_weight_shape)
assert new_bias_shape >= original_bias_shape
# All the weights will be inputted from top to bottom, bias 1D assumed
new.bias.data[:original_bias_shape] = original.bias.data
# Create slices 0:n for each dimension
slicer = tuple([slice(0, dim) for dim in original_weight_shape])
# And input the data
new.weight.data[slicer] = original.weight.data
return new
layer = torch.nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3)
new = expand(layer, in_channels=32, out_channels=64, kernel_size=3)
这应该适用于任何层(有weight 和bias,如果需要可以调整)。使用这种方法,您可以重新创建神经网络或使用 PyTorch 的 apply(文档 here)
还请记住,您必须为“新层”显式传递 *args 和 **kwargs,这将输入经过训练的连接。
【讨论】:
in_channels 不应该是一样的吗?因为输入本身不会改变