transformer模型训练结构解析(加深理解)

运行项目的一些感受:
很多时候,一个整体的深度学习项目的程序的执行流程是需要理一理的,往往是多个模块层层包含嵌套,然后执行的顺序也是在多个python功能模块间跳转,有时候在某个程序文件里的短短一行代码(比如self._train_model(training_loader) )背后可能是运行了上百行另一个类下的某个函数的功能代码,主要需要体会模型中层层嵌套,模块化的思维,然后掌握举一反三的能力。

深度学习里经常使用到的python基础:

class BaseImputer(BaseModel):
    """Abstract class for all imputation models."""

    def __init__(self, device):
        super().__init__(device)

    @abstractmethod
    def fit(self, train_X, val_X=None):
        """Train the imputer.

        Parameters
        ----------
        train_X : array-like, shape: [n_samples, sequence length (time steps), n_features],
            Time-series data for training, can contain missing values.
        val_X : array-like, optional, shape [n_samples, sequence length (time steps), n_features],
            Time-series data for validating, can contain missing values.

        Returns
        -------
        self : object,
            Trained imputer.
        """
        return self   # self代表类的实例对象,
        #代码最后的return self语句表示将训练好的模型对象返回。
        #也就是说,当调用fit方法进行训练后,方法会返回一个已经训练好的BaseImputer对象
        #该对象可以用于后续的预测或其他操作

模型的定义
在下面常见代码中,self.model是所在类BaseNNImputer的一个成员变量,表示一个机器学习模型(例如神经网络模型、回归模型等)的实例对象。

class BaseNNImputer(BaseNNModel, BaseImputer):
    def __init__(
        self, learning_rate, epochs, patience, batch_size, weight_decay, device
    ):
        super().__init__(
            learning_rate, epochs, patience, batch_size, weight_decay, device
        )

    @abstractmethod
    def assemble_input_data(self, data):
        pass

    def _train_model(
        self,
        training_loader,#text_emb,
        val_loader=None,
        val_X_intact=None,
        val_indicating_mask=None,
    ):
        self.optimizer = torch.optim.Adam(
            self.model.parameters(), lr=self.lr, weight_decay=self.weight_decay
        )

        # each training starts from the very beginning, so reset the loss and model dict here
        self.best_loss = float("inf")
        self.best_model_dict = None

        try:
            for epoch in range(self.epochs):
                self.model.train() #self.model是所在类BaseNNImputer的一个成员变量
                epoch_train_loss_collector = []
                ........
如何具体定义一个深度学习模型?
self.model = _TransformerEncoder(

            self.n_layers,

            self.n_steps,

            self.n_features,

            self.d_model,

            self.d_inner,

            self.n_head,

            self.d_k,

            self.d_v,

            self.dropout,

            self.ORT_weight,

            self.MIT_weight,

        )

模型的训练

class Transformer(BaseNNImputer):

    def __init__(

        self,

        n_steps,

        n_features,

        n_layers,

        d_model,

        d_inner,

        n_head,

        d_k,

        d_v,

        dropout,

        ORT_weight=1, 

        MIT_weight=1,

        learning_rate=3e-4,#3e-4, # 1e-3

        epochs=100,

        patience=10, 

        batch_size=32,

        weight_decay=1e-5,#1e-5,  #1e-5 best: 1e-4 

        device=None,

    ):

        super().__init__(

            learning_rate, epochs, patience, batch_size, weight_decay, device

        )



        self.n_steps = n_steps

        self.n_features = n_features

        # model hype-parameters

        self.n_layers = n_layers

        self.d_model = d_model

        self.d_inner = d_inner

        self.n_head = n_head

        self.d_k = d_k

        self.d_v = d_v

        self.dropout = dropout

        self.ORT_weight = ORT_weight

        self.MIT_weight = MIT_weight



        self.model = _TransformerEncoder(

            self.n_layers,

            self.n_steps,

            self.n_features,

            self.d_model,

            self.d_inner,

            self.n_head,

            self.d_k,

            self.d_v,

            self.dropout,

            self.ORT_weight,

            self.MIT_weight,

        )

        self.model = self.model.to(self.device)

        self._print_model_size()



    def fit(self, train_X,x_vectors,text_emb,labels, val_X=None):

        train_X = self.check_input(self.n_steps, self.n_features, train_X)

        if val_X is not None:

            val_X = self.check_input(self.n_steps, self.n_features, val_X)



        training_set = DatasetForMIT(train_X,x_vectors,text_emb,labels)

        training_loader = DataLoader(

            training_set, batch_size=self.batch_size, shuffle=True

        )

        if val_X is None:

            self._train_model(training_loader)

        else:

            val_X_intact, val_X, val_X_missing_mask, val_X_indicating_mask = mcar(

                val_X, 0.2

            )

            val_X = masked_fill(val_X, 1 - val_X_missing_mask, np.nan)

            val_set = DatasetForMIT(val_X)

            val_loader = DataLoader(val_set, batch_size=self.batch_size, shuffle=False)

            self._train_model(

                training_loader, val_loader, val_X_intact, val_X_indicating_mask

            ) #这行代码调用了一个名为_train_model的方法,并传入了training_loader作为参数
            #根据代码片段的上下文,可以推测_train_model方法是用来执行模型的训练操作的。
            #它接收一个数据加载器training_loader作为输入,该加载器提供了训练数据的批量样本。
            #具体的训练操作会在_train_model方法的实现中定义。
            



        self.model.load_state_dict(self.best_model_dict)  #这行代码使用load_state_dict方法加载了一个名为best_model_dict的状态字典到self.model中
        #状态字典包含了模型的参数和权重信息,通过加载状态字典,可以将模型的参数设置为保存的最佳模型的参数。
        #这样做的目的是恢复模型到训练过程中表现最好的状态,以便进行后续的评估或推理。

        self.model.eval()  # set the model as eval status to freeze it.
        #这行代码将模型的状态设置为评估状态,即执行eval()方法。
        #在评估状态下,模型的行为会发生变化,主要是为了冻结一些层和特定操作,以确保在推理或评估阶段不会影响模型的结果。例如,一些具有随机性的操作(如Dropout)可能会被关闭,以保持一致的输出。

        return self #返回self表示将训练好的模型对象作为方法的返回值。

关于模型的训练和评估方法

self.model.train()和self.model.eval()是深度学习模型中常用的方法,用于设置模型的训练和评估状态。

  • train()方法:调用train()方法将模型设置为训练状态。在训练状态下,模型会启用一些具有随机性的操作,如Dropout和Batch Normalization的更新。这些随机性操作有助于模型学习更好的泛化能力和防止过拟合。此外,训练状态下还会计算并更新模型的梯度,以进行参数的优化。
  • eval()方法:调用eval()方法将模型设置为评估状态。在评估状态下,模型会禁用一些具有随机性的操作,以确保模型的输出稳定和可重复。例如,Dropout操作会被关闭,Batch Normalization层会使用训练时的统计信息而不是实时计算的统计信息。这样可以保持一致的输出结果,在模型的推理、验证或测试阶段使用。

需要注意的是,train()和eval()方法通常用于PyTorch等深度学习框架中的模型对象。调用这些方法是为了设置模型的内部状态,以便根据当前的训练或评估阶段执行不同的操作。这样可以确保在不同的阶段下模型的行为一致,提高模型的稳定性和可复现性。

你可能感兴趣的:(transformer,深度学习,人工智能)