VGG-16卷积神经网络犬类识别
时间: 2025-07-05 17:04:20 浏览: 5
### 使用VGG-16卷积神经网络实现犬类图像分类
为了使用预训练的VGG-16模型来执行犬类图像分类任务,可以按照以下方法构建解决方案。此过程涉及准备环境、加载预训练模型以及调整模型以适应特定的任务需求。
#### 准备工作
确保安装了必要的库版本:
```bash
pip install torch==1.9.0 torchvision==0.10.0
```
#### 加载并配置VGG-16模型
通过`torchvision.models`模块可以直接获取已经完成训练的VGG-16模型实例,并将其设置为评估模式以便后续操作[^2]。
```python
import torch
from torchvision import models
use_pretrained = True
net = models.vgg16(pretrained=use_pretrained)
net.eval()
print(net)
```
这段代码会打印出完整的VGG-16架构详情,帮助理解每一层的功能及其参数量大小。
#### 修改最后一层全连接层
由于原始VGG-16是在ImageNet上进行了预训练,默认情况下其最后的全连接层输出维度对应于该数据集中存在的1000个类别。对于仅需区分两类(例如只针对犬类或其他任何二元分类场景),应当修改这一部分使其更适合当前任务的需求。
```python
num_features = net.classifier[-1].in_features
features = list(net.classifier.children())[:-1] # 去掉最后一个全连接层
fc_layer = torch.nn.Linear(num_features, 1) # 新增一层用于二分类
features.extend([torch.nn.ReLU(inplace=True), fc_layer])
net.classifier = torch.nn.Sequential(*features)
if torch.cuda.is_available():
net = net.cuda()
print("Modified Model:", net)
```
这里创建了一个新的线性变换层作为最终预测器,它接收来自倒数第二层特征映射的数量作为输入,并产生单一数值输出表示属于某一类别的概率估计值;同时加入了激活函数ReLU以保持非线性的特性。
#### 数据预处理与增强
考虑到实际应用中的X光安检图像可能较为复杂且背景干扰较多,在进行图像识别之前通常还需要对输入样本做适当转换处理,比如裁剪、缩放、翻转等随机变化手段增加泛化能力[^1]。然而,对于简单的宠物照片而言,则只需遵循标准流程即可满足要求。
```python
from torchvision import transforms
data_transforms = {
'train': transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
'val': transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
}
```
上述定义了一套适用于训练阶段和验证/测试阶段的不同图像预处理策略集合,包括尺寸调整、颜色标准化等一系列常规步骤,有助于提高模型性能表现。
#### 训练模型
有了经过改造后的基础框架之后就可以着手准备具体的训练环节了。这一步骤涉及到批量读取图片文件夹内的所有样本、分配至GPU设备加速计算速度等方面的工作细节。
```python
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
image_datasets = {x: ImageFolder(root=f'data/{x}', transform=data_transforms[x]) for x in ['train', 'val']}
dataloaders = {x: DataLoader(image_datasets[x], batch_size=4, shuffle=(x=='train'), num_workers=4) for x in ['train', 'val']}
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
criterion = torch.nn.BCEWithLogitsLoss().to(device)
optimizer = torch.optim.Adam(filter(lambda p: p.requires_grad, net.parameters()), lr=1e-4)
for epoch in range(num_epochs):
running_loss = 0.0
for phase in ['train', 'val']:
if phase == 'train':
model.train(True)
else:
model.train(False)
for inputs, labels in dataloaders[phase]:
optimizer.zero_grad()
with torch.set_grad_enabled(phase == 'train'):
outputs = net(inputs.to(device))
loss = criterion(outputs.squeeze(), labels.float().to(device))
if phase == 'train':
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"[Epoch {epoch+1}/{num_epochs}] Loss: {running_loss:.4f}")
```
以上展示了基本的循环迭代逻辑,其中包含了切换不同运行状态(`train`, `eval`)、前向传播求解损失值、反向传播更新权重参数等内容。注意此处假设标签是以整型形式给出而输出则采用sigmoid压缩到区间内再比较差异度。
阅读全文
相关推荐










