2024年7月9日~2024年7月15日周报

目录

一、前言

二、完成情况

2.1 特征图保存方法

2.1.1 定义网络模型

2.1.2 定义保存特征图的钩子函数

2.1.3 为模型层注册钩子

2.1.4 运行模型并检查特征图

2.2 实验情况

三、下周计划


一、前言

        本周的7月11日~7月14日参加了机器培训的学习讨论会,对很多概念有了更深的理解。同时,在空闲时间利用笔记本跑了小批量的数据。

二、完成情况

2.1 特征图保存方法

        在深度学习领域,在网络训练过程中生成每一阶段的特征图是一个常见的需求。

2.1.1 定义网络模型

        首先,需要确定我们当前使用的网络模型,不同的模型结果具有不同的层数和层类型,这将影响特征图的生成。

        这里以InversionNet为例:

class InversionNet(nn.Module):
    def __init__(self, dim1=32, dim2=64, dim3=128, dim4=256, dim5=512, sample_spatial=1.0, **kwargs):
        super(InversionNet, self).__init__()
        self.convblock1 = ConvBlock(5, dim1, kernel_size=(7, 1), stride=(2, 1), padding=(3, 0))
        self.convblock2_1 = ConvBlock(dim1, dim2, kernel_size=(3, 1), stride=(2, 1), padding=(1, 0))
        self.convblock2_2 = ConvBlock(dim2, dim2, kernel_size=(3, 1), padding=(1, 0))
        self.convblock3_1 = ConvBlock(dim2, dim2, kernel_size=(3, 1), stride=(2, 1), padding=(1, 0))
        self.convblock3_2 = ConvBlock(dim2, dim2, kernel_size=(3, 1), padding=(1, 0))
        self.convblock4_1 = ConvBlock(dim2, dim3, kernel_size=(3, 1), stride=(2, 1), padding=(1, 0))
        self.convblock4_2 = ConvBlock(dim3, dim3, kernel_size=(3, 1), padding=(1, 0))
        self.convblock5_1 = ConvBlock(dim3, dim3, stride=2)
        self.convblock5_2 = ConvBlock(dim3, dim3)
        self.convblock6_1 = ConvBlock(dim3, dim4, stride=2)
        self.convblock6_2 = ConvBlock(dim4, dim4)
        self.convblock7_1 = ConvBlock(dim4, dim4, stride=2)
        self.convblock7_2 = ConvBlock(dim4, dim4)
        self.convblock8 = ConvBlock(dim4, dim5, kernel_size=(8, ceil(70 * sample_spatial / 8)), padding=0)

        self.deconv1_1 = DeconvBlock(dim5, dim5, kernel_size=5)
        self.deconv1_2 = ConvBlock(dim5, dim5)
        self.deconv2_1 = DeconvBlock(dim5, dim4, kernel_size=4, stride=2, padding=1)
        self.deconv2_2 = ConvBlock(dim4, dim4)
        self.deconv3_1 = DeconvBlock(dim4, dim3, kernel_size=4, stride=2, padding=1)
        self.deconv3_2 = ConvBlock(dim3, dim3)
        self.deconv4_1 = DeconvBlock(dim3, dim2, kernel_size=4, stride=2, padding=1)
        self.deconv4_2 = ConvBlock(dim2, dim2)
        self.deconv5_1 = DeconvBlock(dim2, dim1, kernel_size=4, stride=2, padding=1)
        self.deconv5_2 = ConvBlock(dim1, dim1)
        self.deconv6 = ConvBlock_Tanh(dim1, 1)

    def forward(self, x):
        # Encoder Part
        x = self.convblock1(x)  # (None, 32, 500, 70)
        x = self.convblock2_1(x)  # (None, 64, 250, 70)
        x = self.convblock2_2(x)  # (None, 64, 250, 70)
        x = self.convblock3_1(x)  # (None, 64, 125, 70)
        x = self.convblock3_2(x)  # (None, 64, 125, 70)
        x = self.convblock4_1(x)  # (None, 128, 63, 70)
        x = self.convblock4_2(x)  # (None, 128, 63, 70)
        x = self.convblock5_1(x)  # (None, 128, 32, 35)
        x = self.convblock5_2(x)  # (None, 128, 32, 35)
        x = self.convblock6_1(x)  # (None, 256, 16, 18)
        x = self.convblock6_2(x)  # (None, 256, 16, 18)
        x = self.convblock7_1(x)  # (None, 256, 8, 9)
        x = self.convblock7_2(x)  # (None, 256, 8, 9)
        x = self.convblock8(x)  # (None, 512, 1, 1)

        # Decoder Part Vmodel
        x = self.deconv1_1(x)  # (None, 512, 5, 5)
        x = self.deconv1_2(x)  # (None, 512, 5, 5)
        x = self.deconv2_1(x)  # (None, 256, 10, 10)
        x = self.deconv2_2(x)  # (None, 256, 10, 10)
        x = self.deconv3_1(x)  # (None, 128, 20, 20)
        x = self.deconv3_2(x)  # (None, 128, 20, 20)
        x = self.deconv4_1(x)  # (None, 64, 40, 40)
        x = self.deconv4_2(x)  # (None, 64, 40, 40)
        x = self.deconv5_1(x)  # (None, 32, 80, 80)
        x = self.deconv5_2(x)  # (None, 32, 80, 80)
        x = F.pad(x, [-5, -5, -5, -5], mode="constant", value=0)  # (None, 32, 70, 70) 125, 100
        x = self.deconv6(x)  # (None, 1, 70, 70)

        return x

2.1.2 定义保存特征图的钩子函数

        接下来,定义特征图保存函数。PyTorch提供了register_forward_hook方法,允许在模型的特定层上注册一个回调函数,该函数将在该层的前向传播之后被调用。因此,我们可以利用这个机制来自动保存每个阶段的特征图。钩子方法(hook method)是回调函数(callback function)的一种,它相当于一个监测器,在消息传递的过程中,捕获自己感兴趣的内容,然后去处理。

import torch  
  
# 全局的字典用于存储特征图  
feature_maps = {}  
  
def save_feature_map(module, input, output):  
    # 'module' 是注册了钩子的模块(在这里以一个convblock为例)  
    # 'input' 是该模块的输入  
    # 'output' 是该模块的输出,即我们要保存的特征图  
    # 我们需要一种方式来唯一标识每个convblock,这里我们简单地使用模块的名称  
    key = module.__class__.__name__ if hasattr(module, '__class__') else type(module).__name__  
    if key.startswith('ConvBlock'):  # 假设所有convblock类的名称都以'ConvBlock'开头  
        feature_maps[key] = output.detach().cpu()  # 保存特征图到CPU  
  
# 注意:上面的key获取方式是基于假设的,需要根据实际的convblock类名来调整

2.1.3 为模型层注册钩子

        然后,需要再模型初始化初始化或某个适当的地方,为这些convblock注册钩子。这里为所有的convblock层注册钩子,也可以单独注册。

# 一个方法来注册所有ConvBlock的钩子
def register_ConvBlock_hooks(self):
    for name, module in self._modules.items():
        if isinstance(module, convblock):
            handle = module.register_forward_hook(self.save_feature_map)
            self.hook_handles.append((name, handle))

2.1.4 运行模型并检查特征图

        在训练循环中,除了正常的梯度计算和参数更新外,还需要确保特征图保存机制被正确触发。在每个epoch或每个batch之后,根据需求保存特征图。

def save_feature_map(self, module, input, output):
    # 打印输出尺寸作为示例
    print(f"Feature map shape from {module._get_name()}: {output.shape}")
    # 假设我们想要保存第一个批次和第一个通道的特征图
    batch_idx, channel_idx = 0, 0

    # 提取特征图的一个批次和一个通道
    feature_map = output[batch_idx, channel_idx, :, :]

    # 将tensor从GPU(如果有)移动到CPU,并转换为numpy数组
    feature_map_np = feature_map.detach().cpu().numpy()

    # 归一化特征图到[0, 1]
    feature_map_np = (feature_map_np - feature_map_np.min()) / (feature_map_np.max() - feature_map_np.min())

    # 使用PIL或其他库保存图像
    # 由于PIL期望的是[0, 255]的整数,需要将归一化后的图像乘以255并转换为uint8
    image = Image.fromarray((feature_map_np * 255).astype(np.uint8))

    # 为模块创建一个唯一的名称(这里只是示例)
    module_name = module.__class__.__name__ + "_" + str(id(module))

    # 保存图像
    image_path = f"{module_name}_feature_map.png"
    image.save(image_path)
    print(f"Saved feature map to {image_path}")

         目前只能生成灰度图像,在生成彩色图片时遇到问题,报错如下所示,下周解决该问题。 

2.2 实验情况

        在本周对设计的实验进行了验证,在验证过程中发现选择合适的学习率很重要,指标相差也很大。

        目前的网络结构效果在5000的 CurveFaultA 数据集上优于InversionNet,但是不知道大数据集上表现如何。

        损失函数的表现在小数据集上不太明显,部分指标较好,但是部分指标不好。

三、下周计划

  1. 利用工作站完成实验;

  2. 验证特征图保存方法是否适用;

  3. 了解高级优化算法;

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值