MedGemma 1.5作品分享:基于MedQA数据集的top-k答案置信度可视化分析

核心内容摘要

Matting(抠图)开源模型与数据集全解析:从理论到实践
番茄小说下载器技术解析与应用指南

大规模语言模型在跨学科科学推理中的突破

浙大疏锦行知识点回顾

回调函数# 定义一个回调函数 def handle_result(result): 处理计算结果的回调函数 print(f计算结果是: {result}) # 定义一个接受回调函数的函数 def calculate(a, b, callback): # callback是一个约定俗成的参数名 这个函数接受两个数值和一个回调函数用于处理计算结果。

执行计算并调用回调函数 result a b callback(result) # 在计算完成后调用回调函数 # 使用回调函数 calculate(3, 5, handle_result) # 输出: 计算结果是:

lambda 函数# 定义匿名函数计算平方 square lambda x: x ** 2 # 调用 print(square(

) # 输出:

hook 函数的模块钩子和张量钩子import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt # 设置随机种子保证结果可复现 torch.manual_seed(

np.random.seed(

import torch import torch.nn as nn # 定义一个简单的卷积神经网络模型 class SimpleModel(nn.Module): def __init__(self): super(SimpleModel, self).__init__() # 定义卷积层输入通道1输出通道2卷积核3x3填充1保持尺寸不变 self.conv nn.Conv2d(1, 2, kernel_size3, padding

# 定义ReLU激活函数 self.relu nn.ReLU() # 定义全连接层输入特征2*4*4输出10分类 self.fc nn.Linear(2 * 4 * 4,

def forward(self, x): # 卷积操作 x self.conv(x) # 激活函数 x self.relu(x) # 展平为一维向量准备输入全连接层 x x.view(-1, 2 * 4 *

# 全连接分类 x self.fc(x) return x # 创建模型实例 model SimpleModel() # 创建一个列表用于存储中间层的输出 conv_outputs [] # 定义前向钩子函数 - 用于在模型前向传播过程中获取中间层信息 def forward_hook(module, input, output): 前向钩子函数会在模块每次执行前向传播后被自动调用 参数: module: 当前应用钩子的模块实例 input: 传递给该模块的输入张量元组 output: 该模块产生的输出张量 print(f钩子被调用模块类型: {type(module)}) print(f输入形状: {input[0].shape}) # input是一个元组对应 (image, label) print(f输出形状: {output.shape}) # 保存卷积层的输出用于后续分析 # 使用detach()避免追踪梯度防止内存泄漏 conv_outputs.append(output.detach()) # 在卷积层注册前向钩子 # register_forward_hook返回一个句柄用于后续移除钩子 hook_handle model.conv.register_forward_hook(forward_hook) # 创建一个随机输入张量 (批次大小1, 通道1, 高度4, 宽度

x torch.randn(1, 1, 4,

# 执行前向传播 - 此时会自动触发钩子函数 output model(x) # 释放钩子 - 重要防止在后续模型使用中持续调用钩子造成意外行为或内存泄漏 hook_handle.remove() # # 打印中间层输出结果 # if conv_outputs: # print(f\n卷积层输出形状: {conv_outputs[0].shape}) # print(f卷积层输出值示例: {conv_outputs[0][0, 0, :, :]}) # 定义一个存储梯度的列表 conv_gradients [] # 定义反向钩子函数 def backward_hook(module, grad_input, grad_output): # 模块当前应用钩子的模块 # grad_input模块输入的梯度 # grad_output模块输出的梯度 print(f反向钩子被调用模块类型: {type(module)}) print(f输入梯度数量: {len(grad_input)}) print(f输出梯度数量: {len(grad_output)}) # 保存梯度供后续分析 conv_gradients.append((grad_input, grad_output)) # 在卷积层注册反向钩子 hook_handle model.conv.register_backward_hook(backward_hook) # 创建一个随机输入并进行前向传播 x torch.randn(1, 1, 4, 4, requires_gradTrue) output model(x) # 定义一个简单的损失函数并进行反向传播 loss output.sum() loss.backward() # 释放钩子 hook_handle.remove()

Grad-CAM 的示例import torch import torch.nn as nn import torch.nn.functional as F import torchvision import torchvision.transforms as transforms import numpy as np import matplotlib.pyplot as plt from PIL import Image # 设置随机种子确保结果可复现 # 在深度学习中随机种子可以让每次运行代码时模型初始化参数、数据打乱等随机操作保持一致方便调试和对比实验结果 torch.manual_seed(

np.random.seed(

# 加载CIFAR-10数据集 # 定义数据预处理步骤先将图像转换为张量再进行归一化操作 # 归一化的均值和标准差是(

5,

5,

0.

这里的均值和标准差是对CIFAR-10数据集的经验值使得数据分布更有利于模型训练 transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((

5,

5,

0.

, (

5,

5,

0.

) ]) # 加载测试集指定数据集根目录为./data设置为测试集trainFalse如果数据不存在则下载downloadTrue并应用上述定义的预处理 testset torchvision.datasets.CIFAR10( root./data, trainFalse, downloadTrue, transformtransform ) # 定义类别名称CIFAR-10数据集包含这10个类别 classes (飞机, 汽车, 鸟, 猫, 鹿, 狗, 青蛙, 马, 船, 卡车) # 定义一个简单的CNN模型 class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() # 第一个卷积层输入通道为3彩色图像输出通道为32卷积核大小为3x3填充为1以保持图像尺寸不变 self.conv1 nn.Conv2d(3, 32, kernel_size3, padding

# 第二个卷积层输入通道为32输出通道为64卷积核大小为3x3填充为1 self.conv2 nn.Conv2d(32, 64, kernel_size3, padding

# 第三个卷积层输入通道为64输出通道为128卷积核大小为3x3填充为1 self.conv3 nn.Conv2d(64, 128, kernel_size3, padding

# 最大池化层池化核大小为2x2步长为2用于下采样减少数据量并提取主要特征 self.pool nn.MaxPool2d(2,

# 第一个全连接层输入特征数为128 * 4 * 4经过前面卷积和池化后的特征维度输出为512 self.fc1 nn.Linear(128 * 4 * 4,

# 第二个全连接层输入为512输出为10对应CIFAR-10的10个类别 self.fc2 nn.Linear(512,

def forward(self, x): # 第一个卷积层后接ReLU激活函数和最大池化操作经过池化后图像尺寸变为原来的一半这里输出尺寸变为16x16 x self.pool(F.relu(self.conv1(x))) # 第二个卷积层后接ReLU激活函数和最大池化操作输出尺寸变为8x8 x self.pool(F.relu(self.conv2(x))) # 第三个卷积层后接ReLU激活函数和最大池化操作输出尺寸变为4x4 x self.pool(F.relu(self.conv3(x))) # 将特征图展平为一维向量以便输入到全连接层 x x.view(-1, 128 * 4 *

# 第一个全连接层后接ReLU激活函数 x F.relu(self.fc1(x)) # 第二个全连接层输出分类结果 x self.fc2(x) return x # 初始化模型 model SimpleCNN() print(模型已创建) # 如果有GPU则使用GPU将模型转移到对应的设备上 device torch.device(cuda:0 if torch.cuda.is_available() else cpu) model model.to(device) # 训练模型简化版实际应用中应该进行完整训练 def train_model(model, epochs

: # 加载训练集指定数据集根目录为./data设置为训练集trainTrue如果数据不存在则下载downloadTrue并应用前面定义的预处理 trainset torchvision.datasets.CIFAR10( root./data, trainTrue, downloadTrue, transformtransform ) # 创建数据加载器设置批量大小为64打乱数据顺序shuffleTrue使用2个线程加载数据 trainloader torch.utils.data.DataLoader( trainset, batch_size64, shuffleTrue, num_workers2 ) # 定义损失函数为交叉熵损失用于分类任务 criterion nn.CrossEntropyLoss() # 定义优化器为Adam用于更新模型参数学习率设置为

001 optimizer torch.optim.Adam(model.parameters(), lr

0.

for epoch in range(epochs): running_loss

0 for i, data in enumerate(trainloader,

: # 从数据加载器中获取图像和标签 inputs, labels data # 将图像和标签转移到对应的设备GPU或CPU上 inputs, labels inputs.to(device), labels.to(device) # 清空梯度避免梯度累加 optimizer.zero_grad() # 模型前向传播得到输出 outputs model(inputs) # 计算损失 loss criterion(outputs, labels) # 反向传播计算梯度 loss.backward() # 更新模型参数 optimizer.step() running_loss loss.item() if i % 100 99: # 每100个批次打印一次平均损失 print(f[{epoch 1}, {i 1}] 损失: {running_loss / 100:.3f}) running_loss

0 print(训练完成) # 训练模型可选如果有预训练模型可以加载 # 取消下面这行的注释来训练模型 # train_model(model, epochs

# 或者尝试加载预训练模型如果存在 try: # 尝试加载名为cifar10_cnn.pth的模型参数 model.load_state_dict(torch.load(cifar10_cnn.pth)) print(已加载预训练模型) except: print(无法加载预训练模型使用未训练模型或训练新模型) # 如果没有预训练模型可以在这里调用train_model函数 train_model(model, epochs

# 保存训练后的模型参数 torch.save(model.state_dict(), cifar10_cnn.pth) # 设置模型为评估模式此时模型中的一些操作如dropout、batchnorm等会切换到评估状态 model.eval() # Grad-CAM实现 class GradCAM: def __init__(self, model, target_layer): self.model model self.target_layer target_layer self.gradients None self.activations None # 注册钩子用于获取目标层的前向传播输出和反向传播梯度 self.register_hooks() def register_hooks(self): # 前向钩子函数在目标层前向传播后被调用保存目标层的输出激活值 def forward_hook(module, input, output): self.activations output.detach() # 反向钩子函数在目标层反向传播后被调用保存目标层的梯度 def backward_hook(module, grad_input, grad_output): self.gradients grad_output[0].detach() # 在目标层注册前向钩子和反向钩子 self.target_layer.register_forward_hook(forward_hook) self.target_layer.register_backward_hook(backward_hook) def generate_cam(self, input_image, target_classNone): # 前向传播得到模型输出 model_output self.model(input_image) if target_class is None: # 如果未指定目标类别则取模型预测概率最大的类别作为目标类别 target_class torch.argmax(model_output, dim

.item() # 清除模型梯度避免之前的梯度影响 self.model.zero_grad() # 反向传播构造one-hot向量使得目标类别对应的梯度为1其余为0然后进行反向传播计算梯度 one_hot torch.zeros_like(model_output) one_hot[0, target_class] 1 model_output.backward(gradientone_hot) # 获取之前保存的目标层的梯度和激活值 gradients self.gradients activations self.activations # 对梯度进行全局平均池化得到每个通道的权重用于衡量每个通道的重要性 weights torch.mean(gradients, dim(2,

, keepdimTrue) # 加权激活映射将权重与激活值相乘并求和得到类激活映射的初步结果 cam torch.sum(weights * activations, dim1, keepdimTrue) # ReLU激活只保留对目标类别有正贡献的区域去除负贡献的影响 cam F.relu(cam) # 调整大小并归一化将类激活映射调整为与输入图像相同的尺寸32x32并归一化到[0, 1]范围 cam F.interpolate(cam, size(32,

, modebilinear, align_cornersFalse) cam cam - cam.min() cam cam / cam.max() if cam.max() 0 else cam return cam.cpu().squeeze().numpy(), target_class

九.幺.9.1.-九.幺应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123