diff --git a/classifier/embedding_food_classifier_app.py b/classifier/embedding_food_classifier_app.py index b37144d..607254c 100644 --- a/classifier/embedding_food_classifier_app.py +++ b/classifier/embedding_food_classifier_app.py @@ -1,3 +1,6 @@ +""" +目前可视化用这个脚本,采用度量学习的方式 +""" import os import json import cv2 @@ -67,7 +70,8 @@ class EmbeddingFoodClassifierApp: # model_path = os.path.join(BASE_DIR, "../model/embedding_20251011_133653/best_embedding_model.pth") # model_path = os.path.join(BASE_DIR, "../model/ProcessedIngredientRecognition/embedding_20251029_170904/best_embedding_model.pth") # model_path = os.path.join(BASE_DIR, "../model/WholeIngredientRecognition/cosface_20251106_134718/best_cosface_model.pth") - model_path = os.path.join(BASE_DIR, "../model/WholeIngredientRecognition/grid_search_20251204_140816/model_s64.0_m0.4.pth") + # model_path = os.path.join(BASE_DIR, "../model/WholeIngredientRecognition/grid_search_20251204_140816/model_s64.0_m0.4.pth") + model_path = os.path.join(BASE_DIR, "../model/WholeIngredientRecognition/grid_search_20260302_092600/best_model_s64.0_m0.4.pth") # model_path = os.path.join(BASE_DIR, "../model/DishClassification/cosface_20251111_153649/best_cosface_model.pth") # FAISS索引目录 diff --git a/classifier/embedding_food_classifier_search_app.py b/classifier/embedding_food_classifier_search_app.py index dd9365d..aea3222 100644 --- a/classifier/embedding_food_classifier_search_app.py +++ b/classifier/embedding_food_classifier_search_app.py @@ -1,3 +1,9 @@ +""" +这个脚本是当时过渡期用的一个脚本 +背景是,当时安卓端没做向量数据库 +所以,用矩阵乘法的方式,求相似度 +现在安卓端已集成向量数据库,暂时不用这个脚本 +""" import os import json import cv2 diff --git a/classifier/food_classifier_app.py b/classifier/food_classifier_app.py index 8031dcd..9717a94 100644 --- a/classifier/food_classifier_app.py +++ b/classifier/food_classifier_app.py @@ -1,3 +1,6 @@ +""" +这个是最早用的一个脚本,采用端到端的训练模式 +""" import os import json import cv2 diff --git a/data_expansion/data_expansion.py b/data_expansion/data_expansion.py index 6f578dc..346dba8 100644 --- a/data_expansion/data_expansion.py +++ b/data_expansion/data_expansion.py @@ -1,3 +1,7 @@ +""" +这个脚本主要用于样本增加,主要是前期搜集图片来源于网络 +收集难度大,为了增加样本多样本,提高模型泛化能力 +""" import os import random from PIL import Image diff --git a/demo/向量索引.py b/demo/向量索引.py deleted file mode 100644 index 2be0a51..0000000 --- a/demo/向量索引.py +++ /dev/null @@ -1,40 +0,0 @@ -import faiss -import numpy as np - -# 数据归一化函数 -def normalize_vectors(vectors): - """对向量进行L2归一化""" - norms = np.linalg.norm(vectors, axis=1, keepdims=True) - # 避免除零 - norms = np.where(norms == 0, 1, norms) - return vectors / norms - - -data = np.array([[2, 3], [2, 4], [3, 7]], dtype='float32') - -# 归一化数据 -data_normalized = normalize_vectors(data) -print("原始数据:") -print(data) -print("归一化后数据:") -print(data_normalized) - -# 普通索引 -# base_index = faiss.IndexFlatL2(2) -base_index = faiss.IndexFlatIP(2) - -# 包一层 IDMap -index = faiss.IndexIDMap(base_index) - -# 指定 ID -ids = np.array([101, 102, 103]) # 自定义 ID -# index.add_with_ids(data, ids) -index.add_with_ids(data_normalized, ids) - -# 查询 -query = np.array([[3, 4.5]], dtype='float32') -query_normalized = normalize_vectors(query) -# D, I = index.search(query, k=2) -D, I = index.search(query_normalized, k=2) -print(D) -print(I) # 可能输出 [[101 102]] diff --git a/demo/看一下向量的数量.py b/demo/看一下向量的数量.py deleted file mode 100644 index 34ea4f0..0000000 --- a/demo/看一下向量的数量.py +++ /dev/null @@ -1,20 +0,0 @@ -import faiss -import numpy as np - -# 建一个 2 维向量的 L2 索引 -index = faiss.IndexFlatL2(2) - -print(index.ntotal) # 初始是 0 - -# 插入 5 个向量 -data = np.random.rand(5, 2).astype("float32") -index.add(data) - -print(index.ntotal) # 现在是 5 - -# 再插入 3 个 -more_data = np.random.rand(3, 2).astype("float32") -index.add(more_data) - -print(index.ntotal) # 现在是 8 - diff --git a/demo/识别CIFAR10数据集.py b/demo/识别CIFAR10数据集.py deleted file mode 100644 index 5933d3e..0000000 --- a/demo/识别CIFAR10数据集.py +++ /dev/null @@ -1,773 +0,0 @@ -import random - -import torch -# torchvision是PyTorch中专门用来处理图像的库,使用了torchvision就非常方便 -import torchvision -# transforms是torchvision库用来对图像进行变换的 -import torchvision.transforms as transforms -#time 是Python自带的库,引入它主要是用于记录训练时间 -import time -import sys -from torch.utils.data import random_split -import numpy as np -from tqdm import tqdm -from colorama import Fore, Style, Back -import os - -from torchvision.models import resnet18,resnet34,resnet50,resnet101 -import matplotlib.pyplot as plt - -# print('火山引擎,我来了') -# 记录开始时间 -start_time = time.time() - - -# 加上设备,然后准备放到赠送的线上GPU上训练 -device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - -# transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) -transform = transforms.Compose([transforms.ToTensor(), - transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)), - transforms.RandomHorizontalFlip(), #随机水平翻转 - transforms.RandomCrop(32, padding=4), #随机裁剪 - transforms.RandomErasing(scale=(0.04, 0.2), ratio=(0.5, 2)) #随机遮挡 - ]) -# 下载CIFAR10训练集 -trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) -# 加载训练集,训练集需要打乱,每次训练4个样本 -# trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=0) -# trainloader = torch.utils.data.DataLoader(trainset, batch_size=1, shuffle=True, num_workers=0) -# train_batch_size = 10 -# 每次给模型扔128张图片 -# train_batch_size = 128 -train_batch_size = 512 -# val_batch_size = 50 -val_batch_size = 512 -# test_batch_size = 30 -test_batch_size = 512 -# train_batch_size = 100 - - -# 假设我们要将数据集划分为90%训练集和10%验证集 -split = int(len(trainset) * 0.9) - -# 把随机种子固定下来,这样多次训练,就不会变化,从而避免验证集精度虚高 -torch.manual_seed(42) -np.random.seed(42) -random.seed(42) - - - -# 使用random_split函数随机划分数据集,它是torch封装的一个工具 -trainset, valset = random_split(trainset, [split, len(trainset) - split]) - -# 创建数据加载器 -# train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=2) -# val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False, num_workers=2) - - -# 打乱数据 -trainloader = torch.utils.data.DataLoader(trainset, batch_size=train_batch_size, shuffle=True, num_workers=0) -valloader = torch.utils.data.DataLoader(valset, batch_size=val_batch_size, shuffle= False, num_workers=0) -# trainloader = torch.utils.data.DataLoader(trainset, batch_size=1, shuffle=True, num_workers=2) -# trainloader = torch.utils.data.DataLoader(trainset, batch_size=9, shuffle=True, num_workers=0) -# 下载CIFAR10测试集,所以train这个参数这里要设置为False -testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform) -# 加载测试集,测试集不需要打乱 -# testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=0) -# 测试的时候可以不用打乱数据 -# testloader = torch.utils.data.DataLoader(testset, batch_size=1, shuffle=False, num_workers=0) -# testloader = torch.utils.data.DataLoader(testset, batch_size=10, shuffle=False, num_workers=0) -testloader = torch.utils.data.DataLoader(testset, batch_size=test_batch_size, shuffle=False, num_workers=0) -# testloader = torch.utils.data.DataLoader(testset, batch_size=9, shuffle=False, num_workers=0) - - - - -# 定义CIFAR10数据集的十分类类别 -classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck') - -import numpy as np -# import matplotlib.pyplot as plt - - - - -# 定义一个展示图片的函数 -def imshow(img): - img = img / 2 + 0.5 - npimg = img.numpy() - # plt.imshow(np.transpose(npimg, (1, 2, 0))) - # plt.show() - -#因为这块只是展示图片,没太多必要,所以先注释掉 - -# 从数据迭代器中读取一张图片 -#dataiter = iter(trainloader) - -#images, labels = next(dataiter) - -# # 展开图片 -#imshow(torchvision.utils.make_grid(images)) - -# #打印标签 -#print(''.join('%15s' % classes[labels[j]] for j in range(4))) - -import torch.nn as nn -import torch.nn.functional as F -class Net(nn.Module): - def __init__(self): - super(Net,self).__init__() - #定义两个卷积层 - # self.conv1 = nn.Conv2d(3,6,5) - # self.conv2 = nn.Conv2d(6,16,5) - # 第一个卷积层,输入通道数为3(因为是RGB图片,有3个颜色通道),输出通道数为6,这个是可以随意设置,卷积核大小为3*3 - # self.conv1 = nn.Conv2d(3,6,3) - # 如果卷积核是3*3,那么给周围填充1,刚好尺寸不变 - self.conv1 = nn.Conv2d(3,64,3,padding=1) - # 第二个卷积层,输入通道数为6,因为上次卷积之后输出是6个特征图,输出通道数为16,这个是可以随意设置,卷积核大小同样为3*3 - self.conv2 = nn.Conv2d(64,64,3,padding=1) - #新增加一个卷积层,因为上一个卷积层输出是16个特征图,所以输入通道数为16,输出通道数为16,这个是可以随意设置,卷积核大小同样为3*3 - self.conv3 = nn.Conv2d(64,128,3,padding=1) - self.conv4 = nn.Conv2d(128,128,3,padding=1) - self.conv5 = nn.Conv2d(128,256,3,padding=1) - self.conv6 = nn.Conv2d(256,256,3,padding=1) - self.conv7 = nn.Conv2d(256,256,3,padding=1) - self.conv8 = nn.Conv2d(256,512,3,padding=1) - self.conv9 = nn.Conv2d(512,512,3,padding=1) - self.conv10 = nn.Conv2d(512,512,3,padding=1) - # self.conv11 = nn.Conv2d(512,512,3,padding=1) - # self.conv12 = nn.Conv2d(512,512,3,padding=1) - # self.conv13 = nn.Conv2d(512,512,3,padding=1) - - # 做了批归一化,能有效避免梯度消失和梯度爆炸 - self.bn64 = nn.BatchNorm2d(64) - self.bn128 = nn.BatchNorm2d(128) - self.bn256 = nn.BatchNorm2d(256) - self.bn8 = nn.BatchNorm2d(512) - self.bn9 = nn.BatchNorm2d(512) - self.bn10 = nn.BatchNorm2d(512) - # self.bn11 = nn.BatchNorm2d(512) - # self.bn12 = nn.BatchNorm2d(512) - # self.bn13 = nn.BatchNorm2d(512) - # self.conv3 = nn.Conv2d(16,9,3) - #再增加一个卷积层 - # self.conv4 = nn.Conv2d(16,6,1) - #定义池化层,池化核大小为2*2 - self.pool = nn.MaxPool2d(2,2) - #定义三个全连接层 - # self.fc1 = nn.Linear(16*5*5,120) - #每次输入4个样本,每个样本有3个通道,所以输入通道数为4*3*3*3 - # self.fc1 = nn.Linear(16*3*3,120) - # self.fc1 = nn.Linear(16*4*3*3,120) - # self.fc1 = nn.Linear(16*4,120) - # self.fc1 = nn.Linear(16*16*2*169,120) - # self.fc1 = nn.Linear(73728,120) - # self.fc1 = nn.Linear(256*22*22,120) - # self.fc1 = nn.Linear(256*4*4,120) - # self.fc1 = nn.Linear(512*4*4,120) - # self.fc1 = nn.Linear(512*4*4,800) - self.fc1 = nn.Linear(512*2*2,800) - # self.fc1 = nn.Linear(256*5*5,120) - # self.fc1 = nn.Linear(144*16*16*2,120) - # self.fc1 = nn.Linear(6,120) - # self.fc1 = nn.Linear(4*4*4*3*3,120) - # self.fc2 = nn.Linear(120,84) - self.fc2 = nn.Linear(800,84) - # self.fc4 = nn.Linear(84,84) - # self.fc5 = nn.Linear(84,84) - # self.fc2 = nn.Linear(120,84) - self.fc3 = nn.Linear(84,10) - # 增加drop-out层,丢弃概率 - # self.dropout = nn.Dropout(0.5) - - - - # 定义前向传播,模型的关键还在于前向传播 - def forward(self,x): - # x = self.pool(F.relu(self.conv1(x))) - x = F.relu(self.bn64(self.conv1(x))) - x = self.pool(F.relu(self.bn64(self.conv2(x)))) - # x = self.pool(F.relu(self.conv2(x))) - # x = F.relu(self.conv2(x)) - # x = self.pool(F.relu(self.conv3(x))) - # x = F.relu(self.conv3(x)) - x = F.relu(self.bn128(self.conv3(x))) - - # x = F.relu(self.conv4(x)) - # x = self.pool(F.relu(self.conv4(x))) - x = self.pool(F.relu(self.bn128(self.conv4(x)))) - # x = F.relu(self.conv5(x)) - x = F.relu(self.bn256(self.conv5(x))) - # x = self.pool(F.relu(self.conv5(x))) - x = F.relu(self.bn256(self.conv6(x))) - # x = F.relu(self.conv7(x)) - # x = self.pool(F.relu(self.conv7(x))) - x = self.pool(F.relu(self.bn256(self.conv7(x)))) - # x = self.pool(F.relu(self.bn8(self.conv8(x)))) - x = F.relu(self.bn8(self.conv8(x))) - # x = F.relu(self.bn9(self.conv9(x))) - x = self.pool(F.relu(self.bn9(self.conv9(x)))) - x = F.relu(self.bn10(self.conv10(x))) - # x = self.pool(F.relu(self.bn10(self.conv10(x)))) - # x = F.relu(self.bn11(self.conv11(x))) - # x = F.relu(self.bn12(self.conv12(x))) - # x = F.relu(self.bn13(self.conv13(x))) - #变换x的形状以适配全连接的输入,因为全连接层输入必须是二维的,所以需要将x的形状变成二维的,因为图片是32*32*3,需要将三维变量拉长 - # x = x.view(-1,16*5*5) - # x = x.view(-1,16*3*3) - # x = x.view(-1,16*4*3*3) - # x = x.view(-1,16*4) - # x = x.view(-1,16*16*2*169) - # x = x.view(-1,73728) - # x = x.view(-1,256*22*22) - # x = x.view(-1,256*4*4) - # x = x.view(-1,512*4*4) - x = x.view(-1,512*2*2) - # x = x.view(-1,256*5*5) - # x = x.view(-1,144*16*16*2) - # x = x.view(-1,6) - # x = x.view(-1,4*4*4*3*3) - # x = self.dropout(x) - x = F.relu(self.fc1(x)) - # x = self.dropout(x) - x = F.relu(self.fc2(x)) - # x = self.dropout(x) - # x = F.tanh(self.fc2(x)) - # x = F.sigmoid(self.fc2(x)) - # x = F.relu(self.fc4(x)) - # x = F.relu(self.fc5(x)) - x = self.fc3(x) - # print(x.shape) - return x - -net = Net().to(device) -# 直接加载训练好的模型,就不需要从头开始训练了。如果不加载,一上来损失就是2.290,很高。如果加载了模型,一上来损失只有0.127,效果太明显了,这就是微调的作用 -# net.load_state_dict(torch.load('./cifar_net56.pth')) -# num_classes,代表最终分类的数量,因为CIFAR10有10个分类,所以这里要设置为10 -# net = resnet18(pretrained=False, num_classes=10).to(device) -# net = resnet18(pretrained=True, num_classes=10).to(device) -# net = resnet18(pretrained=True) -# net = resnet34(pretrained=True) -# net = resnet50(pretrained=False) -# net = resnet101(pretrained=True) - -# 冻结模型的所有层,除了最后的全连接层 -# for param in net.parameters(): -# param.requires_grad = False -# -# last_layer = net.fc -# # 替换最后一个全连接层 -# num_classes = 10 # CIFAR10的数据类数为10 -# new_last_layer = torch.nn.Linear(last_layer.in_features, num_classes) -# net.fc = new_last_layer - -# num_ftrs = net.fc.in_features -# net.fc = nn.Linear(num_ftrs, 10) -# 检查是否有可用的GPU,如果有多个GPU,则使用 DataParallel -if torch.cuda.device_count() > 1: - print(f"Let's use {torch.cuda.device_count()} GPUs") - net = nn.DataParallel(net) -net.to(device) -print(net) - -import torch.optim as optim -# 定义损失函数,CrossEntropyLoss()是交叉熵损失函数 -criterion = nn.CrossEntropyLoss() -#原本是0。001,改为0.0001 -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9) -optimizer = optim.Adam(net.parameters(),lr = 0.0001) -# 只更新全连接层的参数,把卷积层的参数冻结,不更新 -# optimizer = optim.SGD(net.fc.parameters(),lr = 0.0001, momentum = 0.9) -# optimizer = optim.SGD(net.fc.parameters(),lr = 0.0002, momentum = 0.9) -# optimizer = optim.SGD(net.parameters(),lr = 0.0002, momentum = 0.9) -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9,weight_decay=0.001) -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9,weight_decay=0.01) -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9,weight_decay=0.005) -# optimizer = optim.SGD(net.parameters(),lr = 0.0005, momentum = 0.9) -# optimizer = optim.SGD(net.parameters(),lr = 0.00001, momentum = 0.9) -# optimizer = optim.SGD(net.parameters(),lr = 0.001, momentum = 0.9) -# optimizer = optim.SGD(net.parameters(),lr = 0.3, momentum = 0.9) -# optimizer = optim.SGD(net.parameters(),lr = 0.5, momentum = 0.9) -# optimizer = optim.SGD(net.parameters(),lr = 1, momentum = 0.9) -# 为了避免过拟合,考虑加入正则化,1e-4 -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9, weight_decay=0.003) -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9, weight_decay=0.005) -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9, weight_decay=0.01) -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9, weight_decay=0.001) -# optimizer = optim.SGD(net.parameters(),lr = 0.0001, momentum = 0.9, weight_decay=0.0001) -# optimizer = optim.SGD(net.parameters(),lr = 0.001, momentum = 0.9) -# optimizer = optim.SGD(net.parameters(),lr = 0.01, momentum = 0.9) -# 使用ADAM梯度下降方法 -# optimizer = optim.Adam(net.parameters(),lr = 0.01) - - -# min_loss = 0.3 -# min_loss = 0.3 -# - -midModelPath = './cifar_net103.pth' -finallPATH = './cifar_net104.pth' -max_val_score = 0 -break_max_val = False -epoch_list = [] -val_acc_list = [] -# 每次验证的正确率 -every_val_acc = '' - -def train(epoch): - # net = Net().to(device) - # print(net) - # net.load_state_dict(torch.load('./cifar_net76.pth')) - # net.load_state_dict(torch.load('./cifar_net75.pth',map_location= 'cpu')) - min_loss = 0.3 - for epoch in range(epoch): - running_loss = 0.0 - # 该代码片段使用enumerate()函数遍历trainloader数据加载器,并为每个数据项提供一个索引。 - # enumerate()函数从0开始计数,并将每个数据项和相应的索引存储在一个元组中, - # 然后将这些元组传递给循环中的变量i和data。这样可以在遍历数据时轻松地访问每个数据项的索引, - # 以便执行相应的操作。 - for i,data in enumerate(trainloader,0): - inputs,labels = data - # print(inputs) - - - #将梯度清零,如果不清零,梯度会累加,导致梯度爆炸,或者梯度消失,导致训练效果不好 - optimizer.zero_grad() - #得到输出张量 - outputs = net(inputs.to(device)) - # print(outputs.shape) - # print(labels.shape) - #计算损失值 - loss = criterion(outputs,labels.to(device)) - #进行反向传播 - loss.backward() - #更新参数 - optimizer.step() - - #打印训练信息 - running_loss += loss.item() - # if(i +1)% 2000 == 0: - # if(i +1)% 100 == 0: - if(i +1)% 10 == 0: - - runTime = time.strftime("%H小时%M分%S秒", time.gmtime(time.time() - start_time)) - tqdm.write(f"Runtime:{Fore.GREEN}{runTime}{Style.RESET_ALL}") - - - # print('[第%d轮, 训练%5d个样本] loss : %.3f' % (epoch +1, (i+1)*train_batch_size,running_loss /2000)) - tqdm.write( - f"第{Fore.YELLOW}{epoch+1}{Style.RESET_ALL}轮,训练{Fore.YELLOW}{(i+1)*train_batch_size}{Style.RESET_ALL}个样本, loss: {Fore.CYAN}{running_loss/2000}{Style.RESET_ALL}") - sys.stdout.flush() # 强制刷新输出缓冲区 - # 以时分秒的形式打印下程序运行时长 - # print('Runtime:',time.strftime("%H:%M:%S",time.gmtime(time.time()-start_time))) - # print('Runtime:',time.strftime("%H小时%M分%S秒",time.gmtime(time.time()-start_time))) - torch.save(net.state_dict(), midModelPath) - verify() - global break_max_val - if (break_max_val): - tqdm.write( - # f"{Back.LIGHTBLUE_EX} {Fore.LIGHTRED_EX}🔥 打破记录了!!!{Back.RESET}{Style.RESET_ALL}") - f"{Fore.LIGHTRED_EX}🔥 打破记录了!!!{Style.RESET_ALL}") - mytestTrainSet() - eval() - # if running_loss/2000 < min_loss: - # if running_loss/2000 < min_loss: - # print('打破记录') - # min_loss = running_loss/2000 - # # PATH = './cifar_net70.pth' - # PATH = midModelPath - # torch.save(net.state_dict(),PATH) - # # 打印验证集精度 - # verify() - # # 打印训练集精度 - # testTrainSet() - # 刷新输出缓冲区,作用是确保输出信息立即显示在控制台上,不然在云服务器上半天显示不出来 - sys.stdout.flush() - running_loss = 0.0 - print("") - print('完成训练') - # - # PATH = './cifar_net71.pth' - PATH = finallPATH - # # # # #保存模型 - torch.save(net.state_dict(),PATH) - eval() - - - -def trainResNet(epoch): - net.load_state_dict(torch.load('./cifar_net101.pth',weights_only=True)) - min_loss = 0.3 - # 加载预训练的ResNet模型(如果需要从头开始训练,则可以去掉预训练权重) - # net = resnet18(pretrained=False, num_classes=10) - # print(net) - for epoch in range(epoch): - running_loss = 0.0 - # 该代码片段使用enumerate()函数遍历trainloader数据加载器,并为每个数据项提供一个索引。 - # enumerate()函数从0开始计数,并将每个数据项和相应的索引存储在一个元组中, - # 然后将这些元组传递给循环中的变量i和data。这样可以在遍历数据时轻松地访问每个数据项的索引, - # 以便执行相应的操作。 - for i,data in enumerate(trainloader,0): - inputs,labels = data - - #将梯度清零,如果不清零,梯度会累加,导致梯度爆炸,或者梯度消失,导致训练效果不好 - optimizer.zero_grad() - #得到输出张量 - outputs = net(inputs.to(device)) - #计算损失值 - loss = criterion(outputs,labels.to(device)) - #进行反向传播 - loss.backward() - #更新参数 - optimizer.step() - - #打印训练信息 - running_loss += loss.item() - if(i +1)% 2000 == 0: - - runTime = time.strftime("%H小时%M分%S秒", time.gmtime(time.time() - start_time)) - tqdm.write(f"Runtime:{Fore.GREEN}{runTime}{Style.RESET_ALL}") - - # print('[第%d轮, 训练%5d个样本] loss : %.3f' % (epoch +1, (i+1)*train_batch_size,running_loss /2000)) - - tqdm.write( - f"第{Fore.YELLOW}{epoch + 1}{Style.RESET_ALL}轮,训练{Fore.YELLOW}{(i + 1) * train_batch_size}{Style.RESET_ALL}个样本, loss: {Fore.CYAN}{running_loss / 2000}{Style.RESET_ALL}") - - # 以时分秒的形式打印下程序运行时长 - # print('Runtime:',time.strftime("%H:%M:%S",time.gmtime(time.time()-start_time))) - # print('Runtime:',time.strftime("%H小时%M分%S秒",time.gmtime(time.time()-start_time))) - - # if running_loss/2000 < min_loss: - # print('打破记录') - # min_loss = running_loss/2000 - # PATH = midModelPath - # # PATH = './cifar_net67.pth' - # # #保存模型 - # torch.save(net.state_dict(),PATH) - # verify() - torch.save(net.state_dict(), midModelPath) - verify() - global break_max_val - if (break_max_val): - tqdm.write( - # f"{Back.LIGHTBLUE_EX} {Fore.LIGHTRED_EX}🔥 打破记录了!!!{Back.RESET}{Style.RESET_ALL}") - f"{Fore.LIGHTRED_EX}🔥 打破记录了!!!{Style.RESET_ALL}") - mytestTrainSet() - eval() - # 刷新输出缓冲区,作用是确保输出信息立即显示在控制台上,不然在云服务器上半天显示不出来 - sys.stdout.flush() - running_loss = 0.0 - print("") - epoch_list.append(epoch + 1) - val_acc_list.append(every_val_acc) - if (epoch + 1) % 5 == 0: - draw(epoch_list, val_acc_list) - - print('完成训练') - # - # PATH = './cifar_net68.pth' - PATH = finallPATH - # # # # #保存模型 - torch.save(net.state_dict(),PATH) - eval() -# - - -#在整个测试集上测试模型的准确率,53%,比之前55%还降了两个百分点。加了一层,正确率变成了46%,妹的,打算训练十次,看看,训练了十次,正确率变成39%,奶奶个熊 -#直接把学习率改成0.0001,训练了十次,损失变为1.163,降了很多。突然正确率又提升到了56% -#决定把卷积层又恢复成两层,看看效果。因为batch给了9,一下子就训练完了,loss值为1.455,正确率为48%,效果不佳, -#加层数反而效果不好,可能加的不够好吧,然后把训练十次,改为30次,试试,第12轮的时候,损失为1.087,感觉正确率一定会超过56%,再训练第30轮的时候,有一次损失才0.793 -#最终的损失是0.854,有点回升了。最终正确率为63%,如果在最低的损失值时,保存模型,那么正确率应该会更高。 -#发现卷积层和全连接层没有必然联系,所以去掉了一个全连接层,试试效果。第12轮的时候,损失为1.027,但是很可惜,没有保存模型。 -# 打算训练100轮,试试效果,这就好比把卷子做50遍,效果可能不太好,那就做100遍,相信效果会好很多。迭代100次太慢了,第42抡,有一次损失是0.727,也不确定会不会降低到0.6以下。 -# 回家路上没有关电脑,不然又要重新训练。电脑烫死了,在59轮时,有一次损失是0.642。感觉100轮下来,还真有可能降低到0.6以下。70论的时候,有一次损失是0.616.第82轮的时候, -# 有一次降到了0.581,可惜因为之前程序写的不对,没法保存那个模型。最终的损失是0.697.正确率为61%,好气人,竟然降了。然后在训练集上跑了下,正确率为78%。不是很高,也就是说 -#给它开卷考试,满分100分,也只能得到78分,说明学的还是不够。 -#准备采用VGG网络架构,第一层卷积层直接从6个卷积核提升到64个卷积核,第二层也是64个卷积核,第三层128个卷积核,第四层也是128个卷积核。准备训练10轮,看看效果 -# 在第九轮的时候,直接损失降低到0.560,这可是之前从来没有过的好成绩,说明还是得卷积盒多一些才可以。但是因为程序没写好,被多次覆盖掉。第十轮有一次损失是0.482 -# 最终损失是0.565.在训练集上的正确率是84%,显著提升,在测试集上的正确率是73%,很厉害了 -# 现在直接改造成了10层卷积层,哈哈,按照VGG的前十层架构,进行训练,然后把池化层去掉了,因为池化层经过三轮之后,变成2*2大小了,用3*3的卷积核没法计算了 -# 网络层数加深之后,明显计算太慢了。下班也训练不完,打算训练五轮试试,看看一个小时能不能训练完,发现层数太深了,根本就训练不动,可能是由于链式法则,乘的数太多了, -# 导致每次只往前走一丁点,所以,可以考虑把学习率提高。 -# 还是用三层架构,训练到第13抡,损失为0.019.我的天呐,牛啊,训练到第16抡,有一次损失为0.015,牛逼。训练到第18轮,有一次损失为0.006,不断降低损失,刷新记录。 -# 在第29轮的时候,有一次损失为0.001.太吊了吧。在测试集上的正确率是69%,在训练集上的正确率是99%,很棒,说明是过拟合了。 -#准备加上正则化,看看效果。计划训练30轮,在服务器上训练。 -# 加上正则化后,在测试集上正确率是68%,在训练集上正确率是97%,我的天呐,还是解决不了过拟合的问题。 -# 打算把正则化提升点,试试效果,加入正则化之后,在第17轮的时候,损失降到0.012.在训练集上的正确率是99%,在测试集上的正确率是69%,并且测试了两个模型, -# 还包括一个损失为0.010的,测试集上正确率也是69%,说明还是过拟合了。决定再次把正则化的系数从0.001,改为0.01,看看效果。 -# 修改成0.01之后,训练了20轮,用时15个小时,最终损失为0.761,降不下去,然后在训练集上正确率为81%,在测试集上正确率是67%,反而效果还差了, -# 那就又将正则化惩罚项系数改为0.005,看看效果。在第14轮的时候,损失降到0.208.到时候看看结果,如果结果不理想,就继续把系数往下降。 -# 第15轮的时候降到了0.188,看来有机会低于0.1啊。 -# 最终损失是0.303,在测试集上正确率是66%,在训练集上正确率是96%。 -# 打算把正则化惩罚项系数改为0.003,看看效果,最低的损失是0.058,在测试集上的正确率是66%,在训练集上的正确率是96%。过拟合问题太难搞了 -# 加入drop-out,试试效果,给三个卷积层都加入了dropout -# dropout比例设置为0.5,损失到1.8附近,就不往下降了。调到0.1试试 -# 不知道咋回事,加入dropout效果并不好,训练了三十轮,损失降不下去,也不知道是不是因为学习率为0.001的缘故, -# 现在把dropout去掉,加入数据增加,平移,反转,遮盖,来试试效果。 -# 不知道咋回事,训练了30抡,损失是0.542,也太差了吧。在训练集上精度是80%,在测试集上精度是75%,竟然不过拟合了,不过损失为什么降不下去 -# 打算再加一层卷积层,一共四个卷积层,试试,最终损失0.482,在训练集上的精度是83%,在测试集上的精度是79%,哇塞,有提升,终于快接近80%了。 -# 打算再加一层,加到五个卷积层,这样,应该就可以上80%了 -# 五层卷积层,最终损失为0.470,在训练集上的精度是84%,在测试集上的精度是80%,哇偶,终于上80%了 -# 五层卷积层,最佳损失为0.422,在训练集上的精度是83%,在测试集上的精度是80% -# 打算第二层卷积层后面加个池化层,在五层卷积层后面也加个池化层,看看效果。 -# 加入池化层之后,第六轮22000样本,只用了1小时15分钟,没加池化层之前用了1小时17分钟。我以为训练速度会加快的,并没有 -# 训练完30轮,最终只用了7小时4分钟,不加池化层,用了6小时58分钟,我咋记得得二十几个小时呢。训练的模型只需要4.04M,之前都是40M-58M这样 -# 加入两个池化层之后,最终损失是0.512,在训练集上的精度是84%,在测试集上的精度是80% -# 加入两个池化层之后,最佳损失是0.423,在训练集上的精度是84%,在测试集上的精度是80% -# 看来加入池化层,对于提高精度作用不大,那就继续增加网络层数吧。 -# 再加上六七两个卷积层,但是加上这两层之后,训练不动了,损失不往下降,试着把学习率从0.0001改为0.00001试试 -# 好像还是不行,那就把学习率提高为0.001,试试,后来发现能训练得动,比较慢而已 -# 再加两个卷积层之后,最终损失是0.461,在训练集上的精度是84%,在测试集上的精度是80%。30轮训练用时12个小时,之前也就7个小时左右,因为网络更复杂了 -# 也不知道是不是因为30轮,还不够,打算再训练20轮,看看效果,看看损失能不能降到0.4以下 -# 在进行到第43轮的时候,损失为0.334,在训练集上的精度是87%,在测试集上的精度是82%,哇塞,果然被自己猜对了,我就是加了两层网络,怎么可能精度没有变化呢。 -# 最佳损失为0.298,在训练集上的精度是89%,在测试集上的精度是83%,哇偶,开心,果然增加模型复杂度,可以提升精度 -# 最终损失为0.371,在训练集上的精度是88%,在测试集上的精度82% -# 决定再加上三层卷积层,3个512特征图,然后训练轮数从50轮提升到70轮,看看效果。并将学习率从0.0001提高到0.0005,避免训练不动 -# 将学习率提升到0.5,训练了一个晚上,损失还是3.7,根本不往下降。 -# 问了下ai,这种情况应该是属于梯度消失了,可以采用批归一化,试试 -# 哇塞,果然是梯度消失了,给新加的三个卷积层加入批归一化之后,采用0.0001的学习率,明显可以训练得动了。 -# 训练了70轮,用了四五天,第一次花这么长时间用来训练,耗时为什么这么长,主要是因为模型更复杂了,而且batch_size给的太小了 -# 最佳损失0.404,在训练集上的精度是85%,在测试集上的精度是80% -# 最终损失0.504,在训练集上的精度是84%,在测试集上的精度是79% -# 加了三层卷积层之后,竟然效果还没有之前好,有点欠拟合。但是我发现好像增加训练轮数,也训练不动了。 -# 弄上阿里云的gpu之后,再训练30轮试试,毕竟用上了GPU,一轮也就6分钟,30轮,也就3小时左右, -# 在GPU上训练可太快了,而且是英伟达A10的GPU,简直狂飙啊。一轮只用了3分钟,比昨天自己用的那个GPU快多了 -# 而且因为自己的batch_size设置的是1,而且num_workers设置的是0,不然会更快,我的天! -# 不知道咋搞的,设置了30轮,但是只训练了15轮 -# 最佳损失是0.341,在训练集上的精度是88%,在测试集上的精度是82% -# 最终损失是0.412,在训练集上的精度是88%,在测试集上的精度是81% -# 又训练了十轮 -# 最佳损失是0.270,在训练集上的精度是%,在测试集上的精度是81% -# 最终损失是0.309,在训练集上的精度是%,在测试集上的精度是82% - -# 还有一点,我觉得最后的全连接,从8192直接到120,是不是120给的太小了,可以给到1000? -# 发现这里面没有padding层,可以考虑加个padding层,看看效果。 -# 给每个卷积层增加了padding=1,这样卷积过程中尺寸不变,然后弄了三个池化层,最终的特征图尺寸是4*4*512, -# 增加padding了之后,扫描用的时间可能会多一些。 -# 效果竟然出奇的好,在24轮的时候,损失为0.254,在训练集上的精度是90%,在测试集上的精度是85% -# 最终损失0.138,在训练集上的精度是95%,在测试集上的精度是87% -# 最佳损失为0.111,在训练集上的精度是95%,在测试集上的精度是87% -#打算把第二个全连接层参数从120,换成800,然后把num_workers从0换成2,试试效果 -# 在第44轮的时候,损失为0.113,在训练集上的精度是95%,在测试集上的精度是88% -# 我的天,太炸裂了,又提升了一个百分点,而且这次因为不急着回去,可以训练70轮,我觉得最终还会涨一点点 -# 最佳损失0.067,在训练集上的精度是%,在测试集上的精度是87% -# 最终损失0.089,在训练集上的精度是97%,在测试集上的精度是89%,这个就训练的很充分了 -# 我的天,也太牛逼了,果然又提升了一个百分点,哈哈,这真是可喜可贺啊 -# 然后决定再加上三层的512特征图,这样就是完整的VGG16了,看看还能不能提高一两个百分点。冲90%有希望了呀。 -# 训练了46轮,损失是0.154,因为要下班了,所以就暂停,明天继续训练,然后明天再训练30轮,我觉得会破记录的。 -# 最佳损失0.087,在训练集上的精度是96%,在测试集上的精度是87% -# 最终损失0.109,在训练集上的精度是%,在测试集上的精度是87% -# 我觉得可能是训练不够充分吧,不然不可能还不如从前了,要么就是过拟合了,现在有两种办法,第一,增加20轮训练,第二,增加dropout。 -# 又训练了20轮 -# 最佳损失0.063,在训练集上的精度是%,在测试集上的精度是88% -# 最终损失XX,在训练集上的精度是96%,在测试集上的精度是88% -# 打算增加dropout,看看效果,之前可能dropout加的不对 -# 在第一个全连接层,和第二个全连接层,增加dropout,比例为0.2 -# 训练40轮,试试,之前那个GPU-DSW打不开了,重新弄了个,下载数据集好快啊 -# 后面可以考虑把batch_size调大一些,这样训练更快 -# 训练了40轮,最佳损失为0.212,在训练集上的精度是90%,在测试集上的精度是84% -# 最终损失0.260,在训练集上的精度是89%,在测试集上的精度是83% -# 好像泛化能力比之前能好一点,从8-9个点,减少到6个点, -# 因为今天周六,现在已经晚上八点,训练不了多久,再来十轮,把batch_size设置为10 -# 把batch_size设置为10,现在训练速度更快了,太厉害了 -# 既然训练速度这么快,那就干脆再训练20轮,反正20轮,20分钟就完了,原本每轮得4分钟,需要80分钟, -# 哈哈,自己太笨了,不然早点把batch_size调大了。 -# 再经过了20轮,相当于总共训练了70轮 -# 最佳损失是0.109,在训练集上的精度是96%,在测试集上的精度是88% -# 最终损失是0.115,在训练集上的精度是%,在测试集上的精度是88% -# 再训练20轮,相当于训练了90轮 -# 最佳损失是0.092,在训练集上的精度是96%,在测试集上的精度是88% -# 最终损失是0.096,在训练集上的精度是%,在测试集上的精度是% -# 明天打算把dropout丢弃比例设置为0.5,训练100轮试试看 -# 训练了100轮,只用了1小时14分钟,果然batch_size作用很大啊 -# 但是大的batch_size可能需要更多的轮数。因为反向传播的次数相对比较少 -# 最终损失0.159,最佳损失0.149。可能是因为drop-out0.5,所以损失有点大. -# 打算再训练50轮,看看效果 -# 最佳损失0.088,在训练集上的精度是97%,在测试集上的精度是87% -# 我晕死,我感觉这个drop-out没有发挥作用啊。 -# 那不要drop-out了,继续搞正则化试试,反正就是炼丹嘛,哈哈 -# 先把正则化惩罚项弄个0.001试试。 -# 直接训练150轮,试试 -# 最佳损失为0.091,在训练集上的精度是96%,在测试集上的精度是87% -# 真是一个让人失望的结果啊,明天把正则化系数提升下,训练150轮试试 -# 将正则化系数设置为0.01,训练150轮 -# 训练了150轮,最终损失为0.351,在训练集上的精度是89%,在测试集上的精度是84% -# 再训练上100轮,看看效果,损失不太好往下降。 -# 又训练了50轮,损失还是0.345,降不下去了。 -# 打算把正则化惩罚项系数调整为0.005,训练200轮试试 -# 最终损失为0.200,在训练集上的精度是93%,在测试集上的精度是85% -# 最佳损失为0.176,在训练集上的精度是94%,在测试集上的精度是86% -# 效果不明显啊,打算再训练100轮试试,感觉还是没有解决过拟合的问题 -# 又训练了40轮,损失为0.167,在训练集上的精度是%,在测试集上的精度是86% -# 训练到100轮,最终损失为0.173,没有太大变化,在测试集上的精度是85% -# 直接把正则化惩罚项系数去掉,然后直接用一个预训练的ResNet18来训练下,看看效果 -# 这一次pretrained=False,是一个空的模型,需要自己训练,下次可以直接pretrained=True,用一下它训练好的参数,试试 -# 训练了100轮,损失降到0.60左右,打算再训练100轮试试 -# 又训练了150轮,共250轮,最终损失为0.355,那就再训练150轮。 -# 为什么要训练那么多轮数,是因为真的Resnet18比自己之前的网络要更复杂。 -# 共训练了400轮,损失为0.233,在训练集上的精度是91%,在测试集上的精度是81% -# 再训练100轮吧。 -# 这个ResNet18收敛速度太慢了, -# 共训练了500轮,最佳损失为0.193,模型保存文件为64 -# 打算继续训练下去,但是现在没时间了,只能明天,打算试一下预训练模型,看看效果 -# 把卷积层的参数冻结了,只训练全连接层的参数,看看效果 -# 共训练了700轮,最终损失为0.189,在测试集上的精度是81% -# 最佳损失为0.167,在训练集上的精度是%,在测试集上的精度是82% -# 原来这200轮训练的只是全连接层的参数,难怪损失降不下去,重新训练200轮吧。 -# 第648轮的时候,损失为0.145,在训练集上的精度是94%,在测试集上的精度是81% -# 严重过拟合,干脆先不用ResNet了,先用自己搭建的VGG试试,给每层加上批归一化,说不定可以上90% -# 第84轮,损失为0.111,在训练集上的精度是95%,在测试集上的精度是87% -# 第116轮,损失为0.076,在训练集上的精度是97%,在测试集上的精度是88% -# 第176轮,损失为0.049,在训练集上的精度是98%,在测试集上的精度是88% -# 最终损失0.050,在测试集上的精度是89% -# 最佳损失0.044,在训练集上的精度是98%,在测试集上的精度是89% -# 又训练了60轮,最佳损失为0.031,最终损失为0.038,在测试集上的精度都是89% -# 又训练了40轮,最佳损失为0.029,在训练集上的精度是98%,在测试集上的精度是90%,明天看看能不能把损失降到0.01以下 -# 我的天,上了90%,对得起自己熬夜到了23:26,哈哈。 -# 再训练100轮试试,看看能降到0.01以下不。 -# 第54轮,损失为0.024,在训练集上的精度是99%,在测试集上的精度是90%,稳稳妥妥的上了90%,看来批归一化效果还是很明显的,之前一直上不来 -# 最佳损失0.021,不训练了,换成Adam试试 -# 明天可以考虑把SGD换成Adam试试,然后也可以在程序中加入在测试集上的精度,随时打印输出 -# 还有一个AdamW,是Adam的变种,也可以试试 -# 换成Adam,然后加入了验证集,训练200轮试试。 -# 带上验证集还挺好的,可以损失监督模型在验证集上的精度 -# 训练了90轮,损失为0.096,在验证集上的精度是88% -# 明天继续训练,再来200轮,看看会不会上91% -# 我明白验证集昨天好好的,但是今天突然就很高,就是因为训练集和验证集是随便划分的,今天的验证集中的数据,昨天是出现在训练集里的,所以拟合程度会更高一些。 -# 第261轮,损失为0.042,在训练集上的精度是98%,在测试集上的精度是90% -# 第300轮,损失为0.047,在测试集上的精度是90% -# 第414轮,损失为0.035,在训练集上的精度是98%,在测试集上的精度是90% -# 第459轮,损失为0.034,在测试集上的精度是90%,损失好像也降不下去了。 -# 自从换成彩色的日志之后,训练集的精度小于验证集的精度,这个不合理,可能还是程序写的有问题。 -# 训练到后面,训练集的精度就高于验证集和测试集的了 -# 把网络结构搞简单一点,说不定泛化能力更强呢。去掉后面三个512的卷积层,试试效果 -# 在第123轮时,损失为0.075,在验证集上的精度是90.8%,在训练集上的精度是97.7%,在测试集上的精度是89.54% -# 在第154轮时,损失为0.064,在验证集上的精度是90.94%,在训练集上的精度是97.97%,在测试集上的精度是90.12% -# 在第178轮时,损失为0.060,在验证集上的精度是91.14%,在训练集上的精度是98.24%,在测试集上的精度是90.21% -# 使用预训练ResNet18,加入了验证集,以及验证集精度曲线图 -# 训练到82轮时,损失是为0.285,在验证集上的精度是85.02%,在训练集上的精度是90.92%,在测试集上的精度是84.22% -# 训练到106轮时,损失为0.2314,在验证集上的精度是85.28%,在训练集上的精度是91.79%,在测试集上的精度是83.95% -# 直接改用ResNet34试下,因为我感觉ResNet18泛化能力挺强的,但是有点欠拟合,因此要选择更复杂一点的网络结构 -# 使用ResNet50训练 -# 训练到37轮时,损失为0.3688,在验证集上的精度是84.96%,在训练集上的精度是88.33%,在测试集上的精度是84.13% -# 训练到69轮时,损失为0.265,在验证集上的精度是87.18%,在训练集上的精度是89.01%,在测试集上的精度是84.04% -# 训练到101轮时,损失为0.198,在验证集上的精度是87.44%,在训练集上的精度是93.75%,在测试集上的精度是86.28% -# 训练到119轮时,损失为0.174,在验证集上的精度是87.5%,在训练集上的精度是94.51%,在测试集上的精度是86.54% -# 训练到134轮时,损失为0.1638,在验证集上的精度是87.68%,在训练集上的精度是94.88%,在测试集上的精度是86.00% -# 训练到143轮时,损失为0.1514,在验证集上的精度是87.9%,在训练集上的精度是95.25%,在测试集上的精度是86.83% -# 训练到156轮时,损失为0.1493,在验证集上的精度是87.96%,在训练集上的精度是95.41%,在测试集上的精度是86.41% -# 再继续训练了109轮,损失降为0.104,不过在验证集上的精度是87.4%,不再往下降了 -# 我发现用预训练的效果反而不好,那我就直接只用ResNet50网络结构,而不用它的预训练参数 -# 第120轮时,损失为0.517,在验证集上的精度是80.16%,在训练集上的精度是82.43%,在测试集上的精度是78.76% -# 第200轮时,损失为0.420,在验证集上的精度是81.84%,在训练集上的精度是86.39%,在测试集上的精度是80.4% -# 使用ResNet101预训练模型,并且冻结前面的参数,只更新全连接层 -# 训练到100多轮,其中在验证集上的精度达到46%,基本上就上不去了。 -# 二供上云弄了云服务器,有英伟达V100的显卡,训练了2小时35分钟,第174轮的时候,在验证集上89.9%,训练集上98.49%,在测试集上88.08% - - - - - - - - - - - - -# 后面还可以加上ResNet,据说ResNet在ImageNet比赛的时候,错误率只有3%,好恐怖 - -def modelInfo(): - params_num = sum(p.numel() for p in net.parameters()); - print("当前模型共有%d个参数",params_num) - -def verify(): - PATH = midModelPath - net.load_state_dict(torch.load(PATH, map_location=device,weights_only=True)) - correct = 0 - total = 0 - # 验证的时候,不需要记录梯度,加快速度 - with torch.no_grad(): - for data in valloader: - images, labels = data - outputs = net(images.to(device)) - # _, predicted = torch.max(outputs.data.to('cpu'), 1) - _, predicted = torch.max(outputs.data.to('cpu'), 1) - total += labels.size(0) - correct += (predicted == labels).sum().item() - # print('验证集正确率:%d %%' % (100 * correct / total)) - tqdm.write( - f"验证集正确率: {Fore.BLUE}{100 * correct / total}{Style.RESET_ALL}%") - global max_val_score - global break_max_val - global every_val_acc - every_val_acc = np.mean(correct / total) - if(correct/total > max_val_score): - max_val_score = correct/total - break_max_val = True - else: - break_max_val = False - - -def mytestTrainSet(): - PATH = midModelPath - net.load_state_dict(torch.load(PATH, map_location=device,weights_only=True)) - correct = 0 - total = 0 - # 验证的时候,不需要记录梯度,加快速度 - with torch.no_grad(): - for data in trainloader: - images, labels = data - outputs = net(images.to(device)) - _, predicted = torch.max(outputs.data.to(device), 1) - total += labels.size(0) - correct += (predicted == labels.to(device)).sum().item() - tqdm.write( - f"训练集正确率: {Fore.BLUE}{round(100 * correct / total,2)}{Style.RESET_ALL}%") - - -def eval(): - # net = Net().to(device) - # print(net) - # net = Net() - # # #加载模型 - PATH = midModelPath - # PATH = finallPATH - net.load_state_dict(torch.load(PATH,map_location=device,weights_only=True)) - # net.load_state_dict(torch.load(PATH)) - # for param in net.parameters(): - # print(param) - correct = 0 - total = 0 - # 测试的时候,不需要记录梯度,加快速度 - with torch.no_grad(): - for data in testloader: - # for data in trainloader: - images,labels = data - outputs = net(images.to(device)) - _,predicted = torch.max(outputs.data.to(device),1) - total += labels.size(0) - correct += (predicted == labels.to(device)).sum().item() - # print('正确率:%d %%'% (100*correct /total)) - tqdm.write( - f"测试集正确率: {Fore.BLUE}{round(100 * correct / total,2)}{Style.RESET_ALL}%") - - -def draw(epoch_list,val_acc_list): - plt.plot(epoch_list, val_acc_list) - plt.xlabel("epoch") - plt.ylabel("val_acc") - plt.show() - - - -if __name__ == '__main__': - # eval(); - # verify() - train(200); - # trainResNet(300); - # modelInfo(); - - - diff --git a/faiss_vector_db/build_faiss_index.py b/faiss_vector_db/build_faiss_index.py index c9f6ca7..607d0ab 100644 --- a/faiss_vector_db/build_faiss_index.py +++ b/faiss_vector_db/build_faiss_index.py @@ -563,7 +563,8 @@ def main(): #新索引 #MODEL_PATH = "../model/WholeIngredientRecognition/cosface_20260121_133207/best_cosface_model.pth" #grid_search最佳模型 s=68, m=0.42 1.22 - MODEL_PATH = "../model/WholeIngredientRecognition/grid_search_20260122_112545/best_model_s68.0_m0.42.pth" + # MODEL_PATH = "../model/WholeIngredientRecognition/grid_search_20260122_112545/best_model_s68.0_m0.42.pth" + MODEL_PATH = "../model/WholeIngredientRecognition/grid_search_20260302_092600/best_model_s64.0_m0.4.pth" # MODEL_PATH = "../model/DishClassification/grid_search_20251121_102723/model_s56.0_m0.4.pth" # MODEL_PATH = "../model/DishClassification/cosface_20251111_153649/best_cosface_model.pth" # TRAIN_DIR = "../dataset/ProcessedIngredientRecognition/train"