当前位置: 首页 > news >正文

简述网站建设方法wordpress忘记用户名

简述网站建设方法,wordpress忘记用户名,全国建设工程四库一平台,平面设计模板素材网站文章目录 引言项目结构一、代码结构解析1.1 训练流程控制 (main.py)1.2 PyTorch实现的CNN模型 (cnn_pytorch.py)1.3 自定义实现CNN模型 (cnn_custom.py) 二、关键算法细节剖析2.1 卷积操作2.2 自定义实现卷积层2.3 ReLU与池化2.4 全连接层 总结 引言 卷积神经网络 (Convolutio…

文章目录

    • 引言
    • 项目结构
    • 一、代码结构解析
      • 1.1 训练流程控制 (main.py)
      • 1.2 PyTorch实现的CNN模型 (cnn_pytorch.py)
      • 1.3 自定义实现CNN模型 (cnn_custom.py)
    • 二、关键算法细节剖析
      • 2.1 卷积操作
      • 2.2 自定义实现卷积层
      • 2.3 ReLU与池化
      • 2.4 全连接层
    • 总结

引言

卷积神经网络 (Convolutional Neural Network, CNN) 是图像识别和处理中的核心技术,特别在计算机视觉任务中广泛应用。本文通过在一个简单的图像分类任务中对比PyTorch实现自定义实现两种方案,解析CNN的关键技术细节。

项目结构

.
├── README.md
├── cnn_pytorch.py
├── cnn_custom.py
└── main.py

项目地址:https://github.com/tangpan360/cnn-from-scratch.git

一、代码结构解析

1.1 训练流程控制 (main.py)

# main.py
import torch
import torch.optim as optim
from cnn_pytorch import SimpleCNN  # 导入模型类
from cnn_custom import SimpleCNNCustom  # 导入自定义模型# 超参数设定
batch_size = 4  # 一次处理 4 张图片
channels = 2  # 2通道
height = 32  # 图片高度
width = 32  # 图片宽度
num_classes = 10  # 假设有 10 个分类
epochs = 10  # 训练轮数
learning_rate = 0.001  # 学习率# 生成一个随机数据集,模拟训练集
train_data = torch.randn(100, channels, height, width)
train_labels = torch.randint(0, num_classes, (100,))# 初始化 pytorch 模型
# model = SimpleCNN(num_classes=num_classes)
# 初始化自定义模型
model = SimpleCNNCustom(num_classes=num_classes)# 定义损失函数(交叉熵损失)
criterion = torch.nn.CrossEntropyLoss()# 选择优化器(Adam)
optimizer = optim.Adam(model.parameters(), lr=learning_rate)# 训练过程
for epoch in range(epochs):model.train()  # 切换到训练模式# 生成当前 batch 的数据inputs = train_datalabels = train_labels# 清空之前的梯度optimizer.zero_grad()# 前向传播outputs = model(inputs)# 计算损失loss = criterion(outputs, labels)# 反向传播loss.backward()# 更新模型参数optimizer.step()# 每个 epoch 打印一次损失print(f"Epoch [{epoch + 1}/{epochs}], Loss: {loss.item():.4f}")

1.2 PyTorch实现的CNN模型 (cnn_pytorch.py)

# cnn_pytorch.py
import torch
import torch.nn as nn# 定义包含两层卷积的 CNN 模型
class SimpleCNN(nn.Module):def __init__(self, num_classes=10):super(SimpleCNN, self).__init__()# 第一层卷积:2 通道 -> 16 通道,卷积核大小 3x3,步长 1,填充 1self.conv1 = nn.Conv2d(in_channels=2, out_channels=16, kernel_size=3, stride=1, padding=1)# 第二层卷积:16 通道 -> 32 通道,卷积核大小 3x3,步长 1,填充 1self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=1)self.relu = nn.ReLU()  # ReLU 激活函数self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  # 2x2 最大池化# 全连接层:将特征展平后,映射到 num_classes 类别self.fc1 = nn.Linear(32 * 8 * 8, num_classes)def forward(self, x):# 第一层卷积 -> ReLU -> 池化x = self.conv1(x)x = self.relu(x)x = self.pool(x)# 第二层卷积 -> ReLU -> 池化x = self.conv2(x)x = self.relu(x)x = self.pool(x)# 展平x = torch.flatten(x, start_dim=1)# 全连接层x = self.fc1(x)return x

1.3 自定义实现CNN模型 (cnn_custom.py)

# cnn_custom.py
import torch
import torch.nn as nn
import torch.nn.functional as F# 手动实现卷积操作
class Conv2dCustom(nn.Module):def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):super(Conv2dCustom, self).__init__()# 卷积核的初始化使用 Xavier 均匀分布self.weight = nn.Parameter(torch.randn(out_channels, in_channels, kernel_size, kernel_size))  # 初始化为随机值nn.init.xavier_uniform_(self.weight)  # 使用 Xavier 均匀分布初始化权重self.bias = nn.Parameter(torch.zeros(out_channels))  # 偏置初始化为零self.stride = strideself.padding = paddingdef forward(self, x):# 输入的维度是 (batch_size, in_channels, height, width)batch_size, in_channels, height, width = x.size()# 计算输出的尺寸kernel_size = self.weight.size(2)out_height = (height + 2 * self.padding - kernel_size) // self.stride + 1out_width = (width + 2 * self.padding - kernel_size) // self.stride + 1# 扩展输入 x 到与卷积核对齐的形式x_padded = F.pad(x, (self.padding, self.padding, self.padding, self.padding))# 进行卷积计算out = torch.zeros(batch_size, self.weight.size(0), out_height, out_width).to(x.device)for i in range(out_height):for j in range(out_width):# 获取当前卷积窗口h_start = i * self.strideh_end = h_start + kernel_sizew_start = j * self.stridew_end = w_start + kernel_size# 提取当前窗口的数据x_slice = x_padded[:, :, h_start:h_end, w_start:w_end]  # shape: (batch_size, in_channels, kernel_size, kernel_size)# 调整 x_slice 和 self.weight 的形状以便广播x_slice = x_slice.unsqueeze(1)  # shape: (batch_size, 1, in_channels, kernel_size, kernel_size)weight = self.weight.unsqueeze(0)  # shape: (1, out_channels, in_channels, kernel_size, kernel_size)# 计算卷积结果element_wise = x_slice * weight  # 逐元素相乘conv_result = element_wise.sum(dim=(2, 3, 4))  # 在指定维度求和out[:, :, i, j] = conv_result + self.biasreturn out# 自定义 ReLU 激活函数
class ReLUCustom(nn.Module):def forward(self, x):result = torch.max(x, torch.tensor(0.0).to(x.device))return result# 自定义最大池化层
class MaxPool2dCustom(nn.Module):def __init__(self, kernel_size, stride=None, padding=0):super(MaxPool2dCustom, self).__init__()self.kernel_size = kernel_sizeself.stride = stride if stride is not None else kernel_sizeself.padding = paddingdef forward(self, x):batch_size, in_channels, height, width = x.size()# 计算输出的尺寸out_height = (height + 2 * self.padding - self.kernel_size) // self.stride + 1out_width = (width + 2 * self.padding - self.kernel_size) // self.stride + 1# 对输入进行 paddingx_padded = F.pad(x, (self.padding, self.padding, self.padding, self.padding))# 最大池化操作out = torch.zeros(batch_size, in_channels, out_height, out_width).to(x.device)for i in range(out_height):for j in range(out_width):# 计算窗口的起始和结束位置h_start = i * self.strideh_end = h_start + self.kernel_sizew_start = j * self.stridew_end = w_start + self.kernel_size# 提取当前窗口的数据x_slice = x_padded[:, :, h_start:h_end, w_start:w_end]# 对窗口进行最大池化max_values = x_slice.amax(dim=(2, 3))out[:, :, i, j] = max_valuesreturn out# 自定义全连接层
class LinearCustom(nn.Module):def __init__(self, in_features, out_features):super(LinearCustom, self).__init__()# 使用 Kaiming 初始化权重,适用于 ReLU 激活函数self.weight = nn.Parameter(torch.empty(in_features, out_features))nn.init.kaiming_normal_(self.weight, mode='fan_out', nonlinearity='relu')# 初始化偏置为 0self.bias = nn.Parameter(torch.zeros(out_features))def forward(self, x):# 将输入展平x = x.view(x.size(0), -1)# 计算线性变换结果output = torch.matmul(x, self.weight) + self.biasreturn output# 定义自定义 CNN 模型
class SimpleCNNCustom(nn.Module):def __init__(self, num_classes=10):super(SimpleCNNCustom, self).__init__()# 第一层卷积self.conv1 = Conv2dCustom(in_channels=2, out_channels=16, kernel_size=3, padding=1)# 第二层卷积self.conv2 = Conv2dCustom(in_channels=16, out_channels=32, kernel_size=3, padding=1)# 激活函数self.relu = ReLUCustom()# 最大池化self.pool = MaxPool2dCustom(kernel_size=2, stride=2)# 全连接层self.fc1 = LinearCustom(32 * 8 * 8, num_classes)def forward(self, x):# 第一层卷积 -> 激活 -> 池化x = self.conv1(x)x = self.relu(x)x = self.pool(x)# 第二层卷积 -> 激活 -> 池化x = self.conv2(x)x = self.relu(x)x = self.pool(x)# 展平x = x.view(x.size(0), -1)# 全连接层x = self.fc1(x)return x

二、关键算法细节剖析

2.1 卷积操作

卷积操作通过滑动卷积核进行局部特征的提取,图像的每个区域与卷积核进行点乘,并通过步长和填充控制卷积的输出尺寸。

2.2 自定义实现卷积层

我们手动实现了卷积层 Conv2dCustom,它通过对输入图像进行切片和点乘操作模拟了传统的卷积操作。此外,我们还实现了自定义的激活函数和池化层,用于更好地理解底层实现。

2.3 ReLU与池化

我们使用了自定义的 ReLU 激活函数 ReLUCustom 和池化层 MaxPool2dCustom,其中池化操作用于降低特征图的空间尺寸,同时保留重要的空间信息。

2.4 全连接层

全连接层用于将卷积层提取到的特征映射到最终的类别空间,确保每个特征都对分类决策产生影响。

总结

通过对比 PyTorch 实现与自定义实现的 CNN 模型,我们能够更好地理解 CNN 的各个构成部分。自定义实现展示了如何从零开始构建卷积神经网络并理解其中的关键操作,而 PyTorch 提供了高度优化的卷积层,可以快速构建高效的模型。

http://www.dtcms.com/a/409586.html

相关文章:

  • 西安免费做网站电话wordpress导航跟随
  • 网站管理过程2 如何写一份详细的网站开发方案
  • 网站域名和备案公司可以不一样么建筑人才网简历
  • 景区网站建设材料用宝塔给远程网站做备份
  • 门源县电子商务网站建设公司运营推广公司
  • 网站所有权问题正规网络推广服务
  • 国内网站建设深圳短视频seo搜索排名如何做
  • 基层档案网站建设北京市建筑信息公开平台
  • 自己做网站还能挣钱吗湛江企业网站建设
  • 网站建设公司哪里找学校网站改版
  • 东莞公司网站制作要多少钱北极鱼wordpress
  • wordpress查询成绩seo泛站群
  • 南京网站开发联系南京乐识163邮箱官方注册入口
  • 网站做海外的防护广州网络公司有哪些
  • 环保主题的网站模板网站安全需做哪些监测
  • 网站开发需会的课程wordpress转typecho插件
  • 大型门户网站建设的意义织梦免费机械网站源码
  • 站长百科 wordpress免费网站模板 php
  • 英文网站 icp备案号可信网站认证代理
  • 一个app网站聊城做手机网站
  • 威海网站建设公司哪家好114网站制作
  • 临沧网站搭建学网络营销好就业吗
  • 河北唐山 网站建设wordpress 个人资料页
  • 做网站和APP需要多少钱钢筋网片规格型号
  • 淘宝网现状 网站建设系统设置友情链接有什么作用
  • 连云港建设网站公司wordpress 自定义字段 调用
  • 秦皇岛做网站优化价格网站app用什么语言开发的
  • 男女做污视频网站大连开发区招聘网站
  • 江苏省住房和建设厅网站wordpress同时登录
  • 一级a做爰电影片免费网站可以做链接的网站