Después de entrenar algunas capas en el modelo fijo durante el entrenamiento previo, ¿se siguen modificando estas capas?

0. Resumen

En el aprendizaje profundo, a menudo usamos el entrenamiento previo para ajustar y mejorar la capacidad de generalización del modelo, acelerar la velocidad de convergencia y ahorrar tiempo de entrenamiento.

En términos generales, hay muchas formas de preentrenar. Las más comunes son establecer una tasa de aprendizaje más pequeña para la capa de preentrenamiento o arreglar la capa de preentrenamiento sin actualizar los pesos. Esto último se analiza aquí.

1. Entrenamiento de capa fija

Ahora suponga que tiene el modelo:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.layer1=conv_base  # conv_base是由conv、BN等组成的卷积基
        self.fc1=nn.Linear(512,100)   # 分类器
        self.fc2=nn.Linear(100, 10)   # 分类器
    
    def forward(self,x):
        feat=self.layers(x)
        out=self.fc1(feat)
        out=self.fc2(out)
        return out

Entre ellos, la capa 1 es la extracción de características preentrenada, y fc1 y fc2 son lo que necesitamos entrenar, por lo que queremos arreglar los parámetros de la capa 1 y solo entrenar los parámetros de fc1 y fc2. Hay dos formas de lograrlo ( esencialmente lo mismo):

  • Establecer require_grad=True para parámetros fijos
# 首先将固定层layer1的requires_grad属性置False
for name, p in model.layer1.named_parameters():   # 固定feat权重
	p.requires_grad = False

# 在优化器中过滤到这些requires_grad参数
para=filter(lambda x:x.requires_grad is not False,model.parameters())
optimizer = torch.optim.SGD(para, lr=0.1)
  • Especifique solo los parámetros que se actualizarán directamente en el optimizador
para=[{
    
    "params":model.fc1.parameters()},
      {
    
    "params":model.fc2.parameters()}]
optimizer = torch.optim.SGD(para, lr=0.1)

En los dos métodos anteriores, el optimizador especifica el método de solo actualizar parámetros para entrenar parámetros específicos.

2. Problema

Después de entrenar de la manera anterior, los parámetros de la capa 1 permanecen sin cambios, solo cambian los parámetros de fc1 y fc2, pero cuando uso los parámetros de la capa 1 para verificar el conjunto de datos, encuentro que los indicadores han cambiado. La capa 1 no ha cambiado. Las métricas también deben ser las mismas que antes del entrenamiento.

De hecho, el problema radica en los modos entrenar () y eval () . Sabemos que BatchNorm debe operar de acuerdo con la media y la varianza de las muestras del conjunto de datos. Durante el entrenamiento, BatchNorm calculará la media y la varianza del conjunto de datos. muestras Al mismo tiempo, se guardará la media y la varianza de este tiempo. Al verificar y probar, la cantidad de datos es relativamente pequeña (extremadamente 1), y la media y la varianza en este momento se calculan usando la media y la varianza guardadas durante el entrenamiento.

Entonces, aunque arreglamos el entrenamiento de parámetros de capa 1, pero en el modo model.train () capa 1, los parámetros en BatchNorm contenidos en él se cambian. Cuando usamos capa 1 para probar en el conjunto de datos nuevamente, usamos la media actualizada y estándar , haciendo que el indicador cambie.

En resumen, aunque los parámetros de la capa 1 que no es BatchNorm (como conv, etc.) no han cambiado, los parámetros de BatchNorm sí lo han hecho.

La solución también es muy sencilla:

# 训练时:先将模型全设为train模型,再将固定曾layer1设为eval模式,这样保证了参数不更新,且BatchNorm层参数也不更新
model.train()
model.layer1.eval()

# 测试时:
model.eval()

Supongo que te gusta

Origin blog.csdn.net/qq_40243750/article/details/129503158
Recomendado
Clasificación