点击查看代码
import torch
from torch import optim
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, Dataset
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
import os
import time

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

#数据加载与预处理
transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])
def load_data():
    train_dataset = datasets.MNIST(root='./data', train=True, transform=transforms, download=True)
    test_dataset = datasets.MNIST(root='./data', train=False, transform=transforms, download=True)
    batch_size = 128
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

    return train_loader, test_loader, test_dataset

#定义CNN模型
class MyCNN(nn.Module):
    def __init__(self):
        super(MyCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(16, 16, kernel_size=3, padding=1)
        self.pool2 = nn.MaxPool2d(2, 2)
        self.output = nn.Linear(16 * 7 * 7, 10)
        self.dropout = nn.Dropout(0.5)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2(x)))
        x = x.view(x.size(0), -1)
        x = self.dropout(x)
        output = self.output(x)

        return output
    
#训练模型
model = MyCNN().to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()

def train(epochs, train_loader, model, optimizer, criterion):
    model.train()
    train_loss = []
    train_acc = []

    for epoch in range(epochs):
        start_time = time.time()
        running_loss = 0.0
        total = 0
        current = 0

        for i, (images, labels) in enumerate(train_loader):
            images, labels = images.to(device), labels.to(device)

            optimizer.zero_grad()
            output = model(images)

            loss = criterion(output, labels)
            loss.backward()
            optimizer.step()

            running_loss += loss.item()
            _, predicted = torch.max(output.data, 1)
            total += labels.size(0)
            current += (predicted == labels).sum().item()
        
        epoch_loss = running_loss / len(train_loader)
        epoch_acc = 100 * current / total
        train_loss.append(epoch_loss)
        train_acc.append(epoch_acc)

        end_time = time.time()
        print(f"Epoch [{epoch+1}/{epochs}], Loss: {epoch_loss:.4f}, Acc: {epoch_acc:.2f}%, Time: {end_time-start_time:.2f}s")

    torch.save(model.state_dict(), os.path.join('model', 'cnn_3116.pth'))
    
    return train_loss, train_acc

# 加载已保存的模型
def load_model(model_path):
    model = MyCNN().to(device)
    if os.path.exists(model_path):
        try:
            model.load_state_dict(torch.load(model_path, map_location=device))
            print(f"成功加载模型: {model_path}")
            return model
        except Exception as e:
            print(f"加载模型失败: {e}")
            return None
    else:
        print(f"模型文件不存在: {model_path}")
        return None

#测试模型
def test(model, test_loader):
    model.eval()
    all_preds = []
    all_labels = []

    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)

            output = model(images)
            _, predicted = torch.max(output.data, 1)

            all_preds.extend(predicted.cpu().numpy())
            all_labels.extend(labels.cpu().numpy())

    all_preds = np.array(all_preds)
    all_labels = np.array(all_labels)

    accuracy = (all_preds == all_labels).mean() * 100
    print(f"测试准确率: {accuracy:.2f}%")

    print("分类效果评估:")
    target_names = [str(i) for i in range(10)]
    report = classification_report(all_labels, all_preds, target_names=target_names)
    print(report)

    cm = confusion_matrix(all_labels, all_preds)
    plt.figure(figsize=(10, 8))
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', 
                xticklabels=target_names, 
                yticklabels=target_names)
    plt.xlabel('Predicted')
    plt.ylabel('True')
    plt.title('Confusion Matrix')
    plt.show()

#主函数
if __name__ == '__main__':
    print("24信计1班 麦麦提力 2024310143034")
    print(f"device: {device}")

    train_loader, test_loader, test_dataset = load_data()
    epochs = 20
    train_loader, test_loader, test_dataset = load_data()
    model_path = os.path.join('model', 'cnn_3116.pth')
    
    # 询问用户是否加载已保存的模型
    load_existing = input("是否加载已保存的模型? (y/n): ").strip().lower()
    
    if load_existing == 'y':
        model = load_model(model_path)
        if model is None:  # 如果加载失败,则创建新模型
            print("将创建新模型进行训练...")
            model = MyCNN().to(device)
            optimizer = optim.Adam(model.parameters(), lr=0.001)
            criterion = nn.CrossEntropyLoss()
            epochs = 20
            train_loss, train_acc = train(epochs, train_loader, model, optimizer, criterion)
    else:
        # 创建新模型并训练
        model = MyCNN().to(device)
        optimizer = optim.Adam(model.parameters(), lr=0.001)
        criterion = nn.CrossEntropyLoss()
        epochs = 20
        train_loss, train_acc = train(epochs, train_loader, model, optimizer, criterion)
    
    # 测试模型
    test(model, test_loader)
    
    # 如果是新训练的模型,绘制训练曲线
    if load_existing != 'y' or model is None:
        plt.figure(figsize=(10, 5))
        plt.subplot(1, 2, 1)
        plt.plot(range(1, epochs+1), train_loss)
        plt.title("Training Loss")
        plt.xlabel("Epoch")
        plt.ylabel("Loss")

        plt.subplot(1, 2, 2)
        plt.plot(range(1, epochs+1), train_acc)
        plt.title("Training Accuracy")
        plt.xlabel("Epoch")
        plt.ylabel("Accuracy (%)")

        plt.tight_layout()
        plt.show()
点击查看代码
import torch
from torch import optim
import torch.nn as nn
from torch.autograd import Variable
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, Dataset
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt
import os
import time

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

#数据加载与预处理
transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])
def load_data():
    train_dataset = datasets.MNIST(root='./data', train=True, transform=transforms, download=True)
    test_dataset = datasets.MNIST(root='./data', train=False, transform=transforms, download=True)
    batch_size = 128
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

    return train_loader, test_loader, test_dataset

#建立神经网络
class MyMLP(nn.Module):
    def __init__(self, 
                 input_dim = 28*28, 
                 hidden_dim = 16, hidden_layers = 3, 
                 output_dim = 10, 
                 activation = nn.ReLU(), dropout = 0.5):
        super(MyMLP, self).__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, hidden_dim)
        self.fc3 = nn.Linear(hidden_dim, hidden_dim)
        self.fc4 = nn.Linear(hidden_dim, hidden_dim)
        self.fc5 = nn.Linear(hidden_dim, output_dim)
    
    def forward(self, x):
        x = x.view(-1, 28*28)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = torch.relu(self.fc3(x))
        x = torch.relu(self.fc4(x))
        x = self.fc5(x)
        return x

#训练模型
model = MyMLP().to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()

def train(epochs, train_loader, optimizer, criterion):
    model.train()
    train_loss = []
    train_acc = []

    for epoch in range(epochs):
        running_loss = 0.0
        total = 0
        current = 0
        for i, (images, labels) in enumerate(train_loader):
            images, labels = images.to(device), labels.to(device)

            optimizer.zero_grad()
            output = model(images)

            loss = criterion(output, labels)
            loss.backward()
            optimizer.step()

            running_loss += loss.item()
            _, predicted = torch.max(output.data, 1)
            total += labels.size(0)
            current += (predicted == labels).sum().item()

        epoch_loss = running_loss / len(train_loader)
        epoch_acc = 100 * current / total
        train_loss.append(epoch_loss)
        train_acc.append(epoch_acc)

        if epoch % 5 == 0:
            print(f"Epoch [{epoch}/epochs], Loss: {epoch_loss:.4f}, Acc: {epoch_acc:.2f}%")
    
    return train_loss, train_acc

def test(model, test_loader):
    model.eval()
    all_preds =[]
    all_labels = []

    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)

            output = model(images)
            _, predicted = torch.max(output.data, 1)

            all_preds.extend(predicted.cpu().numpy())
            all_labels.extend(labels.cpu().numpy())

    all_preds = np.array(all_preds)
    all_labels = np.array(all_labels)

    accuracy = (all_preds == all_labels).mean() * 100
    print(f"测试准确率: {accuracy:.2f}%")

    print("分类效果评估:")
    target_names = [str(i) for i in range(10)]
    report = classification_report(all_labels, all_preds, target_names=target_names)
    print(report)

if __name__ == '__main__':
    print("(麦麦提力2024310143034)")
    print(f"device:{device}")

    train_loader, test_loader, test_dataset = load_data()
    epochs = 20
    train_loss, train_acc = train(epochs, train_loader, optimizer, criterion)
    test(model, test_loader)

    #绘制结果
    plt.figure(figsize=(10, 5))
    plt.subplot(1, 2, 1)
    plt.plot(range(1, epochs+1), train_loss)
    plt.title("Training Loss")
    plt.xlabel("Epoch")
    plt.ylabel("Loss")

    plt.subplot(1, 2, 2)
    plt.plot(range(1, epochs+1), train_acc)
    plt.title("Training Accuracy")
    plt.xlabel("Epoch")
    plt.ylabel("Accuracy (%)")

    plt.tight_layout()
    plt.show()
点击查看代码
import torch
from torch import optim
import torch.nn as nn
from torch.autograd import Variable
from torchvision import transforms, datasets
from torch.utils.data import DataLoader, Dataset
from PIL import Image
import torch.nn.functional as F
import numpy as np
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
import os
import time

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

#数据准备
transform = transforms.Compose([
    transforms.Resize((32, 32)),
    transforms.ToTensor(),
    transforms.Normalize((0.1307), (0.3081))
]) 

def load_data():
    train_dataset = datasets.MNIST(
        root='./data', train=True, download=True, transform=transform
    )
    test_dataset = datasets.MNIST(
        root='./data', train=False, download=True, transform=transform
    )

    batch_size = 128
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

    return train_loader, test_loader, test_dataset

#模型定义
class RegAlexNet(nn.Module):
    def __init__(self, num_classes=10):
        super(RegAlexNet, self).__init__()
        #特征提取层
        self.features = nn.Sequential(
            nn.Conv2d(1, 32, kernel_size=5, stride=1, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            nn.Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )
        #分类层
        self.classifier = nn.Sequential(
            nn.Dropout(p=0.5),
            nn.Linear(64*8*8, 512),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(512, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x
    
#模型训练
model = RegAlexNet().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

def train(epochs, train_loader, model, optimizer, criterion):
    model.train()
    train_loss = []
    train_acc = []

    for epoch in range(epochs):
        start_time = time.time()
        running_loss = 0.0
        total = 0
        current = 0

        for i, (images, labels) in enumerate(train_loader):
            images, labels = images.to(device), labels.to(device)

            optimizer.zero_grad()
            output = model(images)

            loss = criterion(output, labels)
            loss.backward()
            optimizer.step()

            running_loss += loss.item()
            _, predicted = torch.max(output.data, 1)
            total += labels.size(0)
            current += (predicted == labels).sum().item()
        
        epoch_loss = running_loss / len(train_loader)
        epoch_acc = 100 * current / total
        train_loss.append(epoch_loss)
        train_acc.append(epoch_acc)

        end_time = time.time()
        print(f"Epoch [{epoch+1}/{epochs}], Loss: {epoch_loss:.4f}, Acc: {epoch_acc:.2f}%, Time: {end_time-start_time:.2f}s")

    torch.save(model.state_dict(), os.path.join('model', 'alexnet_3116.pth'))
    
    return train_loss, train_acc

# 加载已保存的模型
def load_model(model_path):
    model = RegAlexNet().to(device)
    if os.path.exists(model_path):
        try:
            model.load_state_dict(torch.load(model_path, map_location=device))
            print(f"成功加载模型: {model_path}")
            return model
        except Exception as e:
            print(f"加载模型失败: {e}")
            return None
    else:
        print(f"模型文件不存在: {model_path}")
        return None

#测试模型
def test(model, test_loader):
    model.eval()
    all_preds = []
    all_labels = []

    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)

            output = model(images)
            _, predicted = torch.max(output.data, 1)

            all_preds.extend(predicted.cpu().numpy())
            all_labels.extend(labels.cpu().numpy())

    all_preds = np.array(all_preds)
    all_labels = np.array(all_labels)

    accuracy = (all_preds == all_labels).mean() * 100
    print(f"测试准确率: {accuracy:.2f}%")

    print("分类效果评估:")
    target_names = [str(i) for i in range(10)]
    report = classification_report(all_labels, all_preds, target_names=target_names)
    print(report)

    cm = confusion_matrix(all_labels, all_preds)
    plt.figure(figsize=(10, 8))
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', 
                xticklabels=target_names, 
                yticklabels=target_names)
    plt.xlabel('Predicted')
    plt.ylabel('True')
    plt.title('Confusion Matrix')
    plt.show()


#主函数
if __name__ == '__main__':

    print(f"24信计1麦麦提力 2024310143034")
    print(f"device: {device}")
    
    num_epochs = 20

    train_loader, test_loader, test_dataset = load_data()

    model_path = os.path.join('model', 'alexnet_3116.pth')
    
    # 询问用户是否加载已保存的模型
    load_existing = input("是否加载已保存的模型? (y/n): ").strip().lower()
    
    if load_existing == 'y':
        model = load_model(model_path)
        if model is None:  # 如果加载失败,则创建新模型
            print("将创建新模型进行训练...")
            model = RegAlexNet().to(device)
            optimizer = optim.Adam(model.parameters(), lr=0.001)
            criterion = nn.CrossEntropyLoss()
            epochs = 20
            train_loss, train_acc = train(epochs, train_loader, model, optimizer, criterion)
    else:
        # 创建新模型并训练
        model = RegAlexNet().to(device)
        optimizer = optim.Adam(model.parameters(), lr=0.001)
        criterion = nn.CrossEntropyLoss()
        epochs = 20
        train_loss, train_acc = train(epochs, train_loader, model, optimizer, criterion)
    
    # 测试模型
    test(model, test_loader)
    
    # 如果是新训练的模型,绘制训练曲线
    if load_existing != 'y' or model is None:
        plt.figure(figsize=(10, 5))
        plt.subplot(1, 2, 1)
        plt.plot(range(1, epochs+1), train_loss)
        plt.title("Training Loss")
        plt.xlabel("Epoch")
        plt.ylabel("Loss")

        plt.subplot(1, 2, 2)
        plt.plot(range(1, epochs+1), train_acc)
        plt.title("Training Accuracy")
        plt.xlabel("Epoch")
        plt.ylabel("Accuracy (%)")

        plt.tight_layout()
        plt.show()

屏幕截图 2025-12-26 133727

屏幕截图 2025-12-26 134321

屏幕截图 2025-12-26 135026

Figure_1

posted on 2025-12-26 13:58  986614  阅读(4)  评论(0)    收藏  举报