|
- import torch
- import torch.nn as nn
- import torch.nn.functional as F
- # 设置随机种子确保可重复性
- torch.manual_seed(42)
- class SimpleCNN(nn.Module):
- def __init__(self):
- super(SimpleCNN, self).__init__()
- # 手动初始化卷积层参数
- self.conv1 = nn.Conv2d(1, 2, kernel_size=2, stride=2, bias=True)
- self.conv1.weight.data = torch.tensor([
- [[[0.1, 0.2], [0.3, 0.4]]], # 第一个滤波器
- [[[0.5, 0.6], [0.7, 0.8]]] # 第二个滤波器
- ], dtype=torch.float32)
- self.conv1.bias.data = torch.tensor([0.1, 0.2], dtype=torch.float32)
-
- # 手动初始化全连接层参数
- self.fc = nn.Linear(2, 3, bias=True)
- self.fc.weight.data = torch.tensor([[0.1, 0.2],
- [0.3, 0.4],
- [0.5, 0.6]], dtype=torch.float32)
- self.fc.bias.data = torch.tensor([0.1, 0.2, 0.3], dtype=torch.float32)
-
- def forward(self, x):
- # 卷积层
- conv_out = self.conv1(x)
- print(f"1. 卷积层输出: {conv_out.detach().squeeze().numpy().round(4)}")
-
- # ReLU激活
- relu_out = F.relu(conv_out)
- print(f"2. ReLU激活输出: {relu_out.detach().squeeze().numpy().round(4)}")
-
- # 展平特征图
- flattened = relu_out.view(relu_out.size(0), -1)
-
- # 全连接层
- fc_out = self.fc(flattened)
- print(f"3. 全连接层输出: {fc_out.detach().squeeze().numpy().round(4)}")
-
- return fc_out
- # 创建模型
- model = SimpleCNN()
- # 输入数据 (batch_size=1, channels=1, height=2, width=2)
- x = torch.tensor([[[[1.0, 0.0],
- [0.0, 1.0]]]])
- # 真实标签 (类别索引为2)
- y = torch.tensor([1])
- for i in range(20):
- # 前向传播
- print("================= 前向传播 =================!!!!!!!!!!!!!!!!!!!!")
- output = model(x)
- # 计算损失 (交叉熵损失)
- criterion = nn.CrossEntropyLoss()
- loss = criterion(output, y)
- # 计算softmax概率
- probs = F.softmax(output, dim=1)
- print(f"4. Softmax概率: {probs.detach().squeeze().numpy().round(4)}")
- print(f"5. 损失值: {loss.item():.4f}")
- # 反向传播
- print("\n================= 反向传播 =================")
- model.zero_grad()
- loss.backward()
- # 打印梯度
- print("6. 卷积层权重梯度:")
- print(model.conv1.weight.grad.detach().squeeze().numpy().round(4))
- print("卷积层偏置梯度:", model.conv1.bias.grad.detach().numpy().round(4))
- print("\n7. 全连接层权重梯度:")
- print(model.fc.weight.grad.detach().numpy().round(4))
- print("全连接层偏置梯度:", model.fc.bias.grad.detach().numpy().round(4))
- # 参数更新 (学习率0.1)
- print("\n================= 参数更新 (学习率0.1) =================")
- with torch.no_grad():
- # 更新卷积层参数
- model.conv1.weight -= 0.1 * model.conv1.weight.grad
- model.conv1.bias -= 0.1 * model.conv1.bias.grad
-
- # 更新全连接层参数
- model.fc.weight -= 0.1 * model.fc.weight.grad
- model.fc.bias -= 0.1 * model.fc.bias.grad
- print("8. 更新后的卷积层权重:")
- print(model.conv1.weight.detach().squeeze().numpy().round(4))
- print("更新后的卷积层偏置:", model.conv1.bias.detach().numpy().round(4))
- print("\n9. 更新后的全连接层权重:")
- print(model.fc.weight.detach().numpy().round(4))
- print("更新后的全连接层偏置:", model.fc.bias.detach().numpy().round(4))
- print("================= 前向传播 =================")
- output = model(x)
复制代码 |
|