論文閱讀筆記:《Dataset Distillation by Matching Training Trajectories》

論文閱讀筆記:《Dataset Distillation by Matching Training Trajectories》

    • 1.動機與背景
    • 2.核心方法:軌跡匹配(Trajectory Matching)
    • 3.實驗與效果
    • 4.個人思考與啟發
    • 主體代碼
    • 算法邏輯總結

一句話總結:

這篇論文通過讓合成數據”教“學生網絡沿著專家軌跡走,從而在極小數據量下實現高性能,開創了數據集蒸餾的新范式。后面很多工作都基于這篇工作來進行改進


CVPR2022 github在這里插入圖片描述

1.動機與背景

  • 數據集蒸餾(Dataset Distillation):用一個極小的合成數據集DsynD_{syn}Dsyn?訓練模型,使其在真實測試集上的性能接近用完整訓練集DrealD_{real}Dreal?訓練的模型。
  • 局限性:先前的梯度匹配方法(詳細可看另外一篇博客)只對齊”每一步的梯度“,忽視了模型訓練的長程動態;而完全展開多步優化又代價太高、易不穩定。

2.核心方法:軌跡匹配(Trajectory Matching)

  1. 專家軌跡(Expert Trajectories)

    • 離線預先訓練若干網絡,每隔一個epoch保存一次模型參數{θt?}t=0T\{\theta_{t}^{*} \}_{t=0}^{T}{θt??}t=0T?, 得到”專家軌跡“。
    • 這些軌跡代表真實數據訓練的”理想路徑“,可重復復用,避免再蒸餾時重新訓練大模型。
  2. 軌跡對齊(Long-Range Match)

    • 在合成數據上,從專家軌跡的某個起點 θt?\theta_t^*θt?? 初始化”學生“參數 θt^\hat{\theta_t}θt?^?
    • DsynD_{syn}Dsyn?上做N步梯度下降:

    ? θ^t+n+1=θ^t+n?α?θ?(Dsyn;θ^t+n)\hat{\theta}_{t+n+1}=\hat{\theta}_{t+n}-α?_{θ}?(D_{syn};\hat{\theta}_{t+n})θ^t+n+1?=θ^t+n??α?θ??(Dsyn?;θ^t+n?)

    • 對齊學生在步t+N的參數θ^t+N\hat{\theta}_{t+N}θ^t+N?與專家在更遠的參數θt+M?\theta_{t+M}^*θt+M??, 損失為:
      L=∥θ^t+N?θt+M?∥22∥θt??θt+M?∥22\mathcal{L} = \frac{\left\| \hat{\theta}_{t+N} - \theta_{t+M}^{*} \right\|_{2}^{2}}{\left\| \theta_{t}^{*} - \theta_{t+M}^{*} \right\|_{2}^{2}} L=?θt???θt+M???22??θ^t+N??θt+M???22??
      分母做歸一化,放大信號并自動平衡各層尺度。

    • 外循環(更新合成數據)+內循環(在DsynD_{syn}Dsyn?上模擬N步)結果,借助create_graph=True保留計算圖,將對齊損失反向傳播到合成圖像及可學的學生學習率α\alphaα

  3. 內存優化

    • 不一次性對合成集做匹配,而是在學生網絡的內循環中按小批次(跨類別但每類少量)更新,既保證”每張圖像都被看過“,又大幅節省顯存。

3.實驗與效果

  • 小樣本極端場景:CIFAR-10/100、SVHN 上每類僅 1 或 10 張合成樣本,軌跡匹配比梯度匹配提升約 5–10%。
  • 多分辨率驗證:Tiny-ImageNet (64×64)、ImageNette/ImageWoof (128×128) 均取得顯著增益。
  • 跨架構泛化:雖針對某一網絡訓練,合成集在 ResNet-18、VGG、AlexNet 等不同模型上依舊表現穩健。
  • 消融分析:軌跡長度 MM、內循環步數 NN、匹配目標(參數 vs 輸出)、專家軌跡數量等均對性能有明顯影響,驗證設計合理性。

4.個人思考與啟發

  • ”長程軌跡對齊“勝于”短程梯度對齊“:對齊訓練軌跡(”路徑“)往往比對齊某一步”梯度“更能保證學習行為一致。
  • 雖然可以通過預存儲軌跡和小批次策略提高效率,但是仍然很耗內存。在訓練教師模型的時候,需要把多個教師軌跡存儲下來,在訓練學生模型的時候需要把訓練的參數記錄下來,占用大量的內存與顯存。同時復雜的雙層優化,難以避免復雜度高。

主體代碼

   ''' training '''# 將合成圖像與LR設為可優化image_syn = image_syn.detach().to(args.device).requires_grad_(True)syn_lr = syn_lr.detach().to(args.device).requires_grad_(True)optimizer_img = torch.optim.SGD([image_syn], lr=args.lr_img, momentum=0.5)# 學習率也設置為可優化optimizer_lr = torch.optim.SGD([syn_lr], lr=args.lr_lr, momentum=0.5)optimizer_img.zero_grad()criterion = nn.CrossEntropyLoss().to(args.device)print('%s training begins'%get_time())# 專家軌跡路徑expert_dir = os.path.join(args.buffer_path, args.dataset)if args.dataset == "ImageNet":expert_dir = os.path.join(expert_dir, args.subset, str(args.res))if args.dataset in ["CIFAR10", "CIFAR100"] and not args.zca:expert_dir += "_NO_ZCA"expert_dir = os.path.join(expert_dir, args.model)print("Expert Dir: {}".format(expert_dir))# 加載或部分加載專家軌跡if args.load_all:buffer = []n = 0while os.path.exists(os.path.join(expert_dir, "replay_buffer_{}.pt".format(n))):buffer = buffer + torch.load(os.path.join(expert_dir, "replay_buffer_{}.pt".format(n)))n += 1if n == 0:raise AssertionError("No buffers detected at {}".format(expert_dir))else:expert_files = []n = 0while os.path.exists(os.path.join(expert_dir, "replay_buffer_{}.pt".format(n))):expert_files.append(os.path.join(expert_dir, "replay_buffer_{}.pt".format(n)))n += 1if n == 0:raise AssertionError("No buffers detected at {}".format(expert_dir))file_idx = 0expert_idx = 0random.shuffle(expert_files)if args.max_files is not None:expert_files = expert_files[:args.max_files]print("loading file {}".format(expert_files[file_idx]))buffer = torch.load(expert_files[file_idx])if args.max_experts is not None:buffer = buffer[:args.max_experts]random.shuffle(buffer)# 記錄最佳精度與方差best_acc = {m: 0 for m in model_eval_pool}best_std = {m: 0 for m in model_eval_pool}# --- 蒸餾迭代主循環 ---for it in range(0, args.Iteration+1):save_this_it = False   # 標記本次迭代是否是要保存的最佳合成數據# 將當前迭代進度記錄到 Weights & Biases (W&B)# writer.add_scalar('Progress', it, it)wandb.log({"Progress": it}, step=it)''' Evaluate synthetic data '''# 如果當前迭代在預設的評估點列表中,則評估合成數據在隨機模型上的表現if it in eval_it_pool:for model_eval in model_eval_pool:print('-------------------------\nEvaluation\nmodel_train = %s, model_eval = %s, iteration = %d'%(args.model, model_eval, it))# 打印使用的數據增強策略if args.dsa:print('DSA augmentation strategy: \n', args.dsa_strategy)print('DSA augmentation parameters: \n', args.dsa_param.__dict__)else:print('DC augmentation parameters: \n', args.dc_aug_param)accs_test = []  # 存儲每次評估的測試準確率accs_train = []  # 存儲每次評估的訓練準確率# 重復num_eval 次隨機初始化的模型評估,以平均化隨機性for it_eval in range(args.num_eval):# 隨機初始化一個新模型net_eval = get_network(model_eval, channel, num_classes, im_size).to(args.device) # get a random modeleval_labs = label_syn# 固定合成圖像與標簽,避免在評估時被意外修改with torch.no_grad():image_save = image_synimage_syn_eval, label_syn_eval = copy.deepcopy(image_save.detach()), copy.deepcopy(eval_labs.detach()) # avoid any unaware modification# 將當前合成學習率傳遞給評估函數args.lr_net = syn_lr.item()# 用合成數據訓練并評估 net_eval,返回 (loss, train_acc, test_acc)_, acc_train, acc_test = evaluate_synset(it_eval, net_eval, image_syn_eval, label_syn_eval, testloader, args, texture=args.texture)accs_test.append(acc_test)accs_train.append(acc_train)accs_test = np.array(accs_test)accs_train = np.array(accs_train)acc_test_mean = np.mean(accs_test)acc_test_std = np.std(accs_test)# 如果有新的最佳平均準確率,則更新best_acc并標記保存if acc_test_mean > best_acc[model_eval]:best_acc[model_eval] = acc_test_meanbest_std[model_eval] = acc_test_stdsave_this_it = Trueprint('Evaluate %d random %s, mean = %.4f std = %.4f\n-------------------------'%(len(accs_test), model_eval, acc_test_mean, acc_test_std))# 將評估結果記錄到 W&Bwandb.log({'Accuracy/{}'.format(model_eval): acc_test_mean}, step=it)wandb.log({'Max_Accuracy/{}'.format(model_eval): best_acc[model_eval]}, step=it)wandb.log({'Std/{}'.format(model_eval): acc_test_std}, step=it)wandb.log({'Max_Std/{}'.format(model_eval): best_std[model_eval]}, step=it)# 如果評估改進或周期點,保存合成圖像到 W&B 與本地if it in eval_it_pool and (save_this_it or it % 1000 == 0):with torch.no_grad():image_save = image_syn.cuda()save_dir = os.path.join(".", "logged_files", args.dataset, wandb.run.name)if not os.path.exists(save_dir):os.makedirs(save_dir)# 保存當前迭代的合成圖像與標簽torch.save(image_save.cpu(), os.path.join(save_dir, "images_{}.pt".format(it)))torch.save(label_syn.cpu(), os.path.join(save_dir, "labels_{}.pt".format(it)))# 如果達成新最佳,還額外保存為 bestif save_this_it:torch.save(image_save.cpu(), os.path.join(save_dir, "images_best.pt".format(it)))torch.save(label_syn.cpu(), os.path.join(save_dir, "labels_best.pt".format(it)))# 將像素分布記錄為 W&B 直方圖wandb.log({"Pixels": wandb.Histogram(torch.nan_to_num(image_syn.detach().cpu()))}, step=it)# 可視化合成圖像:若 ipc<50 或 強制保存,則進行網格化展示if args.ipc < 50 or args.force_save:upsampled = image_saveif args.dataset != "ImageNet":# 針對 CIFAR 類數據,將低分辨率圖像放大 4 倍以便觀察upsampled = torch.repeat_interleave(upsampled, repeats=4, dim=2)upsampled = torch.repeat_interleave(upsampled, repeats=4, dim=3)grid = torchvision.utils.make_grid(upsampled, nrow=10, normalize=True, scale_each=True)wandb.log({"Synthetic_Images": wandb.Image(torch.nan_to_num(grid.detach().cpu()))}, step=it)wandb.log({'Synthetic_Pixels': wandb.Histogram(torch.nan_to_num(image_save.detach().cpu()))}, step=it)for clip_val in [2.5]:std = torch.std(image_save)mean = torch.mean(image_save)upsampled = torch.clip(image_save, min=mean-clip_val*std, max=mean+clip_val*std)if args.dataset != "ImageNet":upsampled = torch.repeat_interleave(upsampled, repeats=4, dim=2)upsampled = torch.repeat_interleave(upsampled, repeats=4, dim=3)grid = torchvision.utils.make_grid(upsampled, nrow=10, normalize=True, scale_each=True)wandb.log({"Clipped_Synthetic_Images/std_{}".format(clip_val): wandb.Image(torch.nan_to_num(grid.detach().cpu()))}, step=it)# 如果使用 ZCA 預處理,還需要保存和可視化反變換后的圖像if args.zca:image_save = image_save.to(args.device)image_save = args.zca_trans.inverse_transform(image_save)image_save.cpu()torch.save(image_save.cpu(), os.path.join(save_dir, "images_zca_{}.pt".format(it)))upsampled = image_saveif args.dataset != "ImageNet":upsampled = torch.repeat_interleave(upsampled, repeats=4, dim=2)upsampled = torch.repeat_interleave(upsampled, repeats=4, dim=3)grid = torchvision.utils.make_grid(upsampled, nrow=10, normalize=True, scale_each=True)wandb.log({"Reconstructed_Images": wandb.Image(torch.nan_to_num(grid.detach().cpu()))}, step=it)wandb.log({'Reconstructed_Pixels': wandb.Histogram(torch.nan_to_num(image_save.detach().cpu()))}, step=it)for clip_val in [2.5]:std = torch.std(image_save)mean = torch.mean(image_save)upsampled = torch.clip(image_save, min=mean - clip_val * std, max=mean + clip_val * std)if args.dataset != "ImageNet":upsampled = torch.repeat_interleave(upsampled, repeats=4, dim=2)upsampled = torch.repeat_interleave(upsampled, repeats=4, dim=3)grid = torchvision.utils.make_grid(upsampled, nrow=10, normalize=True, scale_each=True)wandb.log({"Clipped_Reconstructed_Images/std_{}".format(clip_val): wandb.Image(torch.nan_to_num(grid.detach().cpu()))}, step=it)# 記錄當前合成學習率到 W&Bwandb.log({"Synthetic_LR": syn_lr.detach().cpu()}, step=it)# --- 學生模型初始化與專家軌跡抽樣 ---# 隨機初始化學生網絡并轉換為 ReparamModule 以支持扁平化權重student_net = get_network(args.model, channel, num_classes, im_size, dist=False).to(args.device)  # get a random modelstudent_net = ReparamModule(student_net)if args.distributed:student_net = torch.nn.DataParallel(student_net)student_net.train()# 計算網絡參數總數,用于后續損失歸一化num_params = sum([np.prod(p.size()) for p in (student_net.parameters())])# 從 buffer 中輪詢或隨機獲取一條專家軌跡if args.load_all:expert_trajectory = buffer[np.random.randint(0, len(buffer))]else:expert_trajectory = buffer[expert_idx]expert_idx += 1if expert_idx == len(buffer):expert_idx = 0file_idx += 1# 如果切換到下一個 buffer 文件,則重新加載并打亂if file_idx == len(expert_files):file_idx = 0random.shuffle(expert_files)print("loading file {}".format(expert_files[file_idx]))if args.max_files != 1:del bufferbuffer = torch.load(expert_files[file_idx])if args.max_experts is not None:buffer = buffer[:args.max_experts]random.shuffle(buffer)# 從專家軌跡中隨機選擇起始epoch和目標epoch參數start_epoch = np.random.randint(0, args.max_start_epoch)starting_params = expert_trajectory[start_epoch]target_params = expert_trajectory[start_epoch+args.expert_epochs]# 將參數列表展平成單個向量target_params = torch.cat([p.data.to(args.device).reshape(-1) for p in target_params], 0)student_params = [torch.cat([p.data.to(args.device).reshape(-1) for p in starting_params], 0).requires_grad_(True)]starting_params = torch.cat([p.data.to(args.device).reshape(-1) for p in starting_params], 0)syn_images = image_syn # 合成圖像集合y_hat = label_syn.to(args.device)# 準備列表保存中間參數損失與距離param_loss_list = []param_dist_list = []indices_chunks = [] # 用于分批操作的索引緩存# --- 合成數據多步梯度更新模擬 ---for step in range(args.syn_steps):# 如果當前無可用indices_chunks,則重新打亂并拆分if not indices_chunks:indices = torch.randperm(len(syn_images))indices_chunks = list(torch.split(indices, args.batch_syn))these_indices = indices_chunks.pop()x = syn_images[these_indices]   # 取當前批次的合成圖像this_y = y_hat[these_indices]   # 對應標簽# texture 模式下,進行隨機平移并裁剪模擬紋理拼接if args.texture:x = torch.cat([torch.stack([torch.roll(im, (torch.randint(im_size[0]*args.canvas_size, (1,)), torch.randint(im_size[1]*args.canvas_size, (1,))), (1,2))[:,:im_size[0],:im_size[1]] for im in x]) for _ in range(args.canvas_samples)])this_y = torch.cat([this_y for _ in range(args.canvas_samples)])# 可微增強替代普通數據增強if args.dsa and (not args.no_aug):x = DiffAugment(x, args.dsa_strategy, param=args.dsa_param)if args.distributed:forward_params = student_params[-1].unsqueeze(0).expand(torch.cuda.device_count(), -1)else:forward_params = student_params[-1]# 前向計算 logitsx = student_net(x, flat_param=forward_params)ce_loss = criterion(x, this_y)# 計算損失對扁平化參數的梯度(保留圖以繼續反向到合成圖像)grad = torch.autograd.grad(ce_loss, student_params[-1], create_graph=True)[0]# 更新學生參數向下一個步長student_params.append(student_params[-1] - syn_lr * grad)# --- 計算參數匹配損失 ---param_loss = torch.tensor(0.0).to(args.device)param_dist = torch.tensor(0.0).to(args.device)param_loss += torch.nn.functional.mse_loss(student_params[-1], target_params, reduction="sum")param_dist += torch.nn.functional.mse_loss(starting_params, target_params, reduction="sum")param_loss_list.append(param_loss)param_dist_list.append(param_dist)# 歸一化:先按參數總數,再除以起點-目標距離param_loss /= num_paramsparam_dist /= num_paramsparam_loss /= param_distgrand_loss = param_loss# --- 更新合成圖像與合成學習率 ---optimizer_img.zero_grad()optimizer_lr.zero_grad()grand_loss.backward()optimizer_img.step()optimizer_lr.step()# 記錄損失與起始 epochwandb.log({"Grand_Loss": grand_loss.detach().cpu(),"Start_Epoch": start_epoch})# 清理中間梯度緩存,避免顯存泄漏for _ in student_params:del _# 每 10 次迭代打印一次損失信息if it%10 == 0:print('%s iter = %04d, loss = %.4f' % (get_time(), it, grand_loss.item()))wandb.finish()

算法邏輯總結

  1. 準備”專家示范“
    • 先用真實大數據集訓練一個(或多組)模型,把模型再每個訓練輪/每步的所有參數都記下來,這條參數隨實踐變化的記錄叫做”專家軌跡“。
  2. 初始化”學生“
    • 選軌跡上某個時間點,把學生網絡的參數初始化為老師當時的狀態。這樣學生和老師從同一個起點出發。
  3. 學生用合成數據學N步
    • 用我們的小合成數據集讓學生網絡做N步梯度下降(就是跑N個小批次的訓練)。
    • 記錄學生跑完這N步后得到的新參數。
  4. 對齊”未來“
    • 看老師在真實訓練中,從同一個起點走M步后參數是怎么樣,把學生此刻的參數和老師未來第M步的參數做對比。
    • 差距越小,說明學生越像老師;差距越大,說明合成數據還不夠好。
  5. 更新合成數據
    • 把這個”未來對齊“誤差當作損失,反向傳播回去,去調整我們的小合成圖像(和一個”學生學習率“參數)。
    • 目的就是讓下一輪學生訓練時候,能更快更準確地朝著老師的軌跡走。
  6. 重復很多輪
    • 每輪都重新從專家軌跡選一個起點,反復做上面四步,讓小合成數據不斷進化、越來越”聰明“。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91955.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91955.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91955.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STM32標準庫的工程創建

一.所需文件說明 1.啟動文件startup_xxxx.s 作用&#xff1a;初始化堆棧指針、復位向量、中斷向量表&#xff0c;執行 SystemInit() 后跳轉到 main()。 位置&#xff1a;Libraries/CMSIS/Device/ST/STM32Fxx/Source/Templates/arm/ 文件名&#xff1a; startup_stm32f10x_l…

k8s ceph sc 設置文件系統格式化參數

前言 默認的 sc 文件系統 inode 太少,對于小文件場景,往往會出現容量沒滿,inode 已經用盡的情況,本文說明如何設置 inode。 說明 本文使用的是 rook-ceph 部署的 ceph 作為存儲后端。 xfs 文件系統 sc 創建帶格式化參數的 xfs 文件系統的 sc allowVolumeExpansion: t…

關于Npm和Nvm的用法

npm是個什么東西 npm是什么 node package managernodejs包管理工具處理復雜的包的管理的問題那么使用npm以后就不需要從前端引入相應的代碼和文件等。 npm相關的命令 查看版本npm -v 更新npm install npm5.4.0 更新到最新版本npm install npmlatest 初始化項目 npm ini…

MyBatis高效查詢:簡化JDBC開發實戰

Mybatis MyBatis 是一款優秀持久層(DAO)框架&#xff0c;用于簡化 JDBC 開發 &#xff0c;原是 Apache 開源項目 iBatis&#xff0c;經歷遷移改名&#xff0c;2010 年從 Apache 遷到 Google Code 并改名&#xff0c;2013 年 11 月遷至 GitHub&#xff0c;官網為 https://mybati…

系統信息及進程管理命令

系統信息及進程管理 一、系統信息查看 常用命令&#xff1a;uname、hostnam、hostnamectl、uptime、df、du、free、lscpu 1、uname (1)、命令簡介 uname 是一個在 Unix 和類 Unix 系統&#xff08;如 Linux、macOS&#xff09;中常用的命令行工具&#xff0c;用于顯示系統信息。…

【Z字形變換】

代碼思路分析&#xff1a;Z 字形變換 1. 邊界情況處理 if (r 1 || r > n) return s;r 1&#xff1a;只有一行&#xff0c;直接返回原字符串&#xff08;無需變換&#xff09;。r > n&#xff1a;行數大于等于字符串長度&#xff0c;每行只有一個字符&#xff0c;直接返…

VBA中類的解讀及應用第二十五講:把源數據賦給類利用類完成查找

《VBA中類的解讀及應用》教程【10165646】是我推出的第五套教程&#xff0c;目前已經是第一版修訂了。這套教程定位于最高級&#xff0c;是學完初級&#xff0c;中級后的教程。類&#xff0c;是非常抽象的&#xff0c;更具研究的價值。隨著我們學習、應用VBA的深入&#xff0c;…

Vue3核心語法進階(Hook)

Vue3 自定義 Hook&#xff1a;讓你的代碼像樂高一樣“可復用”&#xff01;大家好&#xff0c;我是你們的前端小伙伴&#xff01;上一篇我們聊了 Vue3 的生命周期&#xff0c;今天咱們繼續深入 Vue3 的核心利器——自定義 Hook&#xff08;Custom Hook&#xff09;。如果你已經…

工控領域協議之Modbus

Modbus 是一種通信協議&#xff0c;用于工業自動化領域中的設備之間的通信。它是一種串行通信協議&#xff0c;廣泛應用于連接不同設備、傳感器和執行器的工業控制系統。 Modbus 在工業控制系統、自動化設備、能源管理系統等領域得到廣泛應用。 Modbus 協議的基本特點&#xff…

大件垃圾識別 mAP↑28%:陌訊多模態融合算法實戰解析

一、行業痛點&#xff1a;大件垃圾識別的現實困境在城市環衛智能化轉型過程中&#xff0c;大件垃圾&#xff08;如廢舊家具、電器等&#xff09;的自動化識別與分揀成為關鍵環節。據住建部《城市環境衛生發展報告》顯示&#xff0c;傳統人工分揀模式下大件垃圾識別準確率不足 6…

vk框架或者普通函數封裝的一些函數可以拿取使用【會持續更新】

1.身份證校驗【通用】/*** function isIDCard* description 判斷是否為有效的身份證號碼。* param {string} idCard - 待驗證的身份證號碼。* returns {boolean} 返回驗證結果。*/ pubFun.isIDCard function (idCard) {// 身份證號碼為15位或者18位&#xff0c;15位時全為數字…

如何給Word和WPS文檔添加密碼或取消密碼

要保護Word和WPS文檔&#xff0c;可以為它們加密&#xff0c;加密有兩類&#xff1a;打開密碼和修改密碼。密碼設置有兩個入口&#xff0c;一個是在另存為&#xff0c;一個是在文件菜單。Word和WPS文字的路徑略有不同&#xff0c;微軟Office和WPS的其他套件也是如此操作。一、W…

uni-app項目gitignore文件示例

uni-app 忽略以下文件和目錄 DS_Store 忽略 UniApp 編譯生成的小程序相關目錄 unpackage/ uni_modules/ 忽略編輯器自動生成的文件 idea/ vscode/ 忽略日志文件 logs/ 忽略臨時文件 temp/ 忽略構建工具自動生成的文件 build/ 忽略 npm 安裝的包文件 package-lock.json yarn.loc…

LeetCode 135:分糖果

LeetCode 135&#xff1a;分糖果問題本質與核心挑戰 給定孩子的評分數組&#xff0c;需滿足 “每個孩子至少1顆糖果&#xff0c;相鄰評分高的孩子糖果更多”&#xff0c;求最少糖果總數。核心挑戰&#xff1a; 相鄰約束是雙向的&#xff08;左→右和右→左都需滿足&#xff09;…

【QT】安裝與配置

個人主頁&#xff1a;Guiat 歸屬專欄&#xff1a;QT 文章目錄1. QT簡介與準備工作1.1 什么是QT1.2 QT的版本選擇1.3 系統要求檢查2. QT安裝方式詳解2.1 官方在線安裝器2.2 離線安裝包2.3 包管理器安裝3. Windows平臺安裝配置3.1 Windows安裝步驟3.2 環境變量配置3.3 Visual Stu…

Java從入門到精通 - 算法、正則、異常

算法、正則、異常 此筆記參考黑馬教程&#xff0c;僅學習使用&#xff0c;如有侵權&#xff0c;聯系必刪 文章目錄算法、正則、異常1. 常見算法1.1 簡單認識算法1.1.1 什么是算法&#xff1f;1.1.2 為什么要學習算法&#xff1f;1.2 排序算法1.2.1 冒泡排序1.2.1.1 實現冒泡排…

題單【排序】

P1271 【深基9.例1】選舉學生會 P1271 【深基9.例1】選舉學生會 - 洛谷 【方法一】快速排序 使用sort()&#xff0c;注意數組的范圍&#xff01;&#xff01;&#xff01; #include<bits/stdc.h> using namespace std;int a[2000000],n,m;int main() {cin>>n>&g…

【機器學習】(算法優化二)提升算法之:AdaBoost與隨機梯度

文章目錄一、 AdaBoost&#xff1a;自適應提升算法1、AdaBoost數學原理詳解1.1、 目標函數1.2、 樣本權重更新的邏輯1.3、 模型權重計算的含義1.4、 AdaBoost的核心思想2、為什么AdaBoost如此有效&#xff1f;二、 隨機梯度提升算法&#xff1a;梯度優化下更精細的優化1、隨機梯…

力扣 hot100 Day65

75. 顏色分類 給定一個包含紅色、白色和藍色、共 n 個元素的數組 nums &#xff0c;原地 對它們進行排序&#xff0c;使得相同顏色的元素相鄰&#xff0c;并按照紅色、白色、藍色順序排列。 我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。 必須在不使用庫內置的 sort 函…

12.Linux 磁盤管理

Linux : 磁盤管理 一、磁盤設備命名規則磁盤類型設備命名模式示例特點SATA/SCSI/SAS/dev/sdXsda&#xff08;第一塊硬盤&#xff09; sda1&#xff08;第一塊硬盤第一分區&#xff09;機械硬盤/通用接口NVMe/dev/nvmeXnYpZnvme0n1&#xff08;第一通道第一塊盤&#xff09; …