怎么建网站自己做赌场,h5开发是做什么,怎么在vk网站上做推广,郑州做网站云极目录 1.ResNet残差网络
1.1 ResNet定义 1.2 ResNet 几种网络配置 1.3 ResNet50网络结构
1.3.1 前几层卷积和池化
1.3.2 残差块#xff1a;构建深度残差网络
1.3.3 ResNet主体#xff1a;堆叠多个残差块
1.4 迁移学习猫狗二分类实战
1.4.1 迁移学习
1.4.2 模型训练
1.…目录 1.ResNet残差网络
1.1 ResNet定义 1.2 ResNet 几种网络配置 1.3 ResNet50网络结构
1.3.1 前几层卷积和池化
1.3.2 残差块构建深度残差网络
1.3.3 ResNet主体堆叠多个残差块
1.4 迁移学习猫狗二分类实战
1.4.1 迁移学习
1.4.2 模型训练
1.4.3 模型预测 1.ResNet残差网络
1.1 ResNet定义
深度学习在图像分类、目标检测、语音识别等领域取得了重大突破但是随着网络层数的增加梯度消失和梯度爆炸问题逐渐凸显。随着层数的增加梯度信息在反向传播过程中逐渐变小导致网络难以收敛。同时梯度爆炸问题也会导致网络的参数更新过大无法正常收敛。
为了解决这些问题ResNet提出了一个创新的思路引入残差块Residual Block。残差块的设计允许网络学习残差映射从而减轻了梯度消失问题使得网络更容易训练。
下图是一个基本残差块。它的操作是把某层输入跳跃连接到下一层乃至更深层的激活层之前同本层输出一起经过激活函数输出。 1.2 ResNet 几种网络配置
如下图 1.3 ResNet50网络结构
ResNet-50是一个具有50个卷积层的深度残差网络。它的网络结构非常复杂但我们可以将其分为以下几个模块
1.3.1 前几层卷积和池化
import torch
import torch.nn as nnclass ResNet50(nn.Module):def __init__(self, num_classes1000):super(ResNet50, self).__init__()self.conv1 nn.Conv2d(in_channels3, out_channels64, kernel_size7, stride2, padding3, biasFalse)self.bn1 nn.BatchNorm2d(64)self.relu nn.ReLU(inplaceTrue)self.maxpool nn.MaxPool2d(kernel_size3, stride2, padding1)1.3.2 残差块构建深度残差网络
class ResidualBlock(nn.Module):def __init__(self, in_channels, out_channels, stride1, downsampleNone):super(ResidualBlock, self).__init__()self.conv1 nn.Conv2d(in_channels, out_channels, kernel_size1, stridestride, biasFalse)self.bn1 nn.BatchNorm2d(out_channels)self.conv2 nn.Conv2d(out_channels, out_channels, kernel_size3, stride1, padding1, biasFalse)self.bn2 nn.BatchNorm2d(out_channels)self.conv3 nn.Conv2d(out_channels, out_channels * 4, kernel_size1, stride1, biasFalse)self.bn3 nn.BatchNorm2d(out_channels * 4)self.relu nn.ReLU(inplaceTrue)self.downsample downsampledef forward(self, x):identity xout self.conv1(x)out self.bn1(out)out self.relu(out)out self.conv2(out)out self.bn2(out)out self.relu(out)out self.conv3(out)out self.bn3(out)if self.downsample is not None:identity self.downsample(x)out identityout self.relu(out)return out1.3.3 ResNet主体堆叠多个残差块
在ResNet-50中我们堆叠了多个残差块来构建整个网络。每个残差块会将输入的特征图进行处理并输出更加丰富的特征图。堆叠多个残差块允许网络在深度方向上进行信息的层层提取从而获得更高级的语义信息。代码如下
class ResNet50(nn.Module):def __init__(self, num_classes1000):# ... 前几层代码 ...# 4个残差块的block1self.layer1 self._make_layer(ResidualBlock, 64, 3, stride1)# 4个残差块的block2self.layer2 self._make_layer(ResidualBlock, 128, 4, stride2)# 4个残差块的block3self.layer3 self._make_layer(ResidualBlock, 256, 6, stride2)# 4个残差块的block4self.layer4 self._make_layer(ResidualBlock, 512, 3, stride2)利用make_layer函数实现对基本残差块Bottleneck的堆叠。代码如下
def _make_layer(self, block, channel, block_num, stride1):block: 堆叠的基本模块channel: 每个stage中堆叠模块的第一个卷积的卷积核个数对resnet50分别是:64,128,256,512block_num: 当期stage堆叠block个数stride: 默认卷积步长downsample None # 用于控制shorcut路的if stride ! 1 or self.in_channel ! channel*block.expansion: # 对resnet50conv2中特征图尺寸H,W不需要下采样/2但是通道数x4因此shortcut通道数也需要x4。对其余conv3,4,5既要特征图尺寸H,W/2又要shortcut维度x4downsample nn.Sequential(nn.Conv2d(in_channelsself.in_channel, out_channelschannel*block.expansion, kernel_size1, stridestride, biasFalse), # out_channels决定输出通道数x4stride决定特征图尺寸H,W/2nn.BatchNorm2d(num_featureschannel*block.expansion))layers [] # 每一个convi_x的结构保存在一个layers列表中i{2,3,4,5}layers.append(block(in_channelself.in_channel, out_channelchannel, downsampledownsample, stridestride)) # 定义convi_x中的第一个残差块只有第一个需要设置downsample和strideself.in_channel channel*block.expansion # 在下一次调用_make_layer函数的时候self.in_channel已经x4for _ in range(1, block_num): # 通过循环堆叠其余残差块(堆叠了剩余的block_num-1个)layers.append(block(in_channelself.in_channel, out_channelchannel))return nn.Sequential(*layers) # *的作用是将list转换为非关键字参数传入1.4 迁移学习猫狗二分类实战
1.4.1 迁移学习 迁移学习Transfer Learning是一种机器学习和深度学习技术它允许我们将一个任务学到的知识或特征迁移到另一个相关的任务中从而加速模型的训练和提高性能。在迁移学习中我们通常利用已经在大规模数据集上预训练好的模型称为源任务模型将其权重用于新的任务称为目标任务而不是从头开始训练一个全新的模型。 迁移学习的核心思想是在解决一个新任务之前我们可以先从已经学习过的任务中获取一些通用的特征或知识并将这些特征或知识迁移到新任务中。这样做的好处在于源任务模型已经在大规模数据集上进行了充分训练学到了很多通用的特征例如边缘检测、纹理等这些特征对于许多任务都是有用的。 1.4.2 模型训练
首先我们需要准备用于猫狗二分类的数据集。数据集可以从Kaggle上下载其中包含了大量的猫和狗的图片。
在下载数据集后我们需要将数据集划分为训练集和测试集。训练集文件夹命名为train,其中建立两个文件夹分别为cat和dog每个文件夹里存放相应类别的图片。测试集命名为test同理。然后我们使用ResNet50网络模型在我们的计算机上使用GPU进行训练并保存我们的模型训练完成后在测试集上验证模型预测的正确率。
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
from torch.utils.data import DataLoader, Dataset
from torchvision.datasets import ImageFolder
from torchvision.models import resnet50# 设置随机种子
torch.manual_seed(42)# 定义超参数
batch_size 32
learning_rate 0.001
num_epochs 10# 定义数据转换
transform transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])# 加载数据集
train_dataset ImageFolder(train, transformtransform)
test_dataset ImageFolder(test, transformtransform)train_loader DataLoader(train_dataset, batch_sizebatch_size, shuffleTrue)
test_loader DataLoader(test_dataset, batch_sizebatch_size)# 加载预训练的ResNet-50模型
model resnet50(pretrainedTrue)
num_ftrs model.fc.in_features
model.fc nn.Linear(num_ftrs, 2) # 替换最后一层全连接层以适应二分类问题device torch.device(cuda if torch.cuda.is_available() else cpu)
model.to(device)# 定义损失函数和优化器
criterion nn.CrossEntropyLoss()
optimizer optim.SGD(model.parameters(), lrlearning_rate, momentum0.9)# 训练模型
total_step len(train_loader)
for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader):images images.to(device)labels labels.to(device)# 前向传播outputs model(images)loss criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (i 1) % 100 0:print(fEpoch [{epoch1}/{num_epochs}], Step [{i1}/{total_step}], Loss: {loss.item()})
torch.save(model,model/c.pth)
# 测试模型
model.eval()
with torch.no_grad():correct 0total 0for images, labels in test_loader:images images.to(device)labels labels.to(device)outputs model(images)print(outputs)_, predicted torch.max(outputs.data, 1)total labels.size(0)correct (predicted labels).sum().item()breakprint(fAccuracy on test images: {(correct / total) * 100}%)1.4.3 模型预测
首先加载我们保存的模型这里我们进行单张图片的预测并把预测结果打印日志。
import cv2 as cv
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import torchvision.transforms as transforms
import torch
from PIL import Image
import os
os.environ[KMP_DUPLICATE_LIB_OK] TRUE
device torch.device(cuda if torch.cuda.is_available() else cpu)
modeltorch.load(model/c.pth)
print(model)
model.to(device)test_image_path test/dogs/dog.4001.jpg # Replace with your test image path
image Image.open(test_image_path)
transform transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
input_tensor transform(image).unsqueeze(0).to(device) # Add a batch dimension and move to GPU# Set the model to evaluation mode
model.eval()with torch.no_grad():outputs model(input_tensor)_, predicted torch.max(outputs, 1)predicted_label predicted.item()label[猫,狗]
print(label[predicted_label])
plt.axis(off)
plt.imshow(image)
plt.show()运行截图 至此这篇文章到此结束。