17.使用DenseNet网络进行Fashion-Mnist分类

17.1 DenseNet网络结构设计

python 复制代码
import torch
from torch import nn
from torchsummary import summary
#卷积层
def conv_block(input_channels,num_channels):
    net=nn.Sequential(nn.BatchNorm2d(input_channels),nn.ReLU(),nn.Conv2d(input_channels,num_channels,kernel_size=3,padding=1))
    return net
#过渡层
def transition_block(inputs_channels,num_channels):
    net=nn.Sequential(nn.BatchNorm2d(inputs_channels),nn.ReLU(),
                      nn.Conv2d(inputs_channels,num_channels,kernel_size=1),
                      nn.AvgPool2d(kernel_size=2,stride=2))
    return net
#DenseNetBlock
class DenseBlock(nn.Module):
    def __init__(self, num_convs,input_channels,num_channels):
        super(DenseBlock,self).__init__()
        layer=[]
        for i in range(num_convs):
            layer.append(conv_block(num_channels*i+input_channels,num_channels))
        self.net=nn.Sequential(*layer)
    def forward(self,X):
        for blk in self.net:
            Y=blk(X)
            X=torch.cat((X,Y),dim=1)
        return X
b1=nn.Sequential(nn.Conv2d(1,64,kernel_size=7,stride=2,padding=3),
                 nn.BatchNorm2d(64),nn.ReLU(),
                 nn.MaxPool2d(kernel_size=3,stride=2,padding=1))
num_channels,growth_rate=64,32
num_convs_in_dense_block=[4,4,4,4]
blks=[]
for i,num_convs in enumerate(num_convs_in_dense_block):
    blks.append(DenseBlock(num_convs,num_channels,growth_rate))
    # 上一个稠密块的输出通道数
    num_channels+=num_convs*growth_rate
    # 在稠密块之间添加一个转换层,使通道数量减半
    if i!=len(num_convs_in_dense_block)-1:
        blks.append(transition_block(num_channels,num_channels//2))
        num_channels=num_channels//2
model=nn.Sequential(b1,*blks,
                    nn.BatchNorm2d(num_channels),nn.ReLU(),
                    nn.AdaptiveAvgPool2d((1,1)),
                    nn.Flatten(),
                    nn.Linear(num_channels,10))
device=torch.device("cuda" if torch.cuda.is_available() else 'cpu')
model.to(device)
summary(model,input_size=(1,224,224),batch_size=64)

17.2 DenseNet网络实现Fashion-Mnist分类

python 复制代码
################################################################################################################
#DenseNet
################################################################################################################
import torch
import torchvision
from torch import nn
import matplotlib.pyplot as plt
from torchvision.transforms import transforms
from torch.utils.data import DataLoader
from tqdm import tqdm
from sklearn.metrics import accuracy_score
from torch.nn import functional as F
plt.rcParams['font.family']=['Times New Roman']
class Reshape(torch.nn.Module):
    def forward(self,x):
        return x.view(-1,1,28,28)#[bs,1,28,28]
def plot_metrics(train_loss_list, train_acc_list, test_acc_list, title='Training Curve'):
    epochs = range(1, len(train_loss_list) + 1)
    plt.figure(figsize=(4, 3))
    plt.plot(epochs, train_loss_list, label='Train Loss')
    plt.plot(epochs, train_acc_list, label='Train Acc',linestyle='--')
    plt.plot(epochs, test_acc_list, label='Test Acc', linestyle='--')
    plt.xlabel('Epoch')
    plt.ylabel('Value')
    plt.title(title)
    plt.legend()
    plt.grid(True)
    plt.tight_layout()
    plt.show()
def train_model(model,train_data,test_data,num_epochs):
    train_loss_list = []
    train_acc_list = []
    test_acc_list = []
    for epoch in range(num_epochs):
        total_loss=0
        total_acc_sample=0
        total_samples=0
        loop=tqdm(train_data,desc=f"EPOCHS[{epoch+1}/{num_epochs}]")
        for X,y in loop:
            #X=X.reshape(X.shape[0],-1)
            #print(X.shape)
            X=X.to(device)
            y=y.to(device)
            y_hat=model(X)
            loss=CEloss(y_hat,y)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            #loss累加
            total_loss+=loss.item()*X.shape[0]
            y_pred=y_hat.argmax(dim=1).detach().cpu().numpy()
            y_true=y.detach().cpu().numpy()
            total_acc_sample+=accuracy_score(y_pred,y_true)*X.shape[0]#保存样本数
            total_samples+=X.shape[0]
        test_acc_samples=0
        test_samples=0
        for X,y in test_data:
            X=X.to(device)
            y=y.to(device)
            #X=X.reshape(X.shape[0],-1)
            y_hat=model(X)
            y_pred=y_hat.argmax(dim=1).detach().cpu().numpy()
            y_true=y.detach().cpu().numpy()
            test_acc_samples+=accuracy_score(y_pred,y_true)*X.shape[0]#保存样本数
            test_samples+=X.shape[0]
        avg_train_loss=total_loss/total_samples
        avg_train_acc=total_acc_sample/total_samples
        avg_test_acc=test_acc_samples/test_samples
        train_loss_list.append(avg_train_loss)
        train_acc_list.append(avg_train_acc)
        test_acc_list.append(avg_test_acc)
        print(f"Epoch {epoch+1}: Loss: {avg_train_loss:.4f},Trian Accuracy: {avg_train_acc:.4f},test Accuracy: {avg_test_acc:.4f}")
    plot_metrics(train_loss_list, train_acc_list, test_acc_list)
    return model
def init_weights(m):
    if type(m) == nn.Linear or type(m) == nn.Conv2d:
        nn.init.xavier_uniform_(m.weight)
################################################################################################################
#DenseNet
################################################################################################################
#卷积层
def conv_block(input_channels,num_channels):
    net=nn.Sequential(nn.BatchNorm2d(input_channels),nn.ReLU(),nn.Conv2d(input_channels,num_channels,kernel_size=3,padding=1))
    return net
#过渡层
def transition_block(inputs_channels,num_channels):
    net=nn.Sequential(nn.BatchNorm2d(inputs_channels),nn.ReLU(),
                      nn.Conv2d(inputs_channels,num_channels,kernel_size=1),
                      nn.AvgPool2d(kernel_size=2,stride=2))
    return net
#DenseNetBlock
class DenseBlock(nn.Module):
    def __init__(self, num_convs,input_channels,num_channels):
        super(DenseBlock,self).__init__()
        layer=[]
        for i in range(num_convs):
            layer.append(conv_block(num_channels*i+input_channels,num_channels))
        self.net=nn.Sequential(*layer)
    def forward(self,X):
        for blk in self.net:
            Y=blk(X)
            X=torch.cat((X,Y),dim=1)
        return X
b1=nn.Sequential(nn.Conv2d(1,64,kernel_size=7,stride=2,padding=3),
                 nn.BatchNorm2d(64),nn.ReLU(),
                 nn.MaxPool2d(kernel_size=3,stride=2,padding=1))
num_channels,growth_rate=64,32
num_convs_in_dense_block=[4,4,4,4]
blks=[]
for i,num_convs in enumerate(num_convs_in_dense_block):
    blks.append(DenseBlock(num_convs,num_channels,growth_rate))
    # 上一个稠密块的输出通道数
    num_channels+=num_convs*growth_rate
    # 在稠密块之间添加一个转换层,使通道数量减半
    if i!=len(num_convs_in_dense_block)-1:
        blks.append(transition_block(num_channels,num_channels//2))
        num_channels=num_channels//2
################################################################################################################
transforms=transforms.Compose([transforms.Resize(96),transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])#第一个是mean,第二个是std
train_img=torchvision.datasets.FashionMNIST(root="./data",train=True,transform=transforms,download=True)
test_img=torchvision.datasets.FashionMNIST(root="./data",train=False,transform=transforms,download=True)
train_data=DataLoader(train_img,batch_size=128,num_workers=4,shuffle=True)
test_data=DataLoader(test_img,batch_size=128,num_workers=4,shuffle=False)
################################################################################################################
device=torch.device("cuda" if torch.cuda.is_available() else 'cpu')
model=nn.Sequential(b1,*blks,
                    nn.BatchNorm2d(num_channels),nn.ReLU(),
                    nn.AdaptiveAvgPool2d((1,1)),
                    nn.Flatten(),
                    nn.Linear(num_channels,10))
model.to(device)
model.apply(init_weights)
optimizer=torch.optim.SGD(model.parameters(),lr=0.01,momentum=0.9)
CEloss=nn.CrossEntropyLoss()
model=train_model(model,train_data,test_data,num_epochs=10)
################################################################################################################
相关推荐
ModelWhale21 分钟前
“大模型”技术专栏 | 和鲸 AI Infra 架构总监朱天琦:大模型微调与蒸馏技术的全景分析与实践指南(上)
人工智能·大模型·大语言模型
lxmyzzs2 小时前
【图像算法 - 08】基于 YOLO11 的抽烟检测系统(包含环境搭建 + 数据集处理 + 模型训练 + 效果对比 + 调参技巧)
人工智能·yolo·目标检测·计算机视觉
霖002 小时前
ZYNQ实现FFT信号处理项目
人工智能·经验分享·神经网络·机器学习·fpga开发·信号处理
GIS数据转换器3 小时前
AI 技术在智慧城市建设中的融合应用
大数据·人工智能·机器学习·计算机视觉·系统架构·智慧城市
竹子_233 小时前
《零基础入门AI:传统机器学习进阶(从拟合概念到K-Means算法)》
人工智能·算法·机器学习
上海云盾-高防顾问3 小时前
DDoS 防护的未来趋势:AI 如何重塑安全行业?
人工智能·安全·ddos
Godspeed Zhao3 小时前
自动驾驶中的传感器技术17——Camera(8)
人工智能·机器学习·自动驾驶·camera·cis
摆烂工程师4 小时前
GPT-5 即将凌晨1点进行发布,免费用户可以使用 GPT-5
前端·人工智能·程序员
今天也不想动4 小时前
文献解读-生境分析亚区域选择+2D_DL+3D_DL-局部晚期食管鳞状细胞癌新辅助化疗免疫治疗反应预测
人工智能·影像组学·生境分析
shao9185164 小时前
Gradio全解10——Streaming:流式传输的多模态应用(3)——HF Inference:在服务器运行推理
人工智能·推理·hf inference·inferenceclient·text_to_image·chat_completion