进阶Task3.2+3:《深度学习详解》(Datawhale X 李宏毅苹果书 AI夏令营)

前言 

文章概述《深度学习详解》- 4

本书介绍了卷积神经网络(CNN)的基本结构及其在图像识别任务中的应用,并详细探讨了其工作原理、优化策略以及更广泛的应用领域。文章首先说明了将图像数据转换为适合网络输入的格式的过程,强调了图像作为三维张量的重要性。通过分析全连接网络在图像识别中的局限性,引出了对CNN的关注。与全连接网络相比,CNN通过对参数的共享和局部感受野的使用大幅减少了模型的复杂度并提高了计算效率,更适合处理具有网格状结构的数据,如图像。感受野的设计允许网络专注于图像中的局部特征,减少了需要训练的参数数量,从而降低了过拟合风险并提高了计算效率。参数共享进一步减少了参数数量,使模型更加高效,同时保持了足够的灵活性以适应不同的图像区域。同时,阐述了卷积层如何检测图像中的特征,以及池化层如何减小特征映射的空间尺寸同时保持主要信息。步幅和填充等技术被讨论,以及如何通过调整这些超参数来优化网络性能。此外,文章还介绍了CNN在其他领域的应用,例如在下围棋中的策略规划,强调了模型架构的选择应基于任务特性的考量。最后,文章指出了卷积神经网络的一些局限性,如对图像尺度变化的不敏感性,并提到了解决这一问题的方法。通过对CNN的理论基础和实际应用的详细介绍,本文为读者提供了一种高效解决视觉相关问题的强大工具的理解和运用框架。


个人学习笔记以及概念梳理,望对大家有所帮助。


思维导图4.1-4.4

思维导图4.5-4.8

卷积神经网络的设计结构

一个典型的CNN架构可能会是这样的序列:[Input -> Conv -> ReLU -> Pool -> Conv -> ReLU -> Pool -> Fully Connected -> Output]。

卷积神经网络几种常见的优化方法

补充
以下是几种优化方法的具体应用实例:

正则化:通过添加L2正则化项来惩罚大的权重值,减少过拟合。

Dropout:在训练过程中随机丢弃部分神经元的输出,以防止过拟合。

批量归一化:在网络中加入批量归一化层,有助于加速训练并提高模型性能。

数据增强:通过对训练图像进行随机变换(如翻转、旋转、缩放等),增加训练集的多样性。

学习率调整:采用学习率衰减策略,例如每经过一定数量的epoch后将学习率减半。

权重初始化:使用Xavier或He初始化策略,以改善训练初期的梯度传播。

优化器选择:使用Adam优化器,它结合了动量法和自适应学习率的优势,可以有效地解决训练过程中的问题。

涉及的一些术语

术语

解释

卷积神经网络 (CNN)

一种专为处理具有网格结构的数据(如图像)而设计的神经网络。CNN 通过使用卷积层来自动检测图像中的局部模式。

全连接层 (fully-connected layer)

一种神经网络层,其中每个神经元都与前一层的所有神经元连接。全连接层通常位于 CNN 的末端,用于分类任务。

滤波器 (filter)

CNN 中的小张量,用于检测图像中的特定模式。滤波器在图像上滑动并执行卷积操作,产生特征映射。

特征映射 (feature map)

当图像通过滤波器后产生的输出。每个滤波器都会产生一个特征映射,表示图像中检测到的特定模式。

感受野 (receptive field)

神经元或滤波器能够“看到”的输入空间的大小。感受野定义了神经元能够响应的输入区域。

参数共享 (parameter sharing)

CNN 中的一种策略,允许不同位置的感受野使用相同的滤波器权重。这减少了参数数量并提高了模型的泛化能力。

汇聚 (pooling)

一种下采样技术,用于减小特征映射的尺寸,同时保持最重要的信息。最常见的形式是最大汇聚和平均汇聚。

扁平化 (flattening)

将多维特征映射转换为一维向量的过程,以便可以将其馈送到全连接层中。

通道 (channel)

彩色图像中的颜色信息,例如 RGB 图像有三个通道(红、绿、蓝)。在 CNN 中,通道可以指输入图像的通道或特征映射的数量。

步幅 (stride)

滤波器在图像上移动的距离。步幅决定了滤波器每次移动多少像素。

填充 (padding)

在图像边缘添加额外像素的过程,通常是添加零像素。填充有助于保留边缘信息并控制输出尺寸。

过拟合 (overfitting)

模型在训练数据上表现很好但在新数据上表现不佳的现象。过拟合通常发生在模型过于复杂时。

数据增强 (data augmentation)

通过对训练数据应用变换(如旋转、缩放)来增加训练集多样性的技术,以提高模型的鲁棒性。

学习过程遇到的一些问题的理解:

1卷积神经网络类型,优缺点以及应用场合

补充

标准卷积神经网络

结构:由卷积层、池化层、全连接层组成的简单结构。

应用场景:图像分类、物体检测、语义分割。

残差网络(ResNet)

结构:引入了跳跃连接(skip connections),允许网络深层直接传递梯度。

应用场景:大规模图像分类、目标定位、行人重识别。

Inception 网络 

结构:使用多尺度卷积核并行计算,然后合并结果。

应用场景:图像分类、目标检测、图像风格迁移。

U-Net

结构:包含一个编码器和一个解码器,中间通过跳跃连接传递特征。

应用场景:医学图像分割、语义分割。

VGG 网络

结构:使用固定大小的小型卷积核(通常是3x3)堆叠而成。

应用场景:图像分类、特征提取、生成对抗网络(GANs)。

MobileNet

结构:采用深度可分离卷积,减少了参数数量和计算复杂度。

应用场景:移动设备上的实时图像分类、实时物体检测。

代码运行

使用Z-score标准化归一化的情况, 用不同的卷积神经网络类型 的效果验证,实现功能

将图片分类为10种:'apple_pie', 'beef_tartare', 'beet_salad', 'cheesecake', 'chicken_wings', 'dumplings', 'fish_and_chips', 'gyoza', 'hamburger', 'hot_dog'。

同时输出每一种分类的精度。

具体细节可见

进阶Task2:《深度学习详解》(Datawhale X 李宏毅苹果书 AI夏令营)-CSDN博客


 

使用标准卷积神经网络来看分类效果

代码如下

import os
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from PIL import Image
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

# 指定目录路径
directory = r'.\food-101\picture'

# 定义标签映射
label_to_index = {
    'apple_pie': 0,
    'beef_tartare': 1,
    'beet_salad': 2,
    'cheesecake': 3,
    'chicken_wings': 4,
    'dumplings': 5,
    'fish_and_chips': 6,
    'gyoza': 7,
    'hamburger': 8,
    'hot_dog': 9,
}
index_to_label = {v: k for k, v in label_to_index.items()}

# 读取图片和标签
def load_images_and_labels(directory):
    images = []
    labels = []

    for filename in os.listdir(directory):
        if filename.endswith('.jpg') or filename.endswith('.png'):
            label, _ = filename.split('-', 1)
            label = label.strip()
            images.append(os.path.join(directory, filename))
            labels.append(label_to_index.get(label, None))  # 如果标签不存在,则返回 None

    return images, labels

# 数据预处理
class FoodImageDataset(Dataset):
    def __init__(self, images, labels, transform=None):
        self.images = images
        self.labels = labels
        self.transform = transform

    def __len__(self):
        return len(self.images)

    def __getitem__(self, idx):
        img_path = self.images[idx]
        image = Image.open(img_path)
        label = self.labels[idx]

        if self.transform:
            image = self.transform(image)

        return image, label

# 定义数据转换
transform_train = transforms.Compose([
    transforms.RandomResizedCrop(128),
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(10),  # 添加旋转
    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),  # 添加颜色扰动
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

transform_test = transforms.Compose([
    transforms.Resize((128, 128)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# 加载图片和标签
images, labels = load_images_and_labels(directory)

# 将图片和标签组合成 DataFrame
df = pd.DataFrame({'image': images, 'label': labels})

# 删除无效标签
df = df.dropna(subset=['label']).reset_index(drop=True)

# 划分训练集和测试集
train_df, test_df = train_test_split(df, test_size=0.2, random_state=42)

# 创建数据集
train_dataset = FoodImageDataset(train_df['image'].tolist(), train_df['label'].tolist(), transform=transform_train)
test_dataset = FoodImageDataset(test_df['image'].tolist(), test_df['label'].tolist(), transform=transform_test)

# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

# 定义简单的CNN模型
class SimpleCNN(nn.Module):
    def __init__(self, num_classes=10):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1)
        self.relu1 = nn.ReLU()
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)
        self.relu2 = nn.ReLU()
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.dropout = nn.Dropout(p=0.5)  # 添加 dropout 层
        self.fc1 = nn.Linear(32 * 32 * 32, 256)  # 根据输入尺寸调整
        self.relu3 = nn.ReLU()
        self.fc2 = nn.Linear(256, num_classes)

    def forward(self, x):
        x = self.pool1(self.relu1(self.conv1(x)))
        x = self.pool2(self.relu2(self.conv2(x)))
        x = x.view(-1, 32 * 32 * 32)  # 根据输入尺寸调整
        x = self.dropout(x)
        x = self.relu3(self.fc1(x))
        x = self.fc2(x)
        return x

model = SimpleCNN()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.AdamW(model.parameters(), lr=0.001)  # 使用 AdamW 优化器

# 学习率调度器
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=5, verbose=True)

# 训练模型
num_epochs = 20
best_acc = 0.0
for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    for images, labels in train_loader:
        images, labels = images.to(device), labels.to(device)
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item() * images.size(0)
    epoch_loss = running_loss / len(train_dataset)
    scheduler.step(epoch_loss)

    # 在测试集上评估
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    acc = correct / total
    print(f"Epoch {epoch + 1}/{num_epochs}, Loss: {epoch_loss:.4f}, Val Acc: {acc:.4f}")
    if acc > best_acc:
        best_acc = acc
        torch.save(model.state_dict(), 'best_model.pth')

# 加载最佳模型
model.load_state_dict(torch.load('best_model.pth'))

# 评估模型
y_true = []
y_pred = []

model.eval()
with torch.no_grad():
    for images, labels in test_loader:
        images, labels = images.to(device), labels.to(device)
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        y_true.extend(labels.cpu().numpy())
        y_pred.extend(predicted.cpu().numpy())

# 计算性能指标
print("Classification Report:")
print(classification_report(y_true, y_pred, target_names=list(index_to_label.values())))

# 输出每个类别的精度
report = classification_report(y_true, y_pred, output_dict=True)
for label, metrics in report.items():
    if label in index_to_label and label != 'accuracy':
        print(f"{index_to_label[int(label)]}: Precision={metrics['precision']:.2f}, Recall={metrics['recall']:.2f}")

使用Inception 网络来看分类效果

代码如下

import os
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, models
from PIL import Image
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

# 指定目录路径
directory = r'.\food-101\picture'

# 定义标签映射
label_to_index = {
    'apple_pie': 0,
    'beef_tartare': 1,
    'beet_salad': 2,
    'cheesecake': 3,
    'chicken_wings': 4,
    'dumplings': 5,
    'fish_and_chips': 6,
    'gyoza': 7,
    'hamburger': 8,
    'hot_dog': 9,
}
index_to_label = {v: k for k, v in label_to_index.items()}

# 读取图片和标签
def load_images_and_labels(directory):
    images = []
    labels = []

    for filename in os.listdir(directory):
        if filename.endswith('.jpg') or filename.endswith('.png'):
            label, _ = filename.split('-', 1)
            label = label.strip()
            images.append(os.path.join(directory, filename))
            labels.append(label_to_index.get(label, None))  # 如果标签不存在,则返回 None

    return images, labels

# 数据预处理
class FoodImageDataset(Dataset):
    def __init__(self, images, labels, transform=None):
        self.images = images
        self.labels = labels
        self.transform = transform

    def __len__(self):
        return len(self.images)

    def __getitem__(self, idx):
        img_path = self.images[idx]
        image = Image.open(img_path)
        label = self.labels[idx]

        if self.transform:
            image = self.transform(image)

        return image, label

# 定义数据转换
transform_train = transforms.Compose([
    transforms.RandomResizedCrop(299),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

transform_test = transforms.Compose([
    transforms.Resize((299, 299)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# 加载图片和标签
images, labels = load_images_and_labels(directory)

# 将图片和标签组合成 DataFrame
df = pd.DataFrame({'image': images, 'label': labels})

# 删除无效标签
df = df.dropna(subset=['label']).reset_index(drop=True)

# 划分训练集和测试集
train_df, test_df = train_test_split(df, test_size=0.2, random_state=42)

# 创建数据集
train_dataset = FoodImageDataset(train_df['image'].tolist(), train_df['label'].tolist(), transform=transform_train)
test_dataset = FoodImageDataset(test_df['image'].tolist(), test_df['label'].tolist(), transform=transform_test)

# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

# 使用预训练的 InceptionV3 模型
model = models.inception_v3(weights=models.Inception_V3_Weights.DEFAULT)
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 10)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 学习率调度器
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=5, verbose=True)

# 训练设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

# 训练模型
num_epochs = 20
best_acc = 0.0
for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    for images, labels in train_loader:
        images, labels = images.to(device), labels.to(device)
        optimizer.zero_grad()
        if model.training:
            outputs, aux_outputs = model(images)
            loss1 = criterion(outputs, labels)
            loss2 = criterion(aux_outputs, labels)
            loss = loss1 + 0.4 * loss2  # 辅助输出的权重通常较小
        else:
            outputs = model(images)
            loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item() * images.size(0)
    epoch_loss = running_loss / len(train_dataset)
    scheduler.step(epoch_loss)

    # 在测试集上评估
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    acc = correct / total
    print(f"Epoch {epoch + 1}/{num_epochs}, Loss: {epoch_loss:.4f}, Val Acc: {acc:.4f}")
    if acc > best_acc:
        best_acc = acc
        torch.save(model.state_dict(), 'best_model.pth')

# 加载最佳模型
model.load_state_dict(torch.load('best_model.pth'))

# 评估模型
y_true = []
y_pred = []

model.eval()
with torch.no_grad():
    for images, labels in test_loader:
        images, labels = images.to(device), labels.to(device)
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        y_true.extend(labels.cpu().numpy())
        y_pred.extend(predicted.cpu().numpy())

# 计算性能指标
print("Classification Report:")
print(classification_report(y_true, y_pred, target_names=list(index_to_label.values())))

# 输出每个类别的精度
report = classification_report(y_true, y_pred, output_dict=True)
for label, metrics in report.items():
    if label in index_to_label and label != 'accuracy':
        print(f"{index_to_label[int(label)]}: Precision={metrics['precision']:.2f}, Recall={metrics['recall']:.2f}")

使用 残差网络(ResNet)来看分类效果
代码如下
import os
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, models
from PIL import Image
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

# 指定目录路径
directory = r'.\food-101\picture'

# 定义标签映射
label_to_index = {
    'apple_pie': 0,
    'beef_tartare': 1,
    'beet_salad': 2,
    'cheesecake': 3,
    'chicken_wings': 4,
    'dumplings': 5,
    'fish_and_chips': 6,
    'gyoza': 7,
    'hamburger': 8,
    'hot_dog': 9,
}
index_to_label = {v: k for k, v in label_to_index.items()}

# 读取图片和标签
def load_images_and_labels(directory):
    images = []
    labels = []

    for filename in os.listdir(directory):
        if filename.endswith('.jpg') or filename.endswith('.png'):
            label, _ = filename.split('-', 1)
            label = label.strip()
            images.append(os.path.join(directory, filename))
            labels.append(label_to_index.get(label, None))  # 如果标签不存在,则返回 None

    return images, labels

# 数据预处理
class FoodImageDataset(Dataset):
    def __init__(self, images, labels, transform=None):
        self.images = images
        self.labels = labels
        self.transform = transform

    def __len__(self):
        return len(self.images)

    def __getitem__(self, idx):
        img_path = self.images[idx]
        image = Image.open(img_path)
        label = self.labels[idx]

        if self.transform:
            image = self.transform(image)

        return image, label

# 定义数据转换
transform_train = transforms.Compose([
    transforms.RandomResizedCrop(224),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

transform_test = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# 加载图片和标签
images, labels = load_images_and_labels(directory)

# 将图片和标签组合成 DataFrame
df = pd.DataFrame({'image': images, 'label': labels})

# 删除无效标签
df = df.dropna(subset=['label']).reset_index(drop=True)

# 划分训练集和测试集
train_df, test_df = train_test_split(df, test_size=0.2, random_state=42)

# 创建数据集
train_dataset = FoodImageDataset(train_df['image'].tolist(), train_df['label'].tolist(), transform=transform_train)
test_dataset = FoodImageDataset(test_df['image'].tolist(), test_df['label'].tolist(), transform=transform_test)

# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

# 使用预训练的 ResNet 模型
model = models.resnet50(weights=models.ResNet50_Weights.DEFAULT)
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 10)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 学习率调度器
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=5, verbose=True)

# 训练设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

# 训练模型
num_epochs = 20
best_acc = 0.0
for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    for images, labels in train_loader:
        images, labels = images.to(device), labels.to(device)
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item() * images.size(0)
    epoch_loss = running_loss / len(train_dataset)
    scheduler.step(epoch_loss)

    # 在测试集上评估
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    acc = correct / total
    print(f"Epoch {epoch + 1}/{num_epochs}, Loss: {epoch_loss:.4f}, Val Acc: {acc:.4f}")
    if acc > best_acc:
        best_acc = acc
        torch.save(model.state_dict(), 'best_model.pth')

# 加载最佳模型
model.load_state_dict(torch.load('best_model.pth'))

# 评估模型
y_true = []
y_pred = []

model.eval()
with torch.no_grad():
    for images, labels in test_loader:
        images, labels = images.to(device), labels.to(device)
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        y_true.extend(labels.cpu().numpy())
        y_pred.extend(predicted.cpu().numpy())

# 计算性能指标
print("Classification Report:")
print(classification_report(y_true, y_pred, target_names=list(index_to_label.values())))

# 输出每个类别的精度
report = classification_report(y_true, y_pred, output_dict=True)
for label, metrics in report.items():
    if label in index_to_label and label != 'accuracy':
        print(f"{index_to_label[int(label)]}: Precision={metrics['precision']:.2f}, Recall={metrics['recall']:.2f}")

比较效果

参考之前基于预训练的 ResNet-18 模型

简单的标准卷积神经网络

Inception 网络

残差网络(ResNet)

单单从整体精度而言,残差网络(ResNet)下的分类效果还是较好的,但考虑到时间成本,就需要视情况而选择模型。

注:运行时,Inception 网络和残差网络(ResNet)耗时较长,近30分钟,所以大家在选择模型搭建时,既要考虑到精度,也要适当注意运行时长。


小结

卷积神经网络的关键组件
  • 卷积层:负责检测图像中的基本特征,如边缘和纹理。
  • ReLU激活函数:引入非线性,帮助模型学习复杂的模式。
  • 池化层:减少特征图的空间维度,同时保留关键信息。
  • 全连接层:用于最终的分类决策。
常见的优化方法
  • 正则化:如L2正则化,防止过拟合。
  • Dropout:随机关闭神经元,增强模型的泛化能力。
  • 批量归一化:标准化层间输入,加快训练速度。
  • 数据增强:通过变换训练样本增加多样性。
  • 学习率调整:动态调整学习率以优化收敛速度。
  • 权重初始化:使用Xavier或He初始化以稳定训练初期的梯度。
  • 优化器选择:如Adam优化器,结合了动量和自适应学习率的优点。
不同类型的CNN架构
  • 标准CNN:适用于图像分类、物体检测等。
  • 残差网络(ResNet):通过跳跃连接解决了深层网络中的梯度消失问题。
  • Inception网络:利用多尺度卷积核并行计算,增强了网络的表达力。
  • U-Net:常用于医学图像分割等任务。
  • VGG网络:使用固定大小的小型卷积核,适用于多种图像任务。
  • MobileNet:为移动设备设计,注重实时性能。
实践案例

      文章还展示了如何 使用不同的CNN架构对食物图像进行分类,包括苹果派、牛肉塔塔、甜菜沙拉等十种类别。实验结果显示,尽管残差网络(ResNet)在精度上表现最佳,但由于其较长的训练时间,实际应用时需权衡精度与效率之间的关系。

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值